Compare commits
54 Commits
4ac34b8583
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| eb8af006b0 | |||
| 4af56d9bce | |||
| 998bc6f1fa | |||
| 753fff5f59 | |||
| 02bc4de6d5 | |||
| 5349c60c39 | |||
| 25a6832351 | |||
| 28fc8456e0 | |||
| 6b6d5f1f6d | |||
| f3371c33b0 | |||
| 441a2122bc | |||
| 502127283b | |||
| 0fb9be931f | |||
| 1d46c4f3bd | |||
| dbef9c558d | |||
| 64586f4a86 | |||
| ab20e98663 | |||
| ae6e72e0d9 | |||
| bd5683d498 | |||
| 11eec8f222 | |||
| 2c1673d2dd | |||
| e58b7d36fb | |||
| 0d14e10de5 | |||
| a39cd45bf1 | |||
| ab858aacb8 | |||
| 0647eceab7 | |||
| a903343385 | |||
| 17341f923d | |||
| fcd2718794 | |||
| c9d16959d0 | |||
| ce662609f3 | |||
| 583d901162 | |||
| 61d35374e0 | |||
| 194c8187f9 | |||
| 490d5c923b | |||
| 0e49f35d3b | |||
| b9cee1bc70 | |||
| 3390d01ef6 | |||
| 561028ff04 | |||
| 671583ebbe | |||
| e941502615 | |||
| 8bab2da2ed | |||
| 5ef278ce70 | |||
| 14103175a9 | |||
| 10a3e2fedd | |||
| 25a36d5064 | |||
| 8706b2c7fb | |||
| d493ebf4f0 | |||
| 3e795998d1 | |||
| c694781f38 | |||
| 1a2298963d | |||
| 4c1ed1cf9b | |||
| f80d0a656e | |||
| 4429cd92c1 |
+71
-44
@@ -8,73 +8,100 @@ Checks:
|
|||||||
- -bugprone-integer-division
|
- -bugprone-integer-division
|
||||||
- -bugprone-easily-swappable-parameters
|
- -bugprone-easily-swappable-parameters
|
||||||
- -bugprone-narrowing-conversions
|
- -bugprone-narrowing-conversions
|
||||||
- -modernize-avoid-c-arrays,-warnings-as-errors
|
- -modernize-avoid-c-arrays
|
||||||
|
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
# Solo incluir archivos de tu código fuente (external tiene su propio .clang-tidy)
|
# Headers nostres (excloem source/external/ que conté dependències de tercers no editables)
|
||||||
# Excluye los headers SPIR-V generados en rendering/sdl3gpu/
|
HeaderFilterRegex: 'source/(core|game|utils)/'
|
||||||
HeaderFilterRegex: 'source/(?!external/|rendering/sdl3gpu/.*_spv\.h).*'
|
|
||||||
FormatStyle: file
|
FormatStyle: file
|
||||||
|
|
||||||
CheckOptions:
|
CheckOptions:
|
||||||
# bugprone-empty-catch: aceptar catches vacíos marcados con @INTENTIONAL en un comentario
|
# bugprone-empty-catch: aceptar catches vacíos marcados con @INTENTIONAL en un comentario
|
||||||
- { key: bugprone-empty-catch.IgnoreCatchWithKeywords, value: '@INTENTIONAL' }
|
- { key: bugprone-empty-catch.IgnoreCatchWithKeywords, value: '@INTENTIONAL' }
|
||||||
|
|
||||||
# Variables locales en snake_case
|
# =====================================================================
|
||||||
|
# CONSTANTES → UPPER_CASE (compile-time y runtime, en cualquier scope)
|
||||||
|
# =====================================================================
|
||||||
|
# Todo lo que sea const o constexpr se identifica visualmente en UPPER_CASE,
|
||||||
|
# sin importar si es global, local, miembro o static.
|
||||||
|
|
||||||
|
# constexpr en cualquier scope (globales y locales)
|
||||||
|
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constantes globales (const no-constexpr)
|
||||||
|
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constantes locales (const en función)
|
||||||
|
- { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Static const a nivel de archivo/namespace
|
||||||
|
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Miembros static const/constexpr de clase (p.ej. static constexpr int MAX = 100;)
|
||||||
|
- { key: readability-identifier-naming.ClassConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Miembros const no-static de clase (p.ej. const int limit;)
|
||||||
|
- { key: readability-identifier-naming.ConstantMemberCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Valores de enums
|
||||||
|
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# NOTA: Los parámetros const NO se tratan como constantes aquí.
|
||||||
|
# Un parámetro sigue siendo un parámetro aunque sea const → hereda ParameterCase.
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# VARIABLES NO-CONST
|
||||||
|
# =====================================================================
|
||||||
|
|
||||||
|
# Variables locales
|
||||||
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.LocalVariableCase, value: lower_case }
|
||||||
|
|
||||||
# Miembros privados en snake_case con sufijo _
|
# Parámetros de función
|
||||||
- { key: readability-identifier-naming.PrivateMemberCase, value: lower_case }
|
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
|
||||||
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
|
|
||||||
|
|
||||||
# Miembros protegidos en snake_case con sufijo _
|
# Variables estáticas no-const (static locales, static file-scope,
|
||||||
- { key: readability-identifier-naming.ProtectedMemberCase, value: lower_case }
|
# y static members no-const de clase como el instance_ de un Singleton).
|
||||||
- { key: readability-identifier-naming.ProtectedMemberSuffix, value: _ }
|
# Sufijo _ para marcar que tienen storage estático.
|
||||||
|
|
||||||
# Miembros públicos en snake_case (sin sufijo)
|
|
||||||
- { key: readability-identifier-naming.PublicMemberCase, value: lower_case }
|
|
||||||
|
|
||||||
# Namespaces en CamelCase
|
|
||||||
- { key: readability-identifier-naming.NamespaceCase, value: CamelCase }
|
|
||||||
|
|
||||||
# Variables estáticas privadas como miembros privados
|
|
||||||
- { key: readability-identifier-naming.StaticVariableCase, value: lower_case }
|
- { key: readability-identifier-naming.StaticVariableCase, value: lower_case }
|
||||||
- { key: readability-identifier-naming.StaticVariableSuffix, value: _ }
|
- { key: readability-identifier-naming.StaticVariableSuffix, value: _ }
|
||||||
|
|
||||||
# Constantes estáticas sin sufijo
|
# =====================================================================
|
||||||
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
# MIEMBROS DE CLASE NO-CONST
|
||||||
|
# =====================================================================
|
||||||
|
# Privados: snake_case con sufijo _
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
|
||||||
|
|
||||||
# Constantes globales en UPPER_CASE
|
# Protegidos: snake_case con sufijo _
|
||||||
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
- { key: readability-identifier-naming.ProtectedMemberCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.ProtectedMemberSuffix, value: _ }
|
||||||
|
|
||||||
# Variables constexpr globales en UPPER_CASE
|
# Públicos: snake_case sin sufijo
|
||||||
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE }
|
- { key: readability-identifier-naming.PublicMemberCase, value: lower_case }
|
||||||
|
|
||||||
# Constantes locales en UPPER_CASE
|
# =====================================================================
|
||||||
- { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE }
|
# TIPOS
|
||||||
|
# =====================================================================
|
||||||
# Constexpr miembros en UPPER_CASE (sin sufijo)
|
|
||||||
- { key: readability-identifier-naming.ConstexprMemberCase, value: UPPER_CASE }
|
|
||||||
|
|
||||||
# Constexpr miembros privados/protegidos con sufijo _
|
|
||||||
- { key: readability-identifier-naming.ConstexprMethodCase, value: UPPER_CASE }
|
|
||||||
|
|
||||||
# Clases, structs y enums en CamelCase
|
|
||||||
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
||||||
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||||
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
|
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
|
||||||
|
- { key: readability-identifier-naming.UnionCase, value: CamelCase }
|
||||||
|
- { key: readability-identifier-naming.TypeAliasCase, value: CamelCase }
|
||||||
|
- { key: readability-identifier-naming.TypedefCase, value: CamelCase }
|
||||||
|
- { key: readability-identifier-naming.TemplateParameterCase, value: CamelCase }
|
||||||
|
|
||||||
# Valores de enums en UPPER_CASE
|
# Namespaces
|
||||||
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
- { key: readability-identifier-naming.NamespaceCase, value: CamelCase }
|
||||||
|
|
||||||
# Métodos en camelBack (sin sufijos)
|
# =====================================================================
|
||||||
|
# FUNCIONES Y MÉTODOS (incluyendo constexpr)
|
||||||
|
# =====================================================================
|
||||||
|
# Un método/función constexpr es un invocable, no una constante → camelBack.
|
||||||
|
- { key: readability-identifier-naming.FunctionCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.ConstexprFunctionCase, value: camelBack }
|
||||||
- { key: readability-identifier-naming.MethodCase, value: camelBack }
|
- { key: readability-identifier-naming.MethodCase, value: camelBack }
|
||||||
- { key: readability-identifier-naming.PrivateMethodCase, value: camelBack }
|
- { key: readability-identifier-naming.PrivateMethodCase, value: camelBack }
|
||||||
- { key: readability-identifier-naming.ProtectedMethodCase, value: camelBack }
|
- { key: readability-identifier-naming.ProtectedMethodCase, value: camelBack }
|
||||||
- { key: readability-identifier-naming.PublicMethodCase, value: camelBack }
|
- { key: readability-identifier-naming.PublicMethodCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.ConstexprMethodCase, value: camelBack }
|
||||||
# Funciones en camelBack
|
|
||||||
- { key: readability-identifier-naming.FunctionCase, value: camelBack }
|
|
||||||
|
|
||||||
# Parámetros en lower_case
|
|
||||||
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
|
|
||||||
|
|||||||
Executable
+92
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pre-commit hook: aplica clang-format als fitxers C++ staged abans del commit.
|
||||||
|
# - Només toca fitxers staged dins source/ (exclou source/external/).
|
||||||
|
# - Avorta el commit si hi ha canvis NO staged en aquests fitxers (per no incloure'ls sense voler).
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if ! command -v clang-format >/dev/null 2>&1; then
|
||||||
|
echo "pre-commit: clang-format no trobat — saltant format check" >&2
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mapfile -t STAGED < <(git diff --cached --name-only --diff-filter=ACMR \
|
||||||
|
| grep -E '^source/.*\.(cpp|hpp|h)$' \
|
||||||
|
| grep -vE '^source/external/' || true)
|
||||||
|
|
||||||
|
if [ ${#STAGED[@]} -eq 0 ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
UNSTAGED_DIRTY=()
|
||||||
|
for f in "${STAGED[@]}"; do
|
||||||
|
if ! git diff --quiet -- "$f"; then
|
||||||
|
UNSTAGED_DIRTY+=("$f")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#UNSTAGED_DIRTY[@]} -gt 0 ]; then
|
||||||
|
echo "pre-commit: aquests fitxers tenen canvis NO staged i estan al commit." >&2
|
||||||
|
echo " Fes 'git add' o 'git stash' abans de continuar:" >&2
|
||||||
|
printf ' %s\n' "${UNSTAGED_DIRTY[@]}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
clang-format -i "${STAGED[@]}"
|
||||||
|
git add -- "${STAGED[@]}"
|
||||||
|
|
||||||
|
# --- clang-tidy només sobre els fitxers staged ---
|
||||||
|
if ! command -v clang-tidy >/dev/null 2>&1; then
|
||||||
|
echo "pre-commit: clang-tidy no trobat — saltant tidy" >&2
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||||
|
BUILD_DIR="$REPO_ROOT/build"
|
||||||
|
|
||||||
|
if [ ! -f "$BUILD_DIR/compile_commands.json" ]; then
|
||||||
|
echo "pre-commit: generant compile_commands.json (build dir buit)..." >&2
|
||||||
|
cmake -S "$REPO_ROOT" -B "$BUILD_DIR" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "pre-commit: clang-tidy sobre ${#STAGED[@]} fitxer(s)..." >&2
|
||||||
|
if ! clang-tidy -p "$BUILD_DIR" --quiet "${STAGED[@]}"; then
|
||||||
|
echo "pre-commit: clang-tidy ha trobat errors — commit avortat" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- cppcheck només sobre els .cpp staged ---
|
||||||
|
if ! command -v cppcheck >/dev/null 2>&1; then
|
||||||
|
echo "pre-commit: cppcheck no trobat — saltant cppcheck" >&2
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
CPP_STAGED=()
|
||||||
|
for f in "${STAGED[@]}"; do
|
||||||
|
[[ "$f" == *.cpp ]] && CPP_STAGED+=("$f")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#CPP_STAGED[@]} -eq 0 ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "pre-commit: cppcheck sobre ${#CPP_STAGED[@]} fitxer(s)..." >&2
|
||||||
|
if ! cppcheck \
|
||||||
|
--enable=warning,style,performance,portability \
|
||||||
|
--std=c++20 \
|
||||||
|
--language=c++ \
|
||||||
|
--inline-suppr \
|
||||||
|
--suppress=missingIncludeSystem \
|
||||||
|
--suppress=toomanyconfigs \
|
||||||
|
--suppress='*:*source/external/*' \
|
||||||
|
--suppress='*:*source/core/rendering/sdl3gpu/spv/*' \
|
||||||
|
--suppress=normalCheckLevelMaxBranches \
|
||||||
|
-D_DEBUG \
|
||||||
|
-DLINUX_BUILD \
|
||||||
|
--quiet \
|
||||||
|
--error-exitcode=1 \
|
||||||
|
-I "$REPO_ROOT/source" \
|
||||||
|
"${CPP_STAGED[@]}"; then
|
||||||
|
echo "pre-commit: cppcheck ha trobat errors — commit avortat" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Vendored
+51
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Mac",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/source/**",
|
||||||
|
"${workspaceFolder}/build"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"_DEBUG",
|
||||||
|
"_NO_AUDIO",
|
||||||
|
"MACOS_BUILD"
|
||||||
|
],
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++20",
|
||||||
|
"intelliSenseMode": "macos-clang-arm64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/source/**",
|
||||||
|
"${workspaceFolder}/build"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"_DEBUG",
|
||||||
|
"_NO_AUDIO",
|
||||||
|
"LINUX_BUILD"
|
||||||
|
],
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++20",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Win32",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/source/**",
|
||||||
|
"${workspaceFolder}/build"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"_DEBUG",
|
||||||
|
"_NO_AUDIO",
|
||||||
|
"WINDOWS_BUILD",
|
||||||
|
"_WIN32"
|
||||||
|
],
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++20",
|
||||||
|
"intelliSenseMode": "windows-msvc-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
@@ -4,6 +4,22 @@ Historial de canvis i novetats de Coffee Crisis Arcade Edition.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-05-17
|
||||||
|
|
||||||
|
- **Migració del shader PostFX a la versió d'aee_arcade**: filtratge analític de scanlines amb `smoothstep` (paràmetres `scan_dark_ratio`, `scan_dark_floor`, `scan_edge_soft` exposats per preset). Eliminat tot el pipeline de supersampling 3× + Lanczos downscale (shaders, render targets, opcions de menu, claus de YAML, keybinding F0, llengües). 1 sol render pass vs 3 anteriors.
|
||||||
|
- **Chroma `min`/`max` amb mostreig bilinear subpíxel**: substitueix l'antic `chroma_strength`. Amb min==max queda estàtic; amb min!=max pulsa sinusoidalment entre els dos valors. Adéu al *tic-tac* del NEAREST amb offsets fraccionals.
|
||||||
|
- **MSL extret a headers separats** sota `source/core/rendering/sdl3gpu/msl/` (postfx_vert, postfx_frag, crtpi_frag).
|
||||||
|
- **Service Menu: VSync ara funciona de veritat**. `Screen::applySettings()` propaga al backend GPU (abans només tocava `SDL_SetRenderVSync` i amb backend GPU el present real el fa el swapchain — el canvi era invisible). Separat el setter aplicat al hardware del setter de preferència persistent: `Resource::beginLoad` ja no clobera `Options::video.vsync` durant el preload, així la preferència de l'usuari es preserva entre llançaments.
|
||||||
|
- **Demo player anti-crash**: guarda amb modul al lector (`demo_.data.at(index).at(demo_.index % size)`) i trigger del fade `>=` (era `==`, fragil a frame skips per canvis de preset des del service menu) — evita `vector::_M_range_check` quan el frame de trigger 1800 saltava i `demo_.index` arribava a 2000.
|
||||||
|
- **Reinici real des del service menu** via `execv`.
|
||||||
|
- **Opció de preset de paràmetres al service menu** (`params_file` → `params_preset`: classic / arcade / red). Presets `red` i `classic` arreglats.
|
||||||
|
- **Pack inclou ara la carpeta `config/`** (assets, params, stages, pools, formations).
|
||||||
|
- **Bullet "fire up" reposicionada** (-1 px x, -2 px y) i pintada sobre el jugador en lloc de sota.
|
||||||
|
- **Defaults**: zoom de finestra a 3 (era 2).
|
||||||
|
- Neteja de codi: passades exhaustives de clang-tidy i cppcheck (de 105 warnings a 0).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2026-04-03
|
## 2026-04-03
|
||||||
|
|
||||||
- **Nova intro cinematogràfica**: les tarjetes s'llancen des dels costats de la pantalla amb zoom, rotació i rebot, simulant tirar cartes sobre una mesa. Les anteriors ixen despedides girant quan arriba la següent. Sombra amb efecte de perspectiva 2D→3D.
|
- **Nova intro cinematogràfica**: les tarjetes s'llancen des dels costats de la pantalla amb zoom, rotació i rebot, simulant tirar cartes sobre una mesa. Les anteriors ixen despedides girant quan arriba la següent. Sombra amb efecte de perspectiva 2D→3D.
|
||||||
|
|||||||
@@ -44,24 +44,38 @@ make tidy-fix # run clang-tidy with auto-fix
|
|||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Singletons (core systems)
|
### Source layout
|
||||||
- **Director** (`source/director.hpp`) — Application state machine, orchestrates scene transitions (Logo → Intro → Title → Game → Credits/HiScore → Title)
|
The `source/` tree is organised in the same style as the sibling projects `projecte_2026` and `jaildoctors_dilemma`:
|
||||||
- **Screen** (`source/screen.hpp`) — Window management, SDL3 GPU rendering pipeline, post-processing effects
|
|
||||||
- **Resource** (`source/resource.hpp`) — Asset loading/caching with PRELOAD and LAZY_LOAD modes, reads from `resources.pack`
|
|
||||||
- **Audio** (`source/audio.hpp`) — Music and SFX management
|
|
||||||
- **Input** (`source/input.hpp`) — Keyboard and gamepad input handling
|
|
||||||
|
|
||||||
### Scenes (source/sections/)
|
```
|
||||||
|
source/
|
||||||
|
├── core/ # engine: audio, input, locale, rendering (+ sdl3gpu, sprite), resources, system
|
||||||
|
├── game/ # gameplay: entities, gameplay, scenes, ui, options
|
||||||
|
├── utils/ # color, param, utils
|
||||||
|
├── external/ # vendored third-party headers (json, fkyaml, stb_*)
|
||||||
|
└── main.cpp
|
||||||
|
```
|
||||||
|
|
||||||
|
`#include` paths are absolute relative to `source/` (e.g. `#include "core/audio/audio.hpp"`, `#include "game/scenes/logo.hpp"`). The CMake build adds a single `-I${CMAKE_SOURCE_DIR}/source`.
|
||||||
|
|
||||||
|
### Singletons (core systems)
|
||||||
|
- **Director** (`source/core/system/director.hpp`) — Application state machine, orchestrates scene transitions (Logo → Intro → Title → Game → Credits/HiScore → Title)
|
||||||
|
- **Screen** (`source/core/rendering/screen.hpp`) — Window management, SDL3 GPU rendering pipeline, post-processing effects
|
||||||
|
- **Resource** (`source/core/resources/resource.hpp`) — Asset loading/caching with PRELOAD and LAZY_LOAD modes, reads from `resources.pack`
|
||||||
|
- **Audio** (`source/core/audio/audio.hpp`) — Music and SFX management
|
||||||
|
- **Input** (`source/core/input/input.hpp`) — Keyboard and gamepad input handling
|
||||||
|
|
||||||
|
### Scenes (source/game/scenes/)
|
||||||
Each scene is a self-contained class with update/render lifecycle. Scene flow is managed by Director.
|
Each scene is a self-contained class with update/render lifecycle. Scene flow is managed by Director.
|
||||||
|
|
||||||
### Entity Managers
|
### Entity Managers
|
||||||
- `BalloonManager` / `BulletManager` — Object pool-based entity management
|
- `BalloonManager` / `BulletManager` — Object pool-based entity management (`source/game/gameplay/`)
|
||||||
- `Player` — Two-player support (player 1: keyboard, player 2: gamepad)
|
- `Player` — Two-player support (player 1: keyboard, player 2: gamepad) (`source/game/entities/`)
|
||||||
|
|
||||||
### Rendering Pipeline
|
### Rendering Pipeline
|
||||||
- SDL3 GPU API (Vulkan/Metal/D3D12 backends)
|
- SDL3 GPU API (Vulkan/Metal/D3D12 backends)
|
||||||
- SPIR-V shaders compiled offline from GLSL (`data/shaders/`) via `glslc`
|
- SPIR-V shaders compiled offline from GLSL (`data/shaders/`) via `glslc`
|
||||||
- Compiled shader headers embedded in `source/rendering/sdl3gpu/postfx_*_spv.h`
|
- Compiled shader headers embedded in `source/core/rendering/sdl3gpu/postfx_*_spv.h`
|
||||||
- macOS uses Metal (no SPIR-V compilation needed)
|
- macOS uses Metal (no SPIR-V compilation needed)
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
@@ -72,7 +86,9 @@ Each scene is a self-contained class with update/render lifecycle. Scene flow is
|
|||||||
- Gamepad mappings: `config/gamecontrollerdb.txt`
|
- Gamepad mappings: `config/gamecontrollerdb.txt`
|
||||||
|
|
||||||
### External Libraries (header-only/vendored in source/external/)
|
### External Libraries (header-only/vendored in source/external/)
|
||||||
- nlohmann/json, fkyaml (YAML), stb_image, stb_vorbis, jail_audio
|
- nlohmann/json, fkyaml (YAML), stb_image, stb_vorbis
|
||||||
|
|
||||||
|
`jail_audio` lives in `source/core/audio/` and `gif.{hpp,cpp}` in `source/core/rendering/` — these are first-party, not third-party.
|
||||||
|
|
||||||
## Code Style
|
## Code Style
|
||||||
|
|
||||||
|
|||||||
+245
-153
@@ -3,6 +3,11 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(coffee_crisis_arcade_edition VERSION 2.00)
|
project(coffee_crisis_arcade_edition VERSION 2.00)
|
||||||
|
|
||||||
|
# Tipus de build per defecte (Debug) si no se n'ha especificat cap
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Establecer estándar de C++
|
# Establecer estándar de C++
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
@@ -10,17 +15,24 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
|
|
||||||
# --- GENERACIÓN DE VERSIÓN AUTOMÁTICA ---
|
# --- GENERACIÓN DE VERSIÓN AUTOMÁTICA ---
|
||||||
find_package(Git QUIET)
|
# Si GIT_HASH se ha pasado desde fuera (p.ej. desde el Makefile via -DGIT_HASH=xxx),
|
||||||
if(GIT_FOUND)
|
# lo usamos tal cual. Esto evita problemas con Docker/emscripten, donde git aborta por
|
||||||
execute_process(
|
# "dubious ownership" en el volumen montado. En builds locales sin -DGIT_HASH, se
|
||||||
COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD
|
# resuelve aquí ejecutando git directamente.
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
if(NOT DEFINED GIT_HASH OR GIT_HASH STREQUAL "")
|
||||||
OUTPUT_VARIABLE GIT_HASH
|
find_package(Git QUIET)
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
if(GIT_FOUND)
|
||||||
ERROR_QUIET
|
execute_process(
|
||||||
)
|
COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD
|
||||||
else()
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
set(GIT_HASH "unknown")
|
OUTPUT_VARIABLE GIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED GIT_HASH OR GIT_HASH STREQUAL "")
|
||||||
|
set(GIT_HASH "unknown")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Configurar archivo de versión
|
# Configurar archivo de versión
|
||||||
@@ -28,173 +40,189 @@ configure_file(${CMAKE_SOURCE_DIR}/source/version.h.in ${CMAKE_BINARY_DIR}/versi
|
|||||||
|
|
||||||
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
||||||
set(APP_SOURCES
|
set(APP_SOURCES
|
||||||
# --- Archivos Principales del Sistema ---
|
|
||||||
source/asset.cpp
|
|
||||||
source/audio.cpp
|
|
||||||
source/director.cpp
|
|
||||||
source/global_events.cpp
|
|
||||||
source/global_inputs.cpp
|
|
||||||
source/input.cpp
|
|
||||||
source/lang.cpp
|
|
||||||
source/main.cpp
|
source/main.cpp
|
||||||
source/param.cpp
|
|
||||||
source/resource.cpp
|
|
||||||
source/resource_helper.cpp
|
|
||||||
source/resource_loader.cpp
|
|
||||||
source/resource_pack.cpp
|
|
||||||
source/screen.cpp
|
|
||||||
source/text.cpp
|
|
||||||
source/writer.cpp
|
|
||||||
|
|
||||||
# --- UI (User Interface) ---
|
|
||||||
source/ui/menu_option.cpp
|
|
||||||
source/ui/menu_renderer.cpp
|
|
||||||
source/ui/notifier.cpp
|
|
||||||
source/ui/service_menu.cpp
|
|
||||||
source/ui/ui_message.cpp
|
|
||||||
source/ui/window_message.cpp
|
|
||||||
|
|
||||||
# --- Lógica del Juego ---
|
|
||||||
source/balloon_formations.cpp
|
|
||||||
source/balloon_manager.cpp
|
|
||||||
source/balloon.cpp
|
|
||||||
source/bullet.cpp
|
|
||||||
source/bullet_manager.cpp
|
|
||||||
source/enter_name.cpp
|
|
||||||
source/explosions.cpp
|
|
||||||
source/game_logo.cpp
|
|
||||||
source/item.cpp
|
|
||||||
source/manage_hiscore_table.cpp
|
|
||||||
source/player.cpp
|
|
||||||
source/scoreboard.cpp
|
|
||||||
source/tabe.cpp
|
|
||||||
|
|
||||||
# --- Escenas ---
|
|
||||||
source/sections/credits.cpp
|
|
||||||
source/sections/game.cpp
|
|
||||||
source/sections/hiscore_table.cpp
|
|
||||||
source/sections/instructions.cpp
|
|
||||||
source/sections/intro.cpp
|
|
||||||
source/sections/logo.cpp
|
|
||||||
source/sections/title.cpp
|
|
||||||
|
|
||||||
# --- Sprites y Gráficos ---
|
|
||||||
source/animated_sprite.cpp
|
|
||||||
source/background.cpp
|
|
||||||
source/card_sprite.cpp
|
|
||||||
source/fade.cpp
|
|
||||||
source/moving_sprite.cpp
|
|
||||||
source/path_sprite.cpp
|
|
||||||
source/smart_sprite.cpp
|
|
||||||
source/sprite.cpp
|
|
||||||
source/texture.cpp
|
|
||||||
source/tiled_bg.cpp
|
|
||||||
|
|
||||||
# --- Otros ---
|
|
||||||
source/color.cpp
|
|
||||||
source/demo.cpp
|
|
||||||
source/define_buttons.cpp
|
|
||||||
source/difficulty.cpp
|
|
||||||
source/input_types.cpp
|
|
||||||
source/mouse.cpp
|
|
||||||
source/options.cpp
|
|
||||||
source/shutdown.cpp
|
|
||||||
source/stage.cpp
|
|
||||||
source/system_utils.cpp
|
|
||||||
source/utils.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# Fuentes de librerías de terceros
|
# --- core/audio ---
|
||||||
set(EXTERNAL_SOURCES
|
source/core/audio/audio.cpp
|
||||||
source/external/json.hpp
|
source/core/audio/audio_adapter.cpp
|
||||||
source/external/gif.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# Fuentes del sistema de renderizado
|
# --- core/input ---
|
||||||
set(RENDERING_SOURCES
|
source/core/input/define_buttons.cpp
|
||||||
source/rendering/sdl3gpu/sdl3gpu_shader.cpp
|
source/core/input/global_inputs.cpp
|
||||||
|
source/core/input/input.cpp
|
||||||
|
source/core/input/input_types.cpp
|
||||||
|
source/core/input/mouse.cpp
|
||||||
|
|
||||||
|
# --- core/locale ---
|
||||||
|
source/core/locale/lang.cpp
|
||||||
|
|
||||||
|
# --- core/rendering ---
|
||||||
|
source/core/rendering/background.cpp
|
||||||
|
source/core/rendering/fade.cpp
|
||||||
|
source/core/rendering/gif.cpp
|
||||||
|
source/core/rendering/screen.cpp
|
||||||
|
source/core/rendering/text.cpp
|
||||||
|
source/core/rendering/texture.cpp
|
||||||
|
source/core/rendering/tiled_bg.cpp
|
||||||
|
source/core/rendering/writer.cpp
|
||||||
|
source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp
|
||||||
|
source/core/rendering/sprite/animated_sprite.cpp
|
||||||
|
source/core/rendering/sprite/card_sprite.cpp
|
||||||
|
source/core/rendering/sprite/moving_sprite.cpp
|
||||||
|
source/core/rendering/sprite/path_sprite.cpp
|
||||||
|
source/core/rendering/sprite/smart_sprite.cpp
|
||||||
|
source/core/rendering/sprite/sprite.cpp
|
||||||
|
|
||||||
|
# --- core/resources ---
|
||||||
|
source/core/resources/asset.cpp
|
||||||
|
source/core/resources/asset_integrated.cpp
|
||||||
|
source/core/resources/resource.cpp
|
||||||
|
source/core/resources/resource_helper.cpp
|
||||||
|
source/core/resources/resource_loader.cpp
|
||||||
|
source/core/resources/resource_pack.cpp
|
||||||
|
|
||||||
|
# --- core/system ---
|
||||||
|
source/core/system/demo.cpp
|
||||||
|
source/core/system/director.cpp
|
||||||
|
source/core/system/global_events.cpp
|
||||||
|
source/core/system/shutdown.cpp
|
||||||
|
source/core/system/system_utils.cpp
|
||||||
|
|
||||||
|
# --- game ---
|
||||||
|
source/game/options.cpp
|
||||||
|
|
||||||
|
# --- game/entities ---
|
||||||
|
source/game/entities/balloon.cpp
|
||||||
|
source/game/entities/bullet.cpp
|
||||||
|
source/game/entities/explosions.cpp
|
||||||
|
source/game/entities/item.cpp
|
||||||
|
source/game/entities/player.cpp
|
||||||
|
source/game/entities/tabe.cpp
|
||||||
|
|
||||||
|
# --- game/gameplay ---
|
||||||
|
source/game/gameplay/balloon_formations.cpp
|
||||||
|
source/game/gameplay/balloon_manager.cpp
|
||||||
|
source/game/gameplay/bullet_manager.cpp
|
||||||
|
source/game/gameplay/difficulty.cpp
|
||||||
|
source/game/gameplay/enter_name.cpp
|
||||||
|
source/game/gameplay/game_logo.cpp
|
||||||
|
source/game/gameplay/manage_hiscore_table.cpp
|
||||||
|
source/game/gameplay/scoreboard.cpp
|
||||||
|
source/game/gameplay/stage.cpp
|
||||||
|
|
||||||
|
# --- game/scenes ---
|
||||||
|
source/game/scenes/credits.cpp
|
||||||
|
source/game/scenes/game.cpp
|
||||||
|
source/game/scenes/hiscore_table.cpp
|
||||||
|
source/game/scenes/instructions.cpp
|
||||||
|
source/game/scenes/intro.cpp
|
||||||
|
source/game/scenes/logo.cpp
|
||||||
|
source/game/scenes/preload.cpp
|
||||||
|
source/game/scenes/title.cpp
|
||||||
|
|
||||||
|
# --- game/ui ---
|
||||||
|
source/game/ui/menu_option.cpp
|
||||||
|
source/game/ui/menu_renderer.cpp
|
||||||
|
source/game/ui/notifier.cpp
|
||||||
|
source/game/ui/service_menu.cpp
|
||||||
|
source/game/ui/ui_message.cpp
|
||||||
|
source/game/ui/window_message.cpp
|
||||||
|
|
||||||
|
# --- utils ---
|
||||||
|
source/utils/color.cpp
|
||||||
|
source/utils/param.cpp
|
||||||
|
source/utils/utils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Configuración de SDL3
|
# Configuración de SDL3
|
||||||
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
|
if(EMSCRIPTEN)
|
||||||
message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}")
|
# En Emscripten, SDL3 se compila desde source con FetchContent
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
SDL3
|
||||||
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||||
|
GIT_TAG release-3.4.4
|
||||||
|
GIT_SHALLOW TRUE
|
||||||
|
)
|
||||||
|
set(SDL_SHARED OFF CACHE BOOL "" FORCE)
|
||||||
|
set(SDL_STATIC ON CACHE BOOL "" FORCE)
|
||||||
|
set(SDL_TEST_LIBRARY OFF CACHE BOOL "" FORCE)
|
||||||
|
FetchContent_MakeAvailable(SDL3)
|
||||||
|
message(STATUS "SDL3 compilado desde source para Emscripten")
|
||||||
|
else()
|
||||||
|
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
|
||||||
|
message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# --- SHADER COMPILATION (Linux/Windows only - macOS uses Metal) ---
|
# --- SHADER COMPILATION (Linux/Windows only - macOS uses Metal, Emscripten no soporta SDL3 GPU) ---
|
||||||
if(NOT APPLE)
|
if(NOT APPLE AND NOT EMSCRIPTEN)
|
||||||
find_program(GLSLC_EXE NAMES glslc)
|
find_program(GLSLC_EXE NAMES glslc)
|
||||||
|
|
||||||
set(SHADER_VERT_SRC "${CMAKE_SOURCE_DIR}/data/shaders/postfx.vert")
|
set(SHADERS_DIR "${CMAKE_SOURCE_DIR}/data/shaders")
|
||||||
set(SHADER_FRAG_SRC "${CMAKE_SOURCE_DIR}/data/shaders/postfx.frag")
|
set(HEADERS_DIR "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/spv")
|
||||||
set(SHADER_CRTPI_SRC "${CMAKE_SOURCE_DIR}/data/shaders/crtpi_frag.glsl")
|
|
||||||
set(SHADER_UPSCALE_SRC "${CMAKE_SOURCE_DIR}/data/shaders/upscale.frag")
|
|
||||||
set(SHADER_DOWNSCALE_SRC "${CMAKE_SOURCE_DIR}/data/shaders/downscale.frag")
|
|
||||||
|
|
||||||
set(SHADER_VERT_H "${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu/postfx_vert_spv.h")
|
set(ALL_SHADER_HEADERS
|
||||||
set(SHADER_FRAG_H "${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu/postfx_frag_spv.h")
|
"${HEADERS_DIR}/postfx_vert_spv.h"
|
||||||
set(SHADER_CRTPI_H "${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu/crtpi_frag_spv.h")
|
"${HEADERS_DIR}/postfx_frag_spv.h"
|
||||||
set(SHADER_UPSCALE_H "${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu/upscale_frag_spv.h")
|
"${HEADERS_DIR}/crtpi_frag_spv.h"
|
||||||
set(SHADER_DOWNSCALE_H "${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu/downscale_frag_spv.h")
|
)
|
||||||
|
set(ALL_SHADER_SOURCES
|
||||||
set(ALL_SHADER_SOURCES "${SHADER_VERT_SRC}" "${SHADER_FRAG_SRC}" "${SHADER_CRTPI_SRC}" "${SHADER_UPSCALE_SRC}" "${SHADER_DOWNSCALE_SRC}")
|
"${SHADERS_DIR}/postfx.vert"
|
||||||
set(ALL_SHADER_HEADERS "${SHADER_VERT_H}" "${SHADER_FRAG_H}" "${SHADER_CRTPI_H}" "${SHADER_UPSCALE_H}" "${SHADER_DOWNSCALE_H}")
|
"${SHADERS_DIR}/postfx.frag"
|
||||||
|
"${SHADERS_DIR}/crtpi_frag.glsl"
|
||||||
|
)
|
||||||
|
|
||||||
if(GLSLC_EXE)
|
if(GLSLC_EXE)
|
||||||
set(COMPILE_SHADER_SCRIPT "${CMAKE_SOURCE_DIR}/tools/shaders/compile_shader.cmake")
|
add_custom_command(
|
||||||
|
OUTPUT ${ALL_SHADER_HEADERS}
|
||||||
macro(add_shader SRC_FILE OUT_H VAR_NAME)
|
COMMAND ${CMAKE_COMMAND}
|
||||||
cmake_parse_arguments(S "" "STAGE" "" ${ARGN})
|
-D GLSLC=${GLSLC_EXE}
|
||||||
add_custom_command(
|
-D SHADERS_DIR=${SHADERS_DIR}
|
||||||
OUTPUT "${OUT_H}"
|
-D HEADERS_DIR=${HEADERS_DIR}
|
||||||
COMMAND ${CMAKE_COMMAND}
|
-P ${CMAKE_SOURCE_DIR}/tools/shaders/compile_spirv.cmake
|
||||||
"-DGLSLC=${GLSLC_EXE}"
|
DEPENDS ${ALL_SHADER_SOURCES}
|
||||||
"-DSRC=${SRC_FILE}"
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
"-DOUT_H=${OUT_H}"
|
COMMENT "Compilando shaders SPIR-V..."
|
||||||
"-DVAR=${VAR_NAME}"
|
)
|
||||||
"-DSTAGE=${S_STAGE}"
|
|
||||||
-P "${COMPILE_SHADER_SCRIPT}"
|
|
||||||
DEPENDS "${SRC_FILE}" "${COMPILE_SHADER_SCRIPT}"
|
|
||||||
COMMENT "Compilando shader: ${VAR_NAME}"
|
|
||||||
)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
add_shader("${SHADER_VERT_SRC}" "${SHADER_VERT_H}" "postfx_vert_spv")
|
|
||||||
add_shader("${SHADER_FRAG_SRC}" "${SHADER_FRAG_H}" "postfx_frag_spv")
|
|
||||||
add_shader("${SHADER_CRTPI_SRC}" "${SHADER_CRTPI_H}" "crtpi_frag_spv" STAGE fragment)
|
|
||||||
add_shader("${SHADER_UPSCALE_SRC}" "${SHADER_UPSCALE_H}" "upscale_frag_spv")
|
|
||||||
add_shader("${SHADER_DOWNSCALE_SRC}" "${SHADER_DOWNSCALE_H}" "downscale_frag_spv")
|
|
||||||
|
|
||||||
add_custom_target(shaders DEPENDS ${ALL_SHADER_HEADERS})
|
add_custom_target(shaders DEPENDS ${ALL_SHADER_HEADERS})
|
||||||
message(STATUS "glslc encontrado: shaders se compilarán automáticamente")
|
message(STATUS "glslc encontrado: shaders se compilarán automáticamente")
|
||||||
else()
|
else()
|
||||||
foreach(_h IN LISTS ALL_SHADER_HEADERS)
|
foreach(HDR ${ALL_SHADER_HEADERS})
|
||||||
if(NOT EXISTS "${_h}")
|
if(NOT EXISTS "${HDR}")
|
||||||
message(FATAL_ERROR
|
message(FATAL_ERROR
|
||||||
"glslc no encontrado y header SPIR-V no existe: ${_h}\n"
|
"glslc no encontrado y header SPIR-V no existe: ${HDR}\n"
|
||||||
" Instala glslc: sudo apt install glslang-tools (Linux)\n"
|
" Instala glslc: sudo apt install glslang-tools (Linux)\n"
|
||||||
" choco install vulkan-sdk (Windows)\n"
|
" choco install vulkan-sdk (Windows)"
|
||||||
" O genera los headers manualmente: tools/shaders/compile_spirv.sh"
|
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
message(STATUS "glslc no encontrado - usando headers SPIR-V precompilados")
|
message(STATUS "glslc no encontrado - usando headers SPIR-V precompilados")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
message(STATUS "macOS: shaders SPIR-V omitidos (usa Metal)")
|
if(EMSCRIPTEN)
|
||||||
|
message(STATUS "Emscripten: shaders SPIR-V omitidos (SDL3 GPU no soportado en WebGL2)")
|
||||||
|
else()
|
||||||
|
message(STATUS "macOS: shaders SPIR-V omitidos (usa Metal)")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# --- 2. AÑADIR EJECUTABLE ---
|
# --- 2. AÑADIR EJECUTABLE ---
|
||||||
add_executable(${PROJECT_NAME} ${APP_SOURCES} ${EXTERNAL_SOURCES} ${RENDERING_SOURCES})
|
if(EMSCRIPTEN)
|
||||||
|
# En Emscripten no compilamos sdl3gpu_shader (SDL3 GPU no está soportado en WebGL2)
|
||||||
|
set(APP_SOURCES_WASM ${APP_SOURCES})
|
||||||
|
list(REMOVE_ITEM APP_SOURCES_WASM source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp)
|
||||||
|
add_executable(${PROJECT_NAME} ${APP_SOURCES_WASM})
|
||||||
|
else()
|
||||||
|
add_executable(${PROJECT_NAME} ${APP_SOURCES})
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT APPLE AND GLSLC_EXE)
|
if(NOT APPLE AND NOT EMSCRIPTEN AND GLSLC_EXE)
|
||||||
add_dependencies(${PROJECT_NAME} shaders)
|
add_dependencies(${PROJECT_NAME} shaders)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# --- 3. DIRECTORIOS DE INCLUSIÓN ---
|
# --- 3. DIRECTORIOS DE INCLUSIÓN ---
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||||
"${CMAKE_SOURCE_DIR}/source"
|
"${CMAKE_SOURCE_DIR}/source"
|
||||||
"${CMAKE_SOURCE_DIR}/source/external"
|
|
||||||
"${CMAKE_SOURCE_DIR}/source/rendering"
|
|
||||||
"${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu"
|
|
||||||
"${CMAKE_BINARY_DIR}"
|
"${CMAKE_BINARY_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -204,7 +232,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3)
|
|||||||
|
|
||||||
# --- 4. CONFIGURACIÓN PLATAFORMAS Y COMPILADOR ---
|
# --- 4. CONFIGURACIÓN PLATAFORMAS Y COMPILADOR ---
|
||||||
# Configuración de flags de compilación
|
# Configuración de flags de compilación
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wall)
|
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic)
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE $<$<CONFIG:RELEASE>:-Os -ffunction-sections -fdata-sections>)
|
target_compile_options(${PROJECT_NAME} PRIVATE $<$<CONFIG:RELEASE>:-Os -ffunction-sections -fdata-sections>)
|
||||||
|
|
||||||
# Definir _DEBUG en modo Debug
|
# Definir _DEBUG en modo Debug
|
||||||
@@ -231,13 +259,27 @@ elseif(APPLE)
|
|||||||
-rpath @executable_path/../Frameworks/
|
-rpath @executable_path/../Frameworks/
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
elseif(EMSCRIPTEN)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE EMSCRIPTEN_BUILD NO_SHADERS)
|
||||||
|
# -fexceptions: habilita excepciones C++ (fkyaml, std::runtime_error...) — sin esto cualquier throw llama a abort()
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE -fexceptions)
|
||||||
|
target_link_options(${PROJECT_NAME} PRIVATE
|
||||||
|
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/data@/data"
|
||||||
|
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/config@/config"
|
||||||
|
-fexceptions
|
||||||
|
-sALLOW_MEMORY_GROWTH=1
|
||||||
|
-sMAX_WEBGL_VERSION=2
|
||||||
|
-sINITIAL_MEMORY=67108864
|
||||||
|
-sASSERTIONS=1
|
||||||
|
# ASYNCIFY solo para permitir emscripten_sleep(0) durante la precarga de recursos
|
||||||
|
# (el bucle principal del juego ya usa SDL3 Callback API, no depende de ASYNCIFY).
|
||||||
|
-sASYNCIFY=1
|
||||||
|
)
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Especificar la ubicación del ejecutable
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
|
|
||||||
# --- 5. STATIC ANALYSIS TARGETS ---
|
# --- 5. STATIC ANALYSIS TARGETS ---
|
||||||
|
|
||||||
find_program(CLANG_TIDY_EXE NAMES clang-tidy)
|
find_program(CLANG_TIDY_EXE NAMES clang-tidy)
|
||||||
@@ -258,7 +300,6 @@ list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX ".*/external/.*")
|
|||||||
# cuyo uso vive en un .cpp distinto.
|
# cuyo uso vive en un .cpp distinto.
|
||||||
set(CPPCHECK_SOURCES ${ALL_SOURCE_FILES})
|
set(CPPCHECK_SOURCES ${ALL_SOURCE_FILES})
|
||||||
list(FILTER CPPCHECK_SOURCES INCLUDE REGEX ".*\\.cpp$")
|
list(FILTER CPPCHECK_SOURCES INCLUDE REGEX ".*\\.cpp$")
|
||||||
list(FILTER CPPCHECK_SOURCES EXCLUDE REGEX ".*_spv\\.h$")
|
|
||||||
|
|
||||||
# Targets de clang-tidy
|
# Targets de clang-tidy
|
||||||
if(CLANG_TIDY_EXE)
|
if(CLANG_TIDY_EXE)
|
||||||
@@ -327,13 +368,12 @@ if(CPPCHECK_EXE)
|
|||||||
--inline-suppr
|
--inline-suppr
|
||||||
--suppress=missingIncludeSystem
|
--suppress=missingIncludeSystem
|
||||||
--suppress=toomanyconfigs
|
--suppress=toomanyconfigs
|
||||||
|
--suppress=*:*/source/external/*
|
||||||
|
--suppress=*:*/source/core/rendering/sdl3gpu/spv/*
|
||||||
-D_DEBUG
|
-D_DEBUG
|
||||||
-DLINUX_BUILD
|
-DLINUX_BUILD
|
||||||
--quiet
|
--quiet
|
||||||
-I ${CMAKE_SOURCE_DIR}/source
|
-I ${CMAKE_SOURCE_DIR}/source
|
||||||
-I ${CMAKE_SOURCE_DIR}/source/external
|
|
||||||
-I ${CMAKE_SOURCE_DIR}/source/rendering
|
|
||||||
-I ${CMAKE_SOURCE_DIR}/source/rendering/sdl3gpu
|
|
||||||
${CPPCHECK_SOURCES}
|
${CPPCHECK_SOURCES}
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
COMMENT "Running cppcheck..."
|
COMMENT "Running cppcheck..."
|
||||||
@@ -341,3 +381,55 @@ if(CPPCHECK_EXE)
|
|||||||
else()
|
else()
|
||||||
message(STATUS "cppcheck no encontrado - target 'cppcheck' no disponible")
|
message(STATUS "cppcheck no encontrado - target 'cppcheck' no disponible")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# --- EINA STANDALONE: pack_resources ---
|
||||||
|
# Executable auxiliar que empaqueta `data/` a `resources.pack`.
|
||||||
|
# No es compila per defecte (EXCLUDE_FROM_ALL). Build explícit:
|
||||||
|
# cmake --build build --target pack_resources
|
||||||
|
# Després executar: ./build/pack_resources data resources.pack
|
||||||
|
if(NOT EMSCRIPTEN)
|
||||||
|
add_executable(pack_resources EXCLUDE_FROM_ALL
|
||||||
|
tools/pack_resources/pack_resources.cpp
|
||||||
|
source/core/resources/resource_pack.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(pack_resources PRIVATE "${CMAKE_SOURCE_DIR}/source")
|
||||||
|
target_compile_options(pack_resources PRIVATE -Wall -Wextra -Wpedantic)
|
||||||
|
|
||||||
|
# Regeneració automàtica de resources.pack en cada build si canvia data/.
|
||||||
|
file(GLOB_RECURSE DATA_FILES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/data/*")
|
||||||
|
set(RESOURCE_PACK "${CMAKE_BINARY_DIR}/resources.pack")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${RESOURCE_PACK}
|
||||||
|
COMMAND $<TARGET_FILE:pack_resources>
|
||||||
|
"${CMAKE_SOURCE_DIR}/data"
|
||||||
|
"${RESOURCE_PACK}"
|
||||||
|
DEPENDS pack_resources ${DATA_FILES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Empaquetant data/ → resources.pack"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(resource_pack ALL DEPENDS ${RESOURCE_PACK})
|
||||||
|
add_dependencies(${PROJECT_NAME} resource_pack)
|
||||||
|
|
||||||
|
# --- CÒPIA DE gamecontrollerdb.txt AL COSTAT DEL BINARI ---
|
||||||
|
# SDL_AddGamepadMappingsFromFile només llegeix del filesystem real (no del
|
||||||
|
# pack), així que el fitxer ha de viure al directori del binari. Es copia
|
||||||
|
# només si existeix per no fallar la build d'algú que encara no ha fet
|
||||||
|
# `make controllerdb`.
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt")
|
||||||
|
set(CONTROLLER_DB "${CMAKE_BINARY_DIR}/gamecontrollerdb.txt")
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CONTROLLER_DB}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
"${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt"
|
||||||
|
"${CONTROLLER_DB}"
|
||||||
|
DEPENDS "${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt"
|
||||||
|
COMMENT "Copiant gamecontrollerdb.txt → build/"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
add_custom_target(controller_db ALL DEPENDS ${CONTROLLER_DB})
|
||||||
|
add_dependencies(${PROJECT_NAME} controller_db)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -2,17 +2,13 @@
|
|||||||
# DIRECTORIES
|
# DIRECTORIES
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
||||||
DIR_TOOLS := $(addsuffix /, $(DIR_ROOT)tools)
|
BUILDDIR := build
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# TARGET NAMES
|
# TARGET NAMES
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
TARGET_NAME := coffee_crisis_arcade_edition
|
TARGET_NAME := coffee_crisis_arcade_edition
|
||||||
ifeq ($(OS),Windows_NT)
|
TARGET_FILE := $(BUILDDIR)/$(TARGET_NAME)
|
||||||
TARGET_FILE := $(DIR_ROOT)$(TARGET_NAME).exe
|
|
||||||
else
|
|
||||||
TARGET_FILE := $(DIR_ROOT)$(TARGET_NAME)
|
|
||||||
endif
|
|
||||||
APP_NAME := Coffee Crisis Arcade Edition
|
APP_NAME := Coffee Crisis Arcade Edition
|
||||||
DIST_DIR := dist
|
DIST_DIR := dist
|
||||||
RELEASE_FOLDER := dist/_tmp
|
RELEASE_FOLDER := dist/_tmp
|
||||||
@@ -22,16 +18,33 @@ RESOURCE_FILE := release/windows/coffee.res
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# TOOLS
|
# TOOLS
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
DIR_PACK_TOOL := $(DIR_TOOLS)pack_resources
|
SHADER_CMAKE := $(DIR_ROOT)tools/shaders/compile_spirv.cmake
|
||||||
SHADER_SCRIPT := $(DIR_ROOT)tools/shaders/compile_spirv.sh
|
SHADERS_DIR := $(DIR_ROOT)data/shaders
|
||||||
|
HEADERS_DIR := $(DIR_ROOT)source/core/rendering/sdl3gpu/spv
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
GLSLC := $(shell where glslc 2>NUL)
|
||||||
|
else
|
||||||
|
GLSLC := $(shell command -v glslc 2>/dev/null)
|
||||||
|
endif
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# VERSION (fecha actual)
|
# VERSION (extraída de defines.hpp)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
VERSION := $(shell powershell -Command "Get-Date -Format 'yyyy-MM-dd'")
|
VERSION := $(shell powershell -Command "(Select-String -Path 'source/utils/defines.hpp' -Pattern 'constexpr const char\* VERSION = \"(.+?)\"').Matches.Groups[1].Value")
|
||||||
else
|
else
|
||||||
VERSION := $(shell date +%Y-%m-%d)
|
VERSION := $(shell grep 'constexpr const char\* VERSION' source/utils/defines.hpp | sed -E 's/.*VERSION = "([^"]+)".*/\1/')
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Hash del commit actual, computado en el host. Se pasa a CMake via -DGIT_HASH
|
||||||
|
# para que el build en docker/emscripten no falle por "dubious ownership" de Git.
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>NUL)
|
||||||
|
else
|
||||||
|
GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>/dev/null)
|
||||||
|
endif
|
||||||
|
ifeq ($(GIT_HASH),)
|
||||||
|
GIT_HASH := unknown
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -45,11 +58,15 @@ endif
|
|||||||
# WINDOWS-SPECIFIC VARIABLES
|
# WINDOWS-SPECIFIC VARIABLES
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
WIN_TARGET_FILE := $(DIR_ROOT)$(APP_NAME)
|
WIN_TARGET_FILE := $(BUILDDIR)/$(APP_NAME)
|
||||||
WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME)
|
WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME)
|
||||||
|
# Escapa apòstrofs per a PowerShell (duplica ' → ''). Sense això, APP_NAMEs
|
||||||
|
# com "JailDoctor's Dilemma" trencarien el parsing de -Destination '...'.
|
||||||
|
WIN_RELEASE_FILE_PS := $(subst ','',$(WIN_RELEASE_FILE))
|
||||||
else
|
else
|
||||||
WIN_TARGET_FILE := $(TARGET_FILE)
|
WIN_TARGET_FILE := $(TARGET_FILE)
|
||||||
WIN_RELEASE_FILE := $(RELEASE_FILE)
|
WIN_RELEASE_FILE := $(RELEASE_FILE)
|
||||||
|
WIN_RELEASE_FILE_PS := $(WIN_RELEASE_FILE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -59,7 +76,6 @@ WINDOWS_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-win32-x64.z
|
|||||||
MACOS_INTEL_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-intel.dmg
|
MACOS_INTEL_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-intel.dmg
|
||||||
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-apple-silicon.dmg
|
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-apple-silicon.dmg
|
||||||
LINUX_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux.tar.gz
|
LINUX_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux.tar.gz
|
||||||
RASPI_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-raspberry.tar.gz
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# PLATAFORMA
|
# PLATAFORMA
|
||||||
@@ -76,57 +92,98 @@ else
|
|||||||
UNAME_S := $(shell uname -s)
|
UNAME_S := $(shell uname -s)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# CMAKE GENERATOR (usa Ninja si está disponible; si no, MinGW Makefiles en
|
||||||
|
# Windows / generador por defecto en Linux/macOS). Ninja paraleliza mejor.
|
||||||
|
# ==============================================================================
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
# Dins MSYS2/Git Bash/MinGW, $(shell ...) usa sh.exe i "NUL" NO és
|
||||||
|
# dispositiu — un redirect "2>NUL" crearia un fitxer literal anomenat
|
||||||
|
# NUL al cwd. Detectem MSYSTEM per usar /dev/null en aquests entorns.
|
||||||
|
ifneq ($(MSYSTEM),)
|
||||||
|
NULDEV := /dev/null
|
||||||
|
else
|
||||||
|
NULDEV := NUL
|
||||||
|
endif
|
||||||
|
HAS_NINJA := $(shell ninja --version 2>$(NULDEV))
|
||||||
|
ifneq ($(HAS_NINJA),)
|
||||||
|
CMAKE_GEN := -G "Ninja"
|
||||||
|
else
|
||||||
|
CMAKE_GEN := -G "MinGW Makefiles"
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
HAS_NINJA := $(shell ninja --version 2>/dev/null)
|
||||||
|
ifneq ($(HAS_NINJA),)
|
||||||
|
CMAKE_GEN := -G "Ninja"
|
||||||
|
else
|
||||||
|
CMAKE_GEN :=
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# COMPILACIÓN CON CMAKE
|
# COMPILACIÓN CON CMAKE
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
all:
|
all:
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build
|
@cmake --build build
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Debug -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build
|
@cmake --build build
|
||||||
|
|
||||||
|
run: all
|
||||||
|
@./$(TARGET_FILE)
|
||||||
|
|
||||||
|
run-debug: debug
|
||||||
|
@./$(TARGET_FILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
|
rebuild: clean all
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# RELEASE AUTOMÁTICO (detecta SO)
|
# RELEASE AUTOMÁTICO (detecta SO)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
release:
|
release:
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
@"$(MAKE)" windows_release
|
@"$(MAKE)" _windows-release
|
||||||
else
|
else
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
@$(MAKE) macos_release
|
@$(MAKE) _macos-release
|
||||||
else
|
else
|
||||||
@$(MAKE) linux_release
|
@$(MAKE) _linux-release
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# REGLAS PARA HERRAMIENTA DE EMPAQUETADO Y RESOURCES.PACK
|
# EMPAQUETADO DE RECURSOS (build previ de l'eina + execució)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
pack_tool:
|
pack:
|
||||||
@$(MAKE) -C $(DIR_PACK_TOOL)
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build --target pack_resources
|
||||||
resources.pack:
|
@./build/pack_resources data build/resources.pack
|
||||||
@$(MAKE) -C $(DIR_PACK_TOOL) pack
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# COMPILACIÓN DE SHADERS
|
# REGLAS PARA COMPILACIÓN DE SHADERS (multiplataforma via cmake)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
spirv:
|
compile-shaders:
|
||||||
@echo "Compilando shaders SPIR-V..."
|
ifdef GLSLC
|
||||||
$(SHADER_SCRIPT)
|
@cmake -D GLSLC=$(GLSLC) -D SHADERS_DIR=$(SHADERS_DIR) -D HEADERS_DIR=$(HEADERS_DIR) -P $(SHADER_CMAKE)
|
||||||
|
else
|
||||||
|
@echo "glslc no encontrado - asegurate de que los headers SPIR-V precompilados existen"
|
||||||
|
endif
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# COMPILACIÓN PARA WINDOWS (RELEASE)
|
# COMPILACIÓN PARA WINDOWS (RELEASE)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
windows_release:
|
_windows-release:
|
||||||
@$(MAKE) resources.pack
|
@$(MAKE) pack
|
||||||
@echo off
|
@echo off
|
||||||
@echo Creando release para Windows - Version: $(VERSION)
|
@echo Creando release para Windows - Version: $(VERSION)
|
||||||
|
|
||||||
# Compila con cmake
|
# Compila con cmake
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build
|
@cmake --build build
|
||||||
|
|
||||||
# Crea carpeta de distribución y carpeta temporal 'RELEASE_FOLDER'
|
# Crea carpeta de distribución y carpeta temporal 'RELEASE_FOLDER'
|
||||||
@@ -136,13 +193,13 @@ windows_release:
|
|||||||
|
|
||||||
# Copia la carpeta 'config' y el archivo 'resources.pack'
|
# Copia la carpeta 'config' y el archivo 'resources.pack'
|
||||||
@powershell -Command "Copy-Item -Path 'config' -Destination '$(RELEASE_FOLDER)' -recurse -Force"
|
@powershell -Command "Copy-Item -Path 'config' -Destination '$(RELEASE_FOLDER)' -recurse -Force"
|
||||||
@powershell -Command "Copy-Item -Path 'resources.pack' -Destination '$(RELEASE_FOLDER)'"
|
@powershell -Command "Copy-Item -Path 'build/resources.pack' -Destination '$(RELEASE_FOLDER)'"
|
||||||
|
|
||||||
# Copia los ficheros que estan en la raíz del proyecto
|
# Copia los ficheros que estan en la raíz del proyecto
|
||||||
@powershell -Command "Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)'"
|
@powershell -Command "Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)'"
|
||||||
@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
|
@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
|
||||||
@powershell -Command "Copy-Item 'release\windows\dll\*.dll' -Destination '$(RELEASE_FOLDER)'"
|
@powershell -Command "Copy-Item 'release\windows\dll\*.dll' -Destination '$(RELEASE_FOLDER)'"
|
||||||
@powershell -Command "Copy-Item -Path '$(TARGET_FILE)' -Destination '$(WIN_RELEASE_FILE).exe'"
|
@powershell -Command "Copy-Item -Path '$(TARGET_FILE).exe' -Destination '$(WIN_RELEASE_FILE_PS).exe'"
|
||||||
strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded
|
strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded
|
||||||
|
|
||||||
# Crea el fichero .zip
|
# Crea el fichero .zip
|
||||||
@@ -156,16 +213,32 @@ windows_release:
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# COMPILACIÓN PARA MACOS (RELEASE)
|
# COMPILACIÓN PARA MACOS (RELEASE)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
macos_release:
|
_macos-release:
|
||||||
@$(MAKE) resources.pack
|
@$(MAKE) pack
|
||||||
@echo "Creando release para macOS - Version: $(VERSION)"
|
@echo "Creando release para macOS - Version: $(VERSION)"
|
||||||
|
|
||||||
# Verificar e instalar create-dmg si es necesario
|
# Verifica dependencias necesarias (create-dmg). Si falta, intenta instalarla
|
||||||
@which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg)
|
# con brew; si brew tampoco está, indica el comando exacto al usuario.
|
||||||
|
@command -v create-dmg >/dev/null 2>&1 || { \
|
||||||
# Compila la versión para procesadores Intel con cmake
|
echo ""; \
|
||||||
@cmake -S . -B build/intel -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DMACOS_BUNDLE=ON
|
echo "============================================"; \
|
||||||
@cmake --build build/intel
|
echo " Falta la dependencia: create-dmg"; \
|
||||||
|
echo "============================================"; \
|
||||||
|
if command -v brew >/dev/null 2>&1; then \
|
||||||
|
echo " Instalando con: brew install create-dmg"; \
|
||||||
|
brew install create-dmg || { \
|
||||||
|
echo ""; \
|
||||||
|
echo " ERROR: 'brew install create-dmg' ha fallado."; \
|
||||||
|
echo " Ejecuta el comando manualmente y vuelve a probar."; \
|
||||||
|
exit 1; \
|
||||||
|
}; \
|
||||||
|
else \
|
||||||
|
echo " Homebrew no está instalado."; \
|
||||||
|
echo " Instálalo desde https://brew.sh y luego ejecuta:"; \
|
||||||
|
echo " brew install create-dmg"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
}
|
||||||
|
|
||||||
# Elimina datos de compilaciones anteriores
|
# Elimina datos de compilaciones anteriores
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
@@ -181,39 +254,64 @@ macos_release:
|
|||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
|
|
||||||
# Copia carpetas y ficheros
|
# Copia carpetas y ficheros
|
||||||
cp -R config "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
cp build/resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
cp resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
|
||||||
cp -R release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
cp -R release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||||
cp release/icons/*.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
cp release/icons/*.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
cp release/macos/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
|
cp release/macos/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
|
||||||
cp LICENSE "$(RELEASE_FOLDER)"
|
cp LICENSE "$(RELEASE_FOLDER)"
|
||||||
cp README.md "$(RELEASE_FOLDER)"
|
cp README.md "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Copia el ejecutable Intel al bundle
|
# Actualiza versión en Info.plist
|
||||||
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
@echo "Actualizando Info.plist con versión $(VERSION)..."
|
||||||
|
@RAW_VERSION=$$(echo "$(VERSION)" | sed 's/^v//'); \
|
||||||
|
sed -i '' '/<key>CFBundleShortVersionString<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
|
||||||
|
sed -i '' '/<key>CFBundleVersion<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
|
||||||
|
|
||||||
# Firma la aplicación
|
# Compila y empaqueta la versión Intel (best-effort: si falla, se omite el
|
||||||
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
# DMG Intel y continúa con la build de Apple Silicon).
|
||||||
|
@echo ""
|
||||||
# Empaqueta el .dmg de la versión Intel con create-dmg
|
@echo "============================================"
|
||||||
@echo "Creando DMG Intel con iconos de 96x96..."
|
@echo " Compilando version Intel (x86_64)"
|
||||||
create-dmg \
|
@echo "============================================"
|
||||||
--volname "$(APP_NAME)" \
|
@if cmake -S . -B build/intel -DCMAKE_BUILD_TYPE=Release \
|
||||||
--window-pos 200 120 \
|
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
||||||
--window-size 720 300 \
|
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 \
|
||||||
--icon-size 96 \
|
-DMACOS_BUNDLE=ON \
|
||||||
--text-size 12 \
|
-DGIT_HASH=$(GIT_HASH) \
|
||||||
--icon "$(APP_NAME).app" 278 102 \
|
&& cmake --build build/intel; then \
|
||||||
--icon "LICENSE" 441 102 \
|
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"; \
|
||||||
--icon "README.md" 604 102 \
|
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"; \
|
||||||
--app-drop-link 115 102 \
|
echo "Creando DMG Intel con iconos de 96x96..."; \
|
||||||
--hide-extension "$(APP_NAME).app" \
|
create-dmg \
|
||||||
"$(MACOS_INTEL_RELEASE)" \
|
--volname "$(APP_NAME)" \
|
||||||
"$(RELEASE_FOLDER)" || true
|
--window-pos 200 120 \
|
||||||
@echo "Release Intel creado: $(MACOS_INTEL_RELEASE)"
|
--window-size 720 300 \
|
||||||
|
--icon-size 96 \
|
||||||
|
--text-size 12 \
|
||||||
|
--icon "$(APP_NAME).app" 278 102 \
|
||||||
|
--icon "LICENSE" 441 102 \
|
||||||
|
--icon "README.md" 604 102 \
|
||||||
|
--app-drop-link 115 102 \
|
||||||
|
--hide-extension "$(APP_NAME).app" \
|
||||||
|
"$(MACOS_INTEL_RELEASE)" \
|
||||||
|
"$(RELEASE_FOLDER)" || true; \
|
||||||
|
echo "Release Intel creado: $(MACOS_INTEL_RELEASE)"; \
|
||||||
|
else \
|
||||||
|
echo ""; \
|
||||||
|
echo "============================================"; \
|
||||||
|
echo " WARNING: la build Intel ha fallado."; \
|
||||||
|
echo " Se omite el DMG Intel y se continúa con"; \
|
||||||
|
echo " la build de Apple Silicon."; \
|
||||||
|
echo "============================================"; \
|
||||||
|
echo ""; \
|
||||||
|
fi
|
||||||
|
|
||||||
# Compila la versión para procesadores Apple Silicon con cmake
|
# Compila la versión para procesadores Apple Silicon con cmake
|
||||||
@cmake -S . -B build/arm -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DMACOS_BUNDLE=ON
|
@echo ""
|
||||||
|
@echo "============================================"
|
||||||
|
@echo " Compilando version Apple Silicon (arm64)"
|
||||||
|
@echo "============================================"
|
||||||
|
@cmake -S . -B build/arm -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DMACOS_BUNDLE=ON -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build/arm
|
@cmake --build build/arm
|
||||||
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
||||||
|
|
||||||
@@ -246,12 +344,12 @@ macos_release:
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# COMPILACIÓN PARA LINUX (RELEASE)
|
# COMPILACIÓN PARA LINUX (RELEASE)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
linux_release:
|
_linux-release:
|
||||||
@$(MAKE) resources.pack
|
@$(MAKE) pack
|
||||||
@echo "Creando release para Linux - Version: $(VERSION)"
|
@echo "Creando release para Linux - Version: $(VERSION)"
|
||||||
|
|
||||||
# Compila con cmake
|
# Compila con cmake
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build
|
@cmake --build build
|
||||||
|
|
||||||
# Elimina carpeta temporal previa y la recrea (crea dist/ si no existe)
|
# Elimina carpeta temporal previa y la recrea (crea dist/ si no existe)
|
||||||
@@ -259,8 +357,7 @@ linux_release:
|
|||||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# Copia ficheros
|
# Copia ficheros
|
||||||
cp -R config "$(RELEASE_FOLDER)"
|
cp build/resources.pack "$(RELEASE_FOLDER)"
|
||||||
cp resources.pack "$(RELEASE_FOLDER)"
|
|
||||||
cp LICENSE "$(RELEASE_FOLDER)"
|
cp LICENSE "$(RELEASE_FOLDER)"
|
||||||
cp README.md "$(RELEASE_FOLDER)"
|
cp README.md "$(RELEASE_FOLDER)"
|
||||||
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
||||||
@@ -275,161 +372,86 @@ linux_release:
|
|||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# COMPILACIÓN PARA LINUX (RELEASE CON INTEGRACIÓN DESKTOP)
|
# COMPILACIÓN PARA WEBASSEMBLY (requiere Docker)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
linux_release_desktop:
|
wasm:
|
||||||
@$(MAKE) resources.pack
|
@echo "Compilando para WebAssembly - Version: $(VERSION) ($(GIT_HASH))"
|
||||||
@echo "Creando release con integracion desktop para Linux - Version: $(VERSION)"
|
docker run --rm \
|
||||||
|
--user $(shell id -u):$(shell id -g) \
|
||||||
|
-v $(DIR_ROOT):/src \
|
||||||
|
-w /src \
|
||||||
|
emscripten/emsdk:latest \
|
||||||
|
bash -c "emcmake cmake -S . -B build/wasm -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH) && cmake --build build/wasm"
|
||||||
|
$(MKDIR) "$(DIST_DIR)/wasm"
|
||||||
|
cp build/wasm/$(TARGET_NAME).html $(DIST_DIR)/wasm/
|
||||||
|
cp build/wasm/$(TARGET_NAME).js $(DIST_DIR)/wasm/
|
||||||
|
cp build/wasm/$(TARGET_NAME).wasm $(DIST_DIR)/wasm/
|
||||||
|
cp build/wasm/$(TARGET_NAME).data $(DIST_DIR)/wasm/
|
||||||
|
@echo "Output: $(DIST_DIR)/wasm/"
|
||||||
|
scp $(DIST_DIR)/wasm/$(TARGET_NAME).js $(DIST_DIR)/wasm/$(TARGET_NAME).wasm $(DIST_DIR)/wasm/$(TARGET_NAME).data \
|
||||||
|
maverick:/home/sergio/gitea/web_jailgames/static/games/coffee-crisis-arcade-edition/wasm/
|
||||||
|
ssh maverick 'cd /home/sergio/gitea/web_jailgames && ./deploy.sh'
|
||||||
|
@echo "Deployed to maverick"
|
||||||
|
|
||||||
# Compila con cmake
|
# Versió Debug del build wasm: build local sense deploy. Sortida a dist/wasm-debug/.
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
wasm-debug:
|
||||||
@cmake --build build
|
@echo "Compilando WebAssembly Debug - Version: $(VERSION) ($(GIT_HASH))"
|
||||||
|
docker run --rm \
|
||||||
# Elimina carpetas previas y recrea (crea dist/ si no existe)
|
--user $(shell id -u):$(shell id -g) \
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
-v $(DIR_ROOT):/src \
|
||||||
|
-w /src \
|
||||||
# Crea la estructura de directorios estándar para Linux
|
emscripten/emsdk:latest \
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)"
|
bash -c "emcmake cmake -S . -B build/wasm-debug -DCMAKE_BUILD_TYPE=Debug -DGIT_HASH=$(GIT_HASH) && cmake --build build/wasm-debug"
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin"
|
$(MKDIR) "$(DIST_DIR)/wasm-debug"
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications"
|
cp build/wasm-debug/$(TARGET_NAME).html $(DIST_DIR)/wasm-debug/
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps"
|
cp build/wasm-debug/$(TARGET_NAME).js $(DIST_DIR)/wasm-debug/
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/$(TARGET_NAME)"
|
cp build/wasm-debug/$(TARGET_NAME).wasm $(DIST_DIR)/wasm-debug/
|
||||||
|
cp build/wasm-debug/$(TARGET_NAME).data $(DIST_DIR)/wasm-debug/
|
||||||
# Copia ficheros del juego
|
@echo "Output: $(DIST_DIR)/wasm-debug/"
|
||||||
cp -R config "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/$(TARGET_NAME)/"
|
|
||||||
cp resources.pack "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/$(TARGET_NAME)/"
|
|
||||||
cp LICENSE "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
|
||||||
cp README.md "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
|
||||||
|
|
||||||
# Copia el ejecutable
|
|
||||||
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)"
|
|
||||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)" --strip-unneeded
|
|
||||||
|
|
||||||
# Crea el archivo .desktop
|
|
||||||
@echo '[Desktop Entry]' > "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Version=1.0' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Type=Application' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Name=$(APP_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Comment=Arcade action game - defend Earth from alien invasion!' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Exec=/opt/$(TARGET_NAME)/bin/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Icon=$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Path=/opt/$(TARGET_NAME)/share/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Terminal=false' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'StartupNotify=true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Categories=Game;ArcadeGame;' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
@echo 'Keywords=arcade;action;shooter;retro;' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
|
||||||
|
|
||||||
# Copia el icono (si existe) y lo redimensiona si es necesario
|
|
||||||
@if [ -f "release/icons/icon.png" ]; then \
|
|
||||||
if command -v magick >/dev/null 2>&1; then \
|
|
||||||
magick "release/icons/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
|
||||||
echo "Icono redimensionado de release/icons/icon.png (usando ImageMagick)"; \
|
|
||||||
elif command -v convert >/dev/null 2>&1; then \
|
|
||||||
convert "release/icons/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
|
||||||
echo "Icono redimensionado de release/icons/icon.png (usando ImageMagick legacy)"; \
|
|
||||||
elif command -v ffmpeg >/dev/null 2>&1; then \
|
|
||||||
ffmpeg -i "release/icons/icon.png" -vf scale=256:256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png" -y -loglevel quiet; \
|
|
||||||
echo "Icono redimensionado de release/icons/icon.png (usando ffmpeg)"; \
|
|
||||||
else \
|
|
||||||
cp "release/icons/icon.png" "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
|
||||||
echo "Icono copiado sin redimensionar (instalar ImageMagick o ffmpeg para redimensionado automatico)"; \
|
|
||||||
fi; \
|
|
||||||
else \
|
|
||||||
echo "Advertencia: No se encontró release/icons/icon.png - crear icono manualmente"; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Crea script de instalación
|
|
||||||
@echo '#!/bin/bash' > "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'echo "Instalando $(APP_NAME)..."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo mkdir -p /opt/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo cp -R bin /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo cp -R share /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo cp LICENSE /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo cp README.md /opt/$(TARGET_NAME)/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo mkdir -p /usr/share/applications' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo mkdir -p /usr/share/icons/hicolor/256x256/apps' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo cp /opt/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop /usr/share/applications/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo cp /opt/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png /usr/share/icons/hicolor/256x256/apps/' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo update-desktop-database /usr/share/applications 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'sudo gtk-update-icon-cache /usr/share/icons/hicolor 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'echo "$(APP_NAME) instalado correctamente!"' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
@echo 'echo "Ya puedes encontrarlo en el menu de aplicaciones en la categoria Juegos."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
chmod +x "$(RELEASE_FOLDER)/$(TARGET_NAME)/install.sh"
|
|
||||||
|
|
||||||
# Crea script de desinstalación
|
|
||||||
@echo '#!/bin/bash' > "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
@echo 'echo "Desinstalando $(APP_NAME)..."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
@echo 'sudo rm -rf /opt/$(TARGET_NAME)' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
@echo 'sudo rm -f /usr/share/applications/$(TARGET_NAME).desktop' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
@echo 'sudo rm -f /usr/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
@echo 'sudo update-desktop-database /usr/share/applications 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
@echo 'sudo gtk-update-icon-cache /usr/share/icons/hicolor 2>/dev/null || true' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
@echo 'echo "$(APP_NAME) desinstalado correctamente."' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
chmod +x "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
|
||||||
|
|
||||||
# Empaqueta ficheros
|
|
||||||
$(RMFILE) "$(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
|
||||||
tar -czvf "$(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz" -C "$(RELEASE_FOLDER)" .
|
|
||||||
@echo "Release con integracion desktop creado: $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
|
||||||
@echo "Para instalar: extraer y ejecutar ./$(TARGET_NAME)/install.sh"
|
|
||||||
|
|
||||||
# Elimina la carpeta temporal
|
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# COMPILACIÓN PARA RASPBERRY PI (RELEASE)
|
|
||||||
# ==============================================================================
|
|
||||||
raspi_release:
|
|
||||||
@$(MAKE) resources.pack
|
|
||||||
@echo "Creando release para Raspberry Pi - Version: $(VERSION)"
|
|
||||||
|
|
||||||
# Compila con cmake
|
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
|
||||||
@cmake --build build
|
|
||||||
|
|
||||||
# Elimina carpetas previas y recrea (crea dist/ si no existe)
|
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
|
||||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
|
||||||
|
|
||||||
# Copia ficheros
|
|
||||||
cp -R config "$(RELEASE_FOLDER)"
|
|
||||||
cp resources.pack "$(RELEASE_FOLDER)"
|
|
||||||
cp LICENSE "$(RELEASE_FOLDER)"
|
|
||||||
cp README.md "$(RELEASE_FOLDER)"
|
|
||||||
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
|
||||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
|
||||||
|
|
||||||
# Empaqueta ficheros
|
|
||||||
$(RMFILE) "$(RASPI_RELEASE)"
|
|
||||||
tar -czvf "$(RASPI_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
|
||||||
@echo "Release creado: $(RASPI_RELEASE)"
|
|
||||||
|
|
||||||
# Elimina la carpeta temporal
|
|
||||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CODE QUALITY (delegados a cmake)
|
# CODE QUALITY (delegados a cmake)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
format:
|
format:
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build --target format
|
@cmake --build build --target format
|
||||||
|
|
||||||
format-check:
|
format-check:
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build --target format-check
|
@cmake --build build --target format-check
|
||||||
|
|
||||||
tidy:
|
tidy:
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build --target tidy
|
@cmake --build build --target tidy
|
||||||
|
|
||||||
tidy-fix:
|
tidy-fix:
|
||||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
@cmake --build build --target tidy-fix
|
@cmake --build build --target tidy-fix
|
||||||
|
|
||||||
|
cppcheck:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build --target cppcheck
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# GIT HOOKS
|
||||||
|
# ==============================================================================
|
||||||
|
hooks-install:
|
||||||
|
@git config core.hooksPath .githooks
|
||||||
|
@echo "Git hooks activats: $(shell pwd)/.githooks"
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# DESCARGA DE GAMECONTROLLERDB
|
||||||
|
# ==============================================================================
|
||||||
|
controllerdb:
|
||||||
|
@echo "Descargando gamecontrollerdb.txt..."
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt \
|
||||||
|
-o gamecontrollerdb.txt
|
||||||
|
@echo "gamecontrollerdb.txt actualizado"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# REGLAS ESPECIALES
|
# REGLAS ESPECIALES
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
show_version:
|
show-version:
|
||||||
@echo "Version actual: $(VERSION)"
|
@echo "Version actual: $(VERSION)"
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@@ -440,27 +462,31 @@ help:
|
|||||||
@echo " make - Compilar con cmake (Release)"
|
@echo " make - Compilar con cmake (Release)"
|
||||||
@echo " make debug - Compilar con cmake (Debug)"
|
@echo " make debug - Compilar con cmake (Debug)"
|
||||||
@echo ""
|
@echo ""
|
||||||
|
@echo " Ejecucion:"
|
||||||
|
@echo " make run - Compilar (Release) y ejecutar"
|
||||||
|
@echo " make run-debug - Compilar (Debug) y ejecutar"
|
||||||
|
@echo ""
|
||||||
@echo " Release:"
|
@echo " Release:"
|
||||||
@echo " make release - Crear release (detecta SO automaticamente)"
|
@echo " make release - Crear release (detecta SO automaticamente)"
|
||||||
@echo " make windows_release - Crear release para Windows"
|
@echo " make wasm - Crear build WebAssembly (requiere Docker) en dist/wasm"
|
||||||
@echo " make linux_release - Crear release basico para Linux"
|
@echo " make wasm-debug - Build WebAssembly Debug local (sin deploy)"
|
||||||
@echo " make linux_release_desktop - Crear release con integracion desktop para Linux"
|
|
||||||
@echo " make macos_release - Crear release para macOS"
|
|
||||||
@echo " make raspi_release - Crear release para Raspberry Pi"
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " Herramientas:"
|
@echo " Herramientas:"
|
||||||
@echo " make spirv - Compilar shaders SPIR-V"
|
@echo " make compile-shaders - Compilar shaders SPIR-V"
|
||||||
@echo " make pack_tool - Compilar herramienta de empaquetado"
|
@echo " make pack - Empaquetar recursos a $(BUILDDIR)/resources.pack"
|
||||||
@echo " make resources.pack - Generar pack de recursos desde data/"
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " Calidad de codigo:"
|
@echo " Calidad de codigo:"
|
||||||
@echo " make format - Formatear codigo con clang-format"
|
@echo " make format - Formatear codigo con clang-format"
|
||||||
@echo " make format-check - Verificar formato sin modificar"
|
@echo " make format-check - Verificar formato sin modificar"
|
||||||
@echo " make tidy - Analisis estatico con clang-tidy"
|
@echo " make tidy - Analisis estatico con clang-tidy"
|
||||||
@echo " make tidy-fix - Analisis estatico con auto-fix"
|
@echo " make tidy-fix - Analisis estatico con auto-fix"
|
||||||
|
@echo " make cppcheck - Analisis estatico con cppcheck"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " Otros:"
|
@echo " Otros:"
|
||||||
@echo " make show_version - Mostrar version actual ($(VERSION))"
|
@echo " make clean - Borrar carpeta $(BUILDDIR)/"
|
||||||
|
@echo " make rebuild - clean + all"
|
||||||
|
@echo " make show-version - Mostrar version actual ($(VERSION))"
|
||||||
|
@echo " make hooks-install - Activar git hooks del proyecto"
|
||||||
@echo " make help - Mostrar esta ayuda"
|
@echo " make help - Mostrar esta ayuda"
|
||||||
|
|
||||||
.PHONY: all debug release windows_release macos_release linux_release linux_release_desktop raspi_release pack_tool resources.pack spirv format format-check tidy tidy-fix show_version help
|
.PHONY: all debug run run-debug clean rebuild release _windows-release _macos-release _linux-release wasm wasm-debug pack compile-shaders format format-check tidy tidy-fix cppcheck controllerdb hooks-install show-version help
|
||||||
|
|||||||
@@ -10,14 +10,15 @@ DATA|${SYSTEM_FOLDER}/postfx.yaml|optional,absolute
|
|||||||
DATA|${SYSTEM_FOLDER}/crtpi.yaml|optional,absolute
|
DATA|${SYSTEM_FOLDER}/crtpi.yaml|optional,absolute
|
||||||
DATA|${SYSTEM_FOLDER}/score.bin|optional,absolute
|
DATA|${SYSTEM_FOLDER}/score.bin|optional,absolute
|
||||||
|
|
||||||
# Archivos de configuración del juego
|
# Dades de gameplay (viatgen dins el pack)
|
||||||
DATA|${PREFIX}/config/formations.txt
|
DATA|/data/config/gameplay/formations.txt
|
||||||
DATA|${PREFIX}/config/gamecontrollerdb.txt
|
DATA|/data/config/gameplay/pools.txt
|
||||||
DATA|${PREFIX}/config/param_320x240.txt
|
DATA|/data/config/gameplay/stages.txt
|
||||||
DATA|${PREFIX}/config/param_320x256.txt
|
|
||||||
DATA|${PREFIX}/config/param_red.txt
|
# Presets de paràmetres (viatgen dins el pack)
|
||||||
DATA|${PREFIX}/config/pools.txt
|
DATA|/data/config/presets/classic.txt
|
||||||
DATA|${PREFIX}/config/stages.txt
|
DATA|/data/config/presets/arcade.txt
|
||||||
|
DATA|/data/config/presets/red.txt
|
||||||
|
|
||||||
# Archivos con los datos de la demo
|
# Archivos con los datos de la demo
|
||||||
DEMODATA|/data/demo/demo1.bin
|
DEMODATA|/data/demo/demo1.bin
|
||||||
@@ -22,7 +22,7 @@ fade.venetian_size 12 # Tamaño de las bandas para el efecto v
|
|||||||
|
|
||||||
# --- SCOREBOARD ---
|
# --- SCOREBOARD ---
|
||||||
scoreboard.rect.x 0 # Posición X del marcador
|
scoreboard.rect.x 0 # Posición X del marcador
|
||||||
scoreboard.rect.y 216 # Posición Y del marcador
|
scoreboard.rect.y 200 # Posición Y del marcador
|
||||||
scoreboard.rect.w 320 # Ancho del marcador
|
scoreboard.rect.w 320 # Ancho del marcador
|
||||||
scoreboard.rect.h 40 # Alto del marcador
|
scoreboard.rect.h 40 # Alto del marcador
|
||||||
scoreboard.separator_autocolor true # ¿El separador usa color automático?
|
scoreboard.separator_autocolor true # ¿El separador usa color automático?
|
||||||
@@ -99,8 +99,7 @@ intro.text_distance_from_bottom 48 # Posicion del texto
|
|||||||
debug.color 00FFFF # Color para elementos de depuración
|
debug.color 00FFFF # Color para elementos de depuración
|
||||||
|
|
||||||
# --- RESOURCE ---
|
# --- RESOURCE ---
|
||||||
resource.color FFFFFF # Color de recurso 1
|
resource.color FFFFFF # Color de recursos
|
||||||
resource.color FFFFFF # Color de recurso 2
|
|
||||||
|
|
||||||
# --- TABE ---
|
# --- TABE ---
|
||||||
tabe.min_spawn_time 2.0f # Tiempo mínimo en minutos para que aparezca el Tabe
|
tabe.min_spawn_time 2.0f # Tiempo mínimo en minutos para que aparezca el Tabe
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
# Formato: PARAMETRO VALOR
|
# Formato: PARAMETRO VALOR
|
||||||
|
|
||||||
# --- GAME ---
|
# --- GAME ---
|
||||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
|
||||||
game.item_text_outline_color FFB8B8F0 # Color del outline del texto de los items (RGBA hex) - Rojo claro
|
game.item_text_outline_color FFB8B8F0 # Color del outline del texto de los items (RGBA hex) - Rojo claro
|
||||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||||
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
||||||
@@ -12,8 +11,6 @@ game.play_area.rect.w 320 # Ancho de la zona jugable
|
|||||||
game.play_area.rect.h 216 # Alto de la zona jugable
|
game.play_area.rect.h 216 # Alto de la zona jugable
|
||||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
|
||||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
|
||||||
|
|
||||||
# --- FADE ---
|
# --- FADE ---
|
||||||
fade.color 5C1F1F # Color hexadecimal para el efecto de fundido - Rojo oscuro
|
fade.color 5C1F1F # Color hexadecimal para el efecto de fundido - Rojo oscuro
|
||||||
@@ -39,24 +36,24 @@ scoreboard.text_color2 FFE6E6 # Color secundario del texto del marca
|
|||||||
scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (segundos)
|
scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (segundos)
|
||||||
|
|
||||||
# --- TITLE ---
|
# --- TITLE ---
|
||||||
title.press_start_position 180 # Posición Y del texto "Press Start"
|
title.press_start_position 180 # Posición Y del texto "Press Start"
|
||||||
title.title_duration 800 # Duración de la pantalla de título (frames)
|
title.title_duration 14 # Duración de la pantalla de título (segundos)
|
||||||
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
||||||
title.title_c_c_position 80 # Posición Y del título principal
|
title.title_c_c_position 80 # Posición Y del título principal
|
||||||
title.bg_color 8B4A3A # Color de fondo en la sección titulo - Marrón rojizo
|
title.bg_color 8B4A3A # Color de fondo en la sección titulo - Marrón rojizo
|
||||||
|
|
||||||
# --- BACKGROUND ---
|
# --- BACKGROUND ---
|
||||||
background.attenuate_color FF4A3A40 # Color de atenuación del fondo (RGBA hexadecimal) - Blanco rosado
|
background.attenuate_color FF4A3A40 # Color de atenuación del fondo (RGBA hexadecimal) - Blanco rosado
|
||||||
|
|
||||||
# --- BALLOONS ---
|
# --- BALLOONS --- (deltaTime en segundos: vel en pixels/s, grav en pixels/s²)
|
||||||
balloon.settings[0].vel 2.75f # Velocidad inicial del globo 1
|
balloon.settings[0].vel 165.0f # Velocidad inicial del globo 1 (pixels/s)
|
||||||
balloon.settings[0].grav 0.09f # Gravedad aplicada al globo 1
|
balloon.settings[0].grav 320.0f # Gravedad aplicada al globo 1 (pixels/s²)
|
||||||
balloon.settings[1].vel 3.70f # Velocidad inicial del globo 2
|
balloon.settings[1].vel 222.0f # Velocidad inicial del globo 2 (pixels/s)
|
||||||
balloon.settings[1].grav 0.10f # Gravedad aplicada al globo 2
|
balloon.settings[1].grav 360.0f # Gravedad aplicada al globo 2 (pixels/s²)
|
||||||
balloon.settings[2].vel 4.70f # Velocidad inicial del globo 3
|
balloon.settings[2].vel 282.0f # Velocidad inicial del globo 3 (pixels/s)
|
||||||
balloon.settings[2].grav 0.10f # Gravedad aplicada al globo 3
|
balloon.settings[2].grav 360.0f # Gravedad aplicada al globo 3 (pixels/s²)
|
||||||
balloon.settings[3].vel 5.45f # Velocidad inicial del globo 4
|
balloon.settings[3].vel 327.0f # Velocidad inicial del globo 4 (pixels/s)
|
||||||
balloon.settings[3].grav 0.10f # Gravedad aplicada al globo 4
|
balloon.settings[3].grav 360.0f # Gravedad aplicada al globo 4 (pixels/s²)
|
||||||
|
|
||||||
balloon.color[0] orange # Color de creación del globo normal
|
balloon.color[0] orange # Color de creación del globo normal
|
||||||
balloon.color[1] red # Color del globo normal
|
balloon.color[1] red # Color del globo normal
|
||||||
@@ -72,6 +72,7 @@
|
|||||||
"[NOTIFICATIONS] DISCONNECTED": "desconectat",
|
"[NOTIFICATIONS] DISCONNECTED": "desconectat",
|
||||||
|
|
||||||
"[RESOURCE] LOADING": "Carregant",
|
"[RESOURCE] LOADING": "Carregant",
|
||||||
|
"[RESOURCE] PRESS_TO_CONTINUE": "Prem una tecla per continuar",
|
||||||
|
|
||||||
"[SERVICE_MENU] TITLE": "Menu de servei",
|
"[SERVICE_MENU] TITLE": "Menu de servei",
|
||||||
"[SERVICE_MENU] RESET": "Reiniciar",
|
"[SERVICE_MENU] RESET": "Reiniciar",
|
||||||
@@ -82,9 +83,9 @@
|
|||||||
"[SERVICE_MENU] SHADER": "Shader",
|
"[SERVICE_MENU] SHADER": "Shader",
|
||||||
"[SERVICE_MENU] SHADER_DISABLED": "Desactivat",
|
"[SERVICE_MENU] SHADER_DISABLED": "Desactivat",
|
||||||
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
||||||
"[SERVICE_MENU] SUPERSAMPLING": "Supermostreig",
|
|
||||||
"[SERVICE_MENU] VSYNC": "Sincronisme vertical",
|
"[SERVICE_MENU] VSYNC": "Sincronisme vertical",
|
||||||
"[SERVICE_MENU] INTEGER_SCALE": "Escalat sencer",
|
"[SERVICE_MENU] INTEGER_SCALE": "Escalat sencer",
|
||||||
|
"[SERVICE_MENU] FILTER": "Filtre",
|
||||||
"[SERVICE_MENU] MAIN_VOLUME": "Volumen general",
|
"[SERVICE_MENU] MAIN_VOLUME": "Volumen general",
|
||||||
"[SERVICE_MENU] MUSIC_VOLUME": "Volumen de la musica",
|
"[SERVICE_MENU] MUSIC_VOLUME": "Volumen de la musica",
|
||||||
"[SERVICE_MENU] SFX_VOLUME": "Volumen dels sons",
|
"[SERVICE_MENU] SFX_VOLUME": "Volumen dels sons",
|
||||||
@@ -103,6 +104,10 @@
|
|||||||
"[SERVICE_MENU] EASY": "Facil",
|
"[SERVICE_MENU] EASY": "Facil",
|
||||||
"[SERVICE_MENU] NORMAL": "Normal",
|
"[SERVICE_MENU] NORMAL": "Normal",
|
||||||
"[SERVICE_MENU] HARD": "Dificil",
|
"[SERVICE_MENU] HARD": "Dificil",
|
||||||
|
"[SERVICE_MENU] GAME_PRESET": "Perfil",
|
||||||
|
"[SERVICE_MENU] PRESET_CLASSIC": "Classic",
|
||||||
|
"[SERVICE_MENU] PRESET_ARCADE": "Arcade",
|
||||||
|
"[SERVICE_MENU] PRESET_RED": "Roig",
|
||||||
"[SERVICE_MENU] NEED_RESTART_MESSAGE": "Reiniciar per aplicar canvis",
|
"[SERVICE_MENU] NEED_RESTART_MESSAGE": "Reiniciar per aplicar canvis",
|
||||||
"[SERVICE_MENU] ENABLE_SHUTDOWN": "Permetre apagar el sistema",
|
"[SERVICE_MENU] ENABLE_SHUTDOWN": "Permetre apagar el sistema",
|
||||||
"[SERVICE_MENU] CONTROLS": "Controls",
|
"[SERVICE_MENU] CONTROLS": "Controls",
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
"[NOTIFICATIONS] DISCONNECTED": "disconnected",
|
"[NOTIFICATIONS] DISCONNECTED": "disconnected",
|
||||||
|
|
||||||
"[RESOURCE] LOADING": "Loading",
|
"[RESOURCE] LOADING": "Loading",
|
||||||
|
"[RESOURCE] PRESS_TO_CONTINUE": "Press any key to continue",
|
||||||
|
|
||||||
"[SERVICE_MENU] TITLE": "Service Menu",
|
"[SERVICE_MENU] TITLE": "Service Menu",
|
||||||
"[SERVICE_MENU] RESET": "Reset",
|
"[SERVICE_MENU] RESET": "Reset",
|
||||||
@@ -81,9 +82,9 @@
|
|||||||
"[SERVICE_MENU] SHADER": "Shader",
|
"[SERVICE_MENU] SHADER": "Shader",
|
||||||
"[SERVICE_MENU] SHADER_DISABLED": "Disabled",
|
"[SERVICE_MENU] SHADER_DISABLED": "Disabled",
|
||||||
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
||||||
"[SERVICE_MENU] SUPERSAMPLING": "Supersampling",
|
|
||||||
"[SERVICE_MENU] VSYNC": "V-Sync",
|
"[SERVICE_MENU] VSYNC": "V-Sync",
|
||||||
"[SERVICE_MENU] INTEGER_SCALE": "Integer Scale",
|
"[SERVICE_MENU] INTEGER_SCALE": "Integer Scale",
|
||||||
|
"[SERVICE_MENU] FILTER": "Filter",
|
||||||
"[SERVICE_MENU] MAIN_VOLUME": "Main Volume",
|
"[SERVICE_MENU] MAIN_VOLUME": "Main Volume",
|
||||||
"[SERVICE_MENU] MUSIC_VOLUME": "Music Volume",
|
"[SERVICE_MENU] MUSIC_VOLUME": "Music Volume",
|
||||||
"[SERVICE_MENU] SFX_VOLUME": "Sound Volume",
|
"[SERVICE_MENU] SFX_VOLUME": "Sound Volume",
|
||||||
@@ -102,6 +103,10 @@
|
|||||||
"[SERVICE_MENU] EASY": "Easy",
|
"[SERVICE_MENU] EASY": "Easy",
|
||||||
"[SERVICE_MENU] NORMAL": "Normal",
|
"[SERVICE_MENU] NORMAL": "Normal",
|
||||||
"[SERVICE_MENU] HARD": "Hard",
|
"[SERVICE_MENU] HARD": "Hard",
|
||||||
|
"[SERVICE_MENU] GAME_PRESET": "Preset",
|
||||||
|
"[SERVICE_MENU] PRESET_CLASSIC": "Classic",
|
||||||
|
"[SERVICE_MENU] PRESET_ARCADE": "Arcade",
|
||||||
|
"[SERVICE_MENU] PRESET_RED": "Red",
|
||||||
"[SERVICE_MENU] NEED_RESTART_MESSAGE": "Restart to apply changes",
|
"[SERVICE_MENU] NEED_RESTART_MESSAGE": "Restart to apply changes",
|
||||||
"[SERVICE_MENU] ENABLE_SHUTDOWN": "Allow system shutdown",
|
"[SERVICE_MENU] ENABLE_SHUTDOWN": "Allow system shutdown",
|
||||||
"[SERVICE_MENU] CONTROLS": "Controls",
|
"[SERVICE_MENU] CONTROLS": "Controls",
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
"[NOTIFICATIONS] DISCONNECTED": "desconectado",
|
"[NOTIFICATIONS] DISCONNECTED": "desconectado",
|
||||||
|
|
||||||
"[RESOURCE] LOADING": "Cargando",
|
"[RESOURCE] LOADING": "Cargando",
|
||||||
|
"[RESOURCE] PRESS_TO_CONTINUE": "Pulsa una tecla para continuar",
|
||||||
|
|
||||||
"[SERVICE_MENU] TITLE": "Menu de servicio",
|
"[SERVICE_MENU] TITLE": "Menu de servicio",
|
||||||
"[SERVICE_MENU] RESET": "Reiniciar",
|
"[SERVICE_MENU] RESET": "Reiniciar",
|
||||||
@@ -81,9 +82,9 @@
|
|||||||
"[SERVICE_MENU] SHADER": "Shader",
|
"[SERVICE_MENU] SHADER": "Shader",
|
||||||
"[SERVICE_MENU] SHADER_DISABLED": "Desactivado",
|
"[SERVICE_MENU] SHADER_DISABLED": "Desactivado",
|
||||||
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
||||||
"[SERVICE_MENU] SUPERSAMPLING": "Supersampling",
|
|
||||||
"[SERVICE_MENU] VSYNC": "Sincronismo vertical",
|
"[SERVICE_MENU] VSYNC": "Sincronismo vertical",
|
||||||
"[SERVICE_MENU] INTEGER_SCALE": "Escalado proporcional",
|
"[SERVICE_MENU] INTEGER_SCALE": "Escalado proporcional",
|
||||||
|
"[SERVICE_MENU] FILTER": "Filtro",
|
||||||
"[SERVICE_MENU] MAIN_VOLUME": "Volumen general",
|
"[SERVICE_MENU] MAIN_VOLUME": "Volumen general",
|
||||||
"[SERVICE_MENU] MUSIC_VOLUME": "Volumen de la musica",
|
"[SERVICE_MENU] MUSIC_VOLUME": "Volumen de la musica",
|
||||||
"[SERVICE_MENU] SFX_VOLUME": "Volumen de los efectos",
|
"[SERVICE_MENU] SFX_VOLUME": "Volumen de los efectos",
|
||||||
@@ -102,6 +103,10 @@
|
|||||||
"[SERVICE_MENU] EASY": "Facil",
|
"[SERVICE_MENU] EASY": "Facil",
|
||||||
"[SERVICE_MENU] NORMAL": "Normal",
|
"[SERVICE_MENU] NORMAL": "Normal",
|
||||||
"[SERVICE_MENU] HARD": "Dificil",
|
"[SERVICE_MENU] HARD": "Dificil",
|
||||||
|
"[SERVICE_MENU] GAME_PRESET": "Perfil",
|
||||||
|
"[SERVICE_MENU] PRESET_CLASSIC": "Clasico",
|
||||||
|
"[SERVICE_MENU] PRESET_ARCADE": "Arcade",
|
||||||
|
"[SERVICE_MENU] PRESET_RED": "Rojo",
|
||||||
"[SERVICE_MENU] NEED_RESTART_MESSAGE": "Reiniciar para aplicar cambios",
|
"[SERVICE_MENU] NEED_RESTART_MESSAGE": "Reiniciar para aplicar cambios",
|
||||||
"[SERVICE_MENU] ENABLE_SHUTDOWN": "Permitir apagar el sistema",
|
"[SERVICE_MENU] ENABLE_SHUTDOWN": "Permitir apagar el sistema",
|
||||||
"[SERVICE_MENU] CONTROLS": "Controles",
|
"[SERVICE_MENU] CONTROLS": "Controles",
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
#version 450
|
|
||||||
layout(location = 0) in vec2 v_uv;
|
|
||||||
layout(location = 0) out vec4 out_color;
|
|
||||||
|
|
||||||
layout(set = 2, binding = 0) uniform sampler2D source;
|
|
||||||
|
|
||||||
layout(set = 3, binding = 0) uniform DownscaleUniforms {
|
|
||||||
int algorithm; // 0 = Lanczos2 (ventana 2, ±2 taps), 1 = Lanczos3 (ventana 3, ±3 taps)
|
|
||||||
float pad0;
|
|
||||||
float pad1;
|
|
||||||
float pad2;
|
|
||||||
} u;
|
|
||||||
|
|
||||||
// Kernel Lanczos normalizado: sinc(t) * sinc(t/a) para |t| < a, 0 fuera.
|
|
||||||
float lanczos(float t, float a) {
|
|
||||||
t = abs(t);
|
|
||||||
if (t < 0.0001) { return 1.0; }
|
|
||||||
if (t >= a) { return 0.0; }
|
|
||||||
const float PI = 3.14159265358979;
|
|
||||||
float pt = PI * t;
|
|
||||||
return (a * sin(pt) * sin(pt / a)) / (pt * pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 src_size = vec2(textureSize(source, 0));
|
|
||||||
// Posición en coordenadas de texel (centros de texel en N+0.5)
|
|
||||||
vec2 p = v_uv * src_size;
|
|
||||||
vec2 p_floor = floor(p);
|
|
||||||
|
|
||||||
float a = (u.algorithm == 0) ? 2.0 : 3.0;
|
|
||||||
int win = int(a);
|
|
||||||
|
|
||||||
vec4 color = vec4(0.0);
|
|
||||||
float weight_sum = 0.0;
|
|
||||||
|
|
||||||
for (int j = -win; j <= win; j++) {
|
|
||||||
for (int i = -win; i <= win; i++) {
|
|
||||||
// Centro del texel (i,j) relativo a p_floor
|
|
||||||
vec2 tap_center = p_floor + vec2(float(i), float(j)) + 0.5;
|
|
||||||
vec2 offset = tap_center - p;
|
|
||||||
float w = lanczos(offset.x, a) * lanczos(offset.y, a);
|
|
||||||
color += texture(source, tap_center / src_size) * w;
|
|
||||||
weight_sum += w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out_color = (weight_sum > 0.0) ? (color / weight_sum) : vec4(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
+47
-18
@@ -6,7 +6,9 @@
|
|||||||
// xxd -i postfx.frag.spv > ../../source/core/rendering/sdl3gpu/postfx_frag_spv.h
|
// xxd -i postfx.frag.spv > ../../source/core/rendering/sdl3gpu/postfx_frag_spv.h
|
||||||
//
|
//
|
||||||
// PostFXUniforms must match exactly the C++ struct in sdl3gpu_shader.hpp
|
// PostFXUniforms must match exactly the C++ struct in sdl3gpu_shader.hpp
|
||||||
// (8 floats, 32 bytes, std140/scalar layout).
|
// (16 floats = 4 × vec4 = 64 bytes, std140/scalar layout).
|
||||||
|
// IMPORTANT: Qualsevol canvi ací cal replicar-lo a mà a
|
||||||
|
// source/core/rendering/sdl3gpu/msl/postfx_frag.msl.h (no hi ha generador).
|
||||||
|
|
||||||
layout(location = 0) in vec2 v_uv;
|
layout(location = 0) in vec2 v_uv;
|
||||||
layout(location = 0) out vec4 out_color;
|
layout(location = 0) out vec4 out_color;
|
||||||
@@ -15,7 +17,7 @@ layout(set = 2, binding = 0) uniform sampler2D scene;
|
|||||||
|
|
||||||
layout(set = 3, binding = 0) uniform PostFXUniforms {
|
layout(set = 3, binding = 0) uniform PostFXUniforms {
|
||||||
float vignette_strength;
|
float vignette_strength;
|
||||||
float chroma_strength;
|
float chroma_min; // intensitat mínima de l'aberració cromàtica
|
||||||
float scanline_strength;
|
float scanline_strength;
|
||||||
float screen_height;
|
float screen_height;
|
||||||
float mask_strength;
|
float mask_strength;
|
||||||
@@ -24,10 +26,28 @@ layout(set = 3, binding = 0) uniform PostFXUniforms {
|
|||||||
float bleeding;
|
float bleeding;
|
||||||
float pixel_scale; // physical pixels per logical pixel (vh / tex_height_)
|
float pixel_scale; // physical pixels per logical pixel (vh / tex_height_)
|
||||||
float time; // seconds since SDL init
|
float time; // seconds since SDL init
|
||||||
float oversample; // supersampling factor (1.0 = off, 3.0 = 3×SS)
|
float flicker; // 0 = off, 1 = phosphor flicker ~50 Hz
|
||||||
float flicker; // 0 = off, 1 = phosphor flicker ~50 Hz — 48 bytes total (3 × 16)
|
float chroma_max; // intensitat màxima; si == chroma_min → chroma estàtic
|
||||||
|
// vec4 #3 — paràmetres de scanlines (exposats per preset YAML)
|
||||||
|
float scan_dark_ratio; // fracció de subfila fosca per fila lògica (1/3 ≈ 0.333)
|
||||||
|
float scan_dark_floor; // multiplicador de brillantor de la subfila fosca
|
||||||
|
float scan_edge_soft; // 0 = step dur; 1 = suavitzat d'1 píxel físic (estil crtpi)
|
||||||
|
float pad3; // padding per tancar a 64 bytes (4 × vec4)
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
|
// Mostreig bilinear horitzontal d'un canal RGB. Evita el "tic-tac" del sampler
|
||||||
|
// NEAREST quan l'offset de chroma és subpíxel: sense interpolar, l'offset
|
||||||
|
// arrodonia entre 1 i 2 píxels i el drift temporal feia un parpelleig discret.
|
||||||
|
float sampleBilinearX(vec2 uv_target, int channel) {
|
||||||
|
vec2 tex_size = vec2(textureSize(scene, 0));
|
||||||
|
float px = uv_target.x * tex_size.x - 0.5;
|
||||||
|
float p_floor = floor(px);
|
||||||
|
float f = px - p_floor;
|
||||||
|
vec4 c0 = texture(scene, vec2((p_floor + 0.5) / tex_size.x, uv_target.y));
|
||||||
|
vec4 c1 = texture(scene, vec2((p_floor + 1.5) / tex_size.x, uv_target.y));
|
||||||
|
return mix(c0[channel], c1[channel], f);
|
||||||
|
}
|
||||||
|
|
||||||
// YCbCr helpers for NTSC bleeding
|
// YCbCr helpers for NTSC bleeding
|
||||||
vec3 rgb_to_ycc(vec3 rgb) {
|
vec3 rgb_to_ycc(vec3 rgb) {
|
||||||
return vec3(
|
return vec3(
|
||||||
@@ -69,11 +89,11 @@ void main() {
|
|||||||
vec3 base = texture(scene, uv).rgb;
|
vec3 base = texture(scene, uv).rgb;
|
||||||
|
|
||||||
// Sangrado NTSC — difuminado horizontal de crominancia.
|
// Sangrado NTSC — difuminado horizontal de crominancia.
|
||||||
// step = 1 pixel lógico de juego en UV (corrige SS: textureSize.x = game_w * oversample).
|
// step = 1 pixel lógico de juego en UV.
|
||||||
vec3 colour;
|
vec3 colour;
|
||||||
if (u.bleeding > 0.0) {
|
if (u.bleeding > 0.0) {
|
||||||
float tw = float(textureSize(scene, 0).x);
|
float tw = float(textureSize(scene, 0).x);
|
||||||
float step = u.oversample / tw; // 1 pixel lógico en UV
|
float step = 1.0 / tw; // 1 pixel lógico en UV
|
||||||
vec3 ycc = rgb_to_ycc(base);
|
vec3 ycc = rgb_to_ycc(base);
|
||||||
vec3 ycc_l2 = rgb_to_ycc(texture(scene, uv - vec2(2.0*step, 0.0)).rgb);
|
vec3 ycc_l2 = rgb_to_ycc(texture(scene, uv - vec2(2.0*step, 0.0)).rgb);
|
||||||
vec3 ycc_l1 = rgb_to_ycc(texture(scene, uv - vec2(1.0*step, 0.0)).rgb);
|
vec3 ycc_l1 = rgb_to_ycc(texture(scene, uv - vec2(1.0*step, 0.0)).rgb);
|
||||||
@@ -85,10 +105,14 @@ void main() {
|
|||||||
colour = base;
|
colour = base;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aberración cromática (drift animado con time para efecto NTSC real)
|
// Aberración cromática — intensitat varia entre chroma_min i chroma_max amb
|
||||||
float ca = u.chroma_strength * 0.005 * (1.0 + 0.15 * sin(u.time * 7.3));
|
// una sinusoidal (si min == max, queda estàtica). Mostreig bilinear horitzontal
|
||||||
colour.r = texture(scene, uv + vec2(ca, 0.0)).r;
|
// per evitar el "tic-tac" del NEAREST sampler quan l'offset és subpíxel.
|
||||||
colour.b = texture(scene, uv - vec2(ca, 0.0)).b;
|
if (u.chroma_min > 0.0 || u.chroma_max > 0.0) {
|
||||||
|
float ca = mix(u.chroma_min, u.chroma_max, 0.5 + 0.5 * sin(u.time * 7.3)) * 0.005;
|
||||||
|
colour.r = sampleBilinearX(uv + vec2(ca, 0.0), 0);
|
||||||
|
colour.b = sampleBilinearX(uv - vec2(ca, 0.0), 2);
|
||||||
|
}
|
||||||
|
|
||||||
// Corrección gamma (linealizar antes de scanlines, codificar después)
|
// Corrección gamma (linealizar antes de scanlines, codificar después)
|
||||||
if (u.gamma_strength > 0.0) {
|
if (u.gamma_strength > 0.0) {
|
||||||
@@ -96,15 +120,20 @@ void main() {
|
|||||||
colour = mix(colour, lin, u.gamma_strength);
|
colour = mix(colour, lin, u.gamma_strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scanlines — 1 pixel físico oscuro por fila lógica.
|
// Scanlines — tècnica dels 3 subpíxels verticals per píxel lògic (aee/projecte_2026):
|
||||||
// Modelo sustractivo: las filas de scanline se oscurecen, las demás no cambian.
|
// franja fosca ocupant `scan_dark_ratio` al final de cada fila lògica. La transició es
|
||||||
// Esto evita el efecto de sobrebrillo en contenido con colores vivos.
|
// suavitza amb smoothstep d'ample ≈ 1 píxel físic (estil crtpi: filtratge analític
|
||||||
|
// continu), controlat per `scan_edge_soft`. A 0 és equivalent al step dur antic.
|
||||||
if (u.scanline_strength > 0.0) {
|
if (u.scanline_strength > 0.0) {
|
||||||
float ps = max(1.0, round(u.pixel_scale));
|
float ps = max(u.pixel_scale, 1.0);
|
||||||
float frac_in_row = fract(uv.y * u.screen_height);
|
float sub = fract(uv.y * u.screen_height); // [0,1) dins la fila lògica
|
||||||
float row_pos = floor(frac_in_row * ps);
|
float dark_center = 1.0 - u.scan_dark_ratio * 0.5; // centre de la franja fosca
|
||||||
float is_dark = step(ps - 1.0, row_pos);
|
float d = abs(sub - dark_center);
|
||||||
float scan = mix(1.0, 0.0, is_dark);
|
d = min(d, 1.0 - d); // wrap a la fila següent
|
||||||
|
float half_width = u.scan_dark_ratio * 0.5;
|
||||||
|
float softness = u.scan_edge_soft * 0.5 / ps; // mig píxel físic a cada costat
|
||||||
|
float band = 1.0 - smoothstep(half_width - softness, half_width + softness, d);
|
||||||
|
float scan = mix(1.0, u.scan_dark_floor, band);
|
||||||
colour *= mix(1.0, scan, u.scanline_strength);
|
colour *= mix(1.0, scan, u.scanline_strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#version 450
|
|
||||||
|
|
||||||
// Vulkan GLSL fragment shader — Nearest-neighbour upscale pass
|
|
||||||
// Used as the first render pass when supersampling is active.
|
|
||||||
// Compile: glslc upscale.frag -o upscale.frag.spv
|
|
||||||
// xxd -i upscale.frag.spv > ../../source/core/rendering/sdl3gpu/upscale_frag_spv.h
|
|
||||||
|
|
||||||
layout(location = 0) in vec2 v_uv;
|
|
||||||
layout(location = 0) out vec4 out_color;
|
|
||||||
|
|
||||||
layout(set = 2, binding = 0) uniform sampler2D scene;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
out_color = texture(scene, v_uv);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,642 @@
|
|||||||
|
# Arquitectura de **Coffee Crisis Arcade Edition**
|
||||||
|
|
||||||
|
> Guía de orientación para un desarrollador nuevo en el proyecto.
|
||||||
|
>
|
||||||
|
> Cada afirmación está anclada a código real: se cita el fichero (y, cuando
|
||||||
|
> ayuda, la función o el número de línea) que la respalda. Donde no he
|
||||||
|
> encontrado algo, lo digo explícitamente en lugar de inventarlo.
|
||||||
|
>
|
||||||
|
> **Coffee Crisis Arcade Edition** es un *shooter* arcade cooperativo de 2
|
||||||
|
> jugadores escrito en **C++20 sobre SDL3**: los jugadores defienden el café
|
||||||
|
> de globos gigantes. Apunta a Windows, Linux, macOS (Intel/Apple Silicon),
|
||||||
|
> Raspberry Pi, Anbernic y web (Emscripten). Los comentarios del código están
|
||||||
|
> en español/valenciano; este documento está en castellano.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Índice
|
||||||
|
|
||||||
|
1. [Visión general](#1-visión-general)
|
||||||
|
2. [Punto de entrada y bucle principal](#2-punto-de-entrada-y-bucle-principal)
|
||||||
|
3. [Secciones y flujo de la aplicación](#3-secciones-y-flujo-de-la-aplicación)
|
||||||
|
4. [Renderizado: de la lógica al píxel](#4-renderizado-de-la-lógica-al-píxel)
|
||||||
|
5. [Entrada](#5-entrada)
|
||||||
|
6. [Lógica del juego: la clase `Game`](#6-lógica-del-juego-la-clase-game)
|
||||||
|
7. [Entidades y managers de gameplay](#7-entidades-y-managers-de-gameplay)
|
||||||
|
8. [Modo demo y attract mode](#8-modo-demo-y-attract-mode)
|
||||||
|
9. [Recursos](#9-recursos)
|
||||||
|
10. [Audio](#10-audio)
|
||||||
|
11. [Configuración, parámetros y constantes](#11-configuración-parámetros-y-constantes)
|
||||||
|
12. [Localización](#12-localización)
|
||||||
|
13. [Convenciones y patrones recurrentes](#13-convenciones-y-patrones-recurrentes)
|
||||||
|
14. [Guía de navegación: "si quieres tocar X, mira Y"](#14-guía-de-navegación-si-quieres-tocar-x-mira-y)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Visión general
|
||||||
|
|
||||||
|
El árbol `source/` separa **motor** y **juego**:
|
||||||
|
|
||||||
|
- **`source/core/`** — motor genérico: `system` (arranque, secciones, demo,
|
||||||
|
eventos globales), `rendering` (+ `sdl3gpu`, `sprite`), `input`, `resources`,
|
||||||
|
`audio`, `locale`.
|
||||||
|
- **`source/game/`** — el juego concreto: `scenes` (las secciones), `gameplay`
|
||||||
|
(managers), `entities` (jugador, globos, balas, ítems…), `ui`, y `options`.
|
||||||
|
- **`source/utils/`** — `color`, `param`, `utils`, `defines`.
|
||||||
|
- **`source/external/`** — vendorizado: `nlohmann/json`, `fkyaml`, `stb_image`,
|
||||||
|
`stb_vorbis`.
|
||||||
|
|
||||||
|
Los `#include` son **absolutos respecto a `source/`** (p.ej.
|
||||||
|
`#include "core/audio/audio.hpp"`); CMake añade un único `-I.../source`
|
||||||
|
(ver `CLAUDE.md`). ~150 ficheros C++, ~32.000 líneas.
|
||||||
|
|
||||||
|
**Cuatro ideas-fuerza que conviene interiorizar:**
|
||||||
|
|
||||||
|
1. **El flujo de la aplicación se conduce con una variable global**
|
||||||
|
(`Section::name`), no con objetos de transición. El `Director` reacciona a
|
||||||
|
sus cambios (§3).
|
||||||
|
2. **El render usa texturas GPU vía `SDL_Renderer`** dibujadas sobre una
|
||||||
|
*render-target texture*, con post-procesado opcional vía un backend SDL3
|
||||||
|
GPU. No es un blitter de software (§4).
|
||||||
|
3. **El gameplay se organiza con managers/pools** (`BalloonManager`,
|
||||||
|
`BulletManager`, `StageManager`) coordinados por una clase `Game` muy grande
|
||||||
|
(§6, §7).
|
||||||
|
4. **Sí hay modo demo** (*attract mode*): es **reproducción de input grabado**,
|
||||||
|
no IA (§8).
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
SDL[SDL3 callbacks · main.cpp] --> DIR[Director]
|
||||||
|
DIR -->|lee Section::name| ST{handleSectionTransition}
|
||||||
|
ST --> SEC["Section activa (Logo/Intro/Title/Game/…)"]
|
||||||
|
DIR --> GE[GlobalEvents] --> INP[Input] & SVC[ServiceMenu]
|
||||||
|
SEC --> GAME[Game]
|
||||||
|
GAME --> BM[BalloonManager] & BLM[BulletManager] & STG[StageManager]
|
||||||
|
GAME --> PL[Players] -->|Input::Action| INP
|
||||||
|
GAME --> DEMO["Demo (playback de input grabado)"] -.->|setInput| PL
|
||||||
|
GAME -->|SDL_RenderTexture| CV["game_canvas_ (render target)"]
|
||||||
|
CV -->|RenderReadPixels → uploadPixels| SB[ShaderBackend SDL3 GPU] --> WIN[Ventana]
|
||||||
|
RES["Resource / Asset"] -.-> GAME & SEC
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Punto de entrada y bucle principal
|
||||||
|
|
||||||
|
### 2.1. SDL conduce el bucle (callbacks)
|
||||||
|
|
||||||
|
`source/main.cpp` define `SDL_MAIN_USE_CALLBACKS`: no hay `while` propio. SDL
|
||||||
|
llama a cuatro funciones, todas delegando en el `Director`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
SDL_AppInit → *appstate = new Director(argc, argv); // main.cpp:15
|
||||||
|
SDL_AppIterate→ Director::iterate(); // un frame
|
||||||
|
SDL_AppEvent → Director::handleEvent(event); // un evento
|
||||||
|
SDL_AppQuit → delete Director;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2. El `Director`
|
||||||
|
|
||||||
|
`source/core/system/director.{hpp,cpp}` es el orquestador. Mantiene **un
|
||||||
|
`unique_ptr` por cada sección** (`preload_`, `logo_`, `intro_`, `title_`,
|
||||||
|
`game_`, …) de los que **solo uno está vivo** a la vez (`director.hpp:60`).
|
||||||
|
|
||||||
|
**Constructor (`director.cpp:82`)**: fija la semilla aleatoria, crea la carpeta
|
||||||
|
de sistema (`jailgames/coffee_crisis_arcade_edition`), decide la sección
|
||||||
|
inicial según el build (`RECORDING` → GAME; `_DEBUG` → lee `debug.yaml`; Release
|
||||||
|
→ LOGO) y llama a `init()`.
|
||||||
|
|
||||||
|
**`init()` (`director.cpp:131`)** inicializa en orden: `Asset` (índice de
|
||||||
|
ficheros), sistema de recursos (`resources.pack`, con/ sin *fallback* a disco
|
||||||
|
según build), `Input`, `Options` (config.yaml, controllers.json, presets de
|
||||||
|
shaders), parámetros y *scores*, `Lang`, `Screen`, `Audio` y `Resource`.
|
||||||
|
|
||||||
|
### 2.3. Arranque NO bloqueante (PRELOAD incremental)
|
||||||
|
|
||||||
|
Un detalle importante: si el modo de carga es `PRELOAD`, **no se cargan todos
|
||||||
|
los recursos de golpe**. `init()` redirige el arranque a la sección `PRELOAD`
|
||||||
|
guardando el destino real en `Section::post_preload` (`director.cpp:191`):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Section::post_preload = Section::name; // destino real
|
||||||
|
Section::name = Section::Name::PRELOAD; // mientras tanto, barra de progreso
|
||||||
|
Resource::get()->beginLoad();
|
||||||
|
```
|
||||||
|
|
||||||
|
Cada frame, `Director::iterate()` (`director.cpp:489`) llama a
|
||||||
|
`Resource::loadStep(50 /*ms*/)`: carga recursos hasta agotar un presupuesto de
|
||||||
|
50 ms por frame, manteniendo la ventana y el bucle vivos. Cuando termina,
|
||||||
|
`finishBoot()` inicializa lo que depende de los recursos (`ServiceMenu`,
|
||||||
|
`Notifier`, singletons de `Screen`) y salta a `post_preload`.
|
||||||
|
|
||||||
|
### 2.4. Orden del frame y gestión del tiempo
|
||||||
|
|
||||||
|
`Director::iterate()` (`director.cpp:489`):
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant SDL
|
||||||
|
participant Dir as Director::iterate
|
||||||
|
participant Sec as Section activa
|
||||||
|
SDL->>Dir: SDL_AppIterate
|
||||||
|
alt boot_loading_
|
||||||
|
Dir->>Dir: Resource::loadStep(50ms) → finishBoot() al terminar
|
||||||
|
end
|
||||||
|
Dir->>Dir: handleSectionTransition() (destruye/crea sección)
|
||||||
|
Dir->>Sec: iterate() (la sección hace su propio update+render)
|
||||||
|
```
|
||||||
|
|
||||||
|
El tiempo es **time-based**: cada sección calcula su propio `delta_time`. En
|
||||||
|
`Game` es `calculateDeltaTime()` (`game.hpp:210`), usado en todos los `update`.
|
||||||
|
Los eventos llegan por separado vía `Director::handleEvent` →
|
||||||
|
`GlobalEvents::handle` + reenvío a la sección activa (`director.cpp:539`).
|
||||||
|
|
||||||
|
### 2.5. Reinicio en caliente
|
||||||
|
|
||||||
|
Igual que su proyecto hermano, soporta reinicio real vía `execv`
|
||||||
|
(`Director::relaunch()`, `director.cpp:254`): la sección `RESET` (p.ej. tras
|
||||||
|
F10 o cambio de idioma) reemplaza el proceso por sí mismo; si no se puede
|
||||||
|
(Emscripten, `argv` inválido), cae a un `reset()` interno que recarga recursos y
|
||||||
|
vuelve a `LOGO`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Secciones y flujo de la aplicación
|
||||||
|
|
||||||
|
### 3.1. Variables globales de estado
|
||||||
|
|
||||||
|
`source/core/system/section.hpp` define el estado del flujo como **variables
|
||||||
|
globales `inline`** en el namespace `Section`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline Name name = Name::RESET; // sección a la que ir
|
||||||
|
inline Name post_preload = Name::LOGO; // destino tras PRELOAD
|
||||||
|
inline Options options = Options::NONE; // 1P/2P/BOTH, timeouts, etc.
|
||||||
|
inline AttractMode attract_mode = AttractMode::TITLE_TO_DEMO;
|
||||||
|
```
|
||||||
|
|
||||||
|
`Name` enumera: `RESET, PRELOAD, LOGO, INTRO, TITLE, GAME, HI_SCORE_TABLE,
|
||||||
|
GAME_DEMO, INSTRUCTIONS, CREDITS, QUIT`. Cualquier parte del código cambia el
|
||||||
|
flujo simplemente asignando `Section::name = ...`.
|
||||||
|
|
||||||
|
### 3.2. La transición de secciones
|
||||||
|
|
||||||
|
`Director::handleSectionTransition()` (`director.cpp:390`) se ejecuta cada
|
||||||
|
frame:
|
||||||
|
|
||||||
|
- Si `Section::name == RESET`: intenta `relaunch()`; si vuelve, hace el reset
|
||||||
|
interno.
|
||||||
|
- Si `Section::name == last_built_section_name_`: no hace nada (ya está viva).
|
||||||
|
- Si cambió: `resetActiveSection()` (libera todos los `unique_ptr`) y un
|
||||||
|
`switch` construye la nueva sección. Para `GAME` traduce `Section::options`
|
||||||
|
a `Player::Id` (1P/2P/BOTH); para `GAME_DEMO` construye `Game(..., DEMO_ON)`
|
||||||
|
con jugador aleatorio (`director.cpp:448`).
|
||||||
|
|
||||||
|
Cada sección (`source/game/scenes/`) es autónoma y expone `iterate()` +
|
||||||
|
`handleEvent()`. `Director::iterate` despacha al puntero vivo con una cadena de
|
||||||
|
`if/else if` (`director.cpp:517`).
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
RESET --> PRELOAD --> LOGO --> INTRO --> TITLE
|
||||||
|
TITLE -->|jugar| GAME --> HI_SCORE_TABLE --> TITLE
|
||||||
|
TITLE -->|timeout / attract| GAME_DEMO --> TITLE
|
||||||
|
TITLE -->|attract alterno| LOGO
|
||||||
|
TITLE --> INSTRUCTIONS & CREDITS
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3. Attract mode
|
||||||
|
|
||||||
|
El *attract mode* alterna entre mostrar la demo y volver al logo. En
|
||||||
|
`title.cpp:51` el Title, al construirse, mira `Section::attract_mode` y fija su
|
||||||
|
`next_section_` (a `GAME_DEMO` o `LOGO`), **invirtiendo el modo** para la
|
||||||
|
próxima vez. Cuando el Title agota su *timeout* sin input, salta a esa sección
|
||||||
|
(ver §8).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Renderizado: de la lógica al píxel
|
||||||
|
|
||||||
|
A diferencia de un blitter de software, aquí **los sprites son texturas GPU**
|
||||||
|
compuestas por `SDL_Renderer`, y el post-procesado se hace en un backend SDL3
|
||||||
|
GPU.
|
||||||
|
|
||||||
|
### 4.1. `Texture` y la jerarquía de sprites
|
||||||
|
|
||||||
|
- `source/core/rendering/texture.hpp` — `Texture` envuelve un `SDL_Texture*`,
|
||||||
|
con `loadFromFile`, `createBlank`, `setAsRenderTarget` y un `render(x, y,
|
||||||
|
clip, zoom, angle, …)`. Es la unidad de dibujo.
|
||||||
|
- `source/core/rendering/sprite/` — jerarquía sobre `Sprite`
|
||||||
|
(`sprite.hpp:13`), que guarda **varias texturas** (`textures_`), un
|
||||||
|
`sprite_clip_` y posición/zoom:
|
||||||
|
- `AnimatedSprite` — animación por fotogramas (clip que avanza).
|
||||||
|
- `MovingSprite` — con velocidad.
|
||||||
|
- `PathSprite` — sigue rutas precalculadas (`Path`).
|
||||||
|
- `SmartSprite` — sprite con lógica propia (p.ej. el café que salta al ser
|
||||||
|
golpeado).
|
||||||
|
- `CardSprite` — variante para "cartas"/paneles.
|
||||||
|
|
||||||
|
El `Player`, por ejemplo, compone un `AnimatedSprite player_sprite_` y un
|
||||||
|
`power_sprite_` para el aura (`player.hpp:250`).
|
||||||
|
|
||||||
|
### 4.2. Dos render-targets
|
||||||
|
|
||||||
|
Hay **dos texturas de destino** encadenadas:
|
||||||
|
|
||||||
|
1. **`Game::canvas_`** — textura de la *zona de juego*. `Game::fillCanvas()`
|
||||||
|
(`game.cpp`) fija el render-target a `canvas_` y dibuja, **en este orden**:
|
||||||
|
`background → smart_sprites → items → balloons → tabe → players → bullets →
|
||||||
|
path_sprites`. Ese orden es el z-order del playfield.
|
||||||
|
|
||||||
|
2. **`Screen::game_canvas_`** — textura de *pantalla completa* (ARGB8888 a la
|
||||||
|
resolución de juego; `screen.cpp:92`, `SDL_TEXTUREACCESS_TARGET`).
|
||||||
|
`Game::render()` hace `screen_->start()` (que pone el target en
|
||||||
|
`game_canvas_`), copia `canvas_` sobre él, y encima dibuja **scoreboard** y
|
||||||
|
los **fades** de entrada/salida; finalmente `screen_->render()`.
|
||||||
|
|
||||||
|
### 4.3. Post-procesado y presentación
|
||||||
|
|
||||||
|
`Screen::renderPresent()` (`screen.cpp:156`) decide cómo llega a la ventana:
|
||||||
|
|
||||||
|
- **Con backend GPU acelerado**: lee los píxeles de `game_canvas_` con
|
||||||
|
`SDL_RenderReadPixels` a un `pixel_buffer_` CPU, los sube al backend
|
||||||
|
(`shader_backend_->uploadPixels(...)`) y este los renderiza con el shader
|
||||||
|
activo (`shader_backend_->render()`).
|
||||||
|
- **Sin backend** (fallback): vuelca `game_canvas_` directamente a la ventana
|
||||||
|
con `SDL_RenderTexture`.
|
||||||
|
|
||||||
|
El backend vive en `source/core/rendering/sdl3gpu/` (SDL3 GPU API; shaders
|
||||||
|
SPIR-V compilados offline desde GLSL en `data/shaders/`, embebidos en cabeceras
|
||||||
|
`spv/`/`msl/`). Hay dos shaders seleccionables, **PostFX** y **CrtPi**, con
|
||||||
|
presets en `postfx.yaml`/`crtpi.yaml` (`screen.cpp:382`). El build `NO_SHADERS`
|
||||||
|
(Anbernic) desactiva todo el pipeline de shaders.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
OBJ["background, balloons, players, bullets…"] -->|SDL_RenderTexture| CANVAS["Game::canvas_ (zona de juego)"]
|
||||||
|
CANVAS -->|copiar| GC["Screen::game_canvas_ (pantalla)"]
|
||||||
|
SB2[scoreboard] --> GC
|
||||||
|
FADE[fades de entrada/salida] --> GC
|
||||||
|
GC -->|RenderReadPixels → uploadPixels| SHADER["ShaderBackend (PostFX/CrtPi)"]
|
||||||
|
SHADER --> WIN[Ventana]
|
||||||
|
GC -.fallback sin GPU.-> WIN
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4. Efectos de pantalla
|
||||||
|
|
||||||
|
`Screen` integra efectos globales sobre la presentación: **shake**
|
||||||
|
(`ShakeEffect`, desplaza el rect), **flash** (`FlashEffect`, tinte temporal) y
|
||||||
|
**attenuate** (atenuación) — todos definidos como structs internos en
|
||||||
|
`screen.hpp:108`–`205`. Las transiciones entre estados usan
|
||||||
|
`source/core/rendering/fade.*` (cuadrícula de cuadros).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Entrada
|
||||||
|
|
||||||
|
### 5.1. `Input` singleton
|
||||||
|
|
||||||
|
`source/core/input/input.hpp`. Centraliza teclado y mandos bajo un enum de
|
||||||
|
**acciones** (`Input::Action`, alias de `InputAction`). El mapeo por defecto
|
||||||
|
vive en structs:
|
||||||
|
|
||||||
|
- **`Keyboard`** (`input.hpp:54`): flechas = mover; **Q/W/E** = disparar
|
||||||
|
izquierda/centro/derecha; Enter = START; F12 = SERVICE; P = PAUSE; ESC = EXIT;
|
||||||
|
**F1–F11** = ventana/vídeo/audio/idioma/reset/info.
|
||||||
|
- **`Gamepad`** (`input.hpp:99`): cruceta = mover; WEST/NORTH/EAST = disparar;
|
||||||
|
START/ BACK = start/service. Cada mando es un `shared_ptr<Gamepad>` con su
|
||||||
|
propio `bindings`, nombre y *path*.
|
||||||
|
|
||||||
|
La consulta principal es `checkAction(action, repeat, check_keyboard, gamepad)`
|
||||||
|
(`input.hpp:168`). Hay además detección de ejes y triggers como botones, y
|
||||||
|
gestión de configuraciones de mando persistidas (`gamepad_config_manager`,
|
||||||
|
`controllers.json`).
|
||||||
|
|
||||||
|
### 5.2. Eventos globales y hotkeys
|
||||||
|
|
||||||
|
- `source/core/system/global_events.cpp` — `GlobalEvents::handle(event)` trata
|
||||||
|
lo común a cualquier sección: `SDL_EVENT_QUIT`, *resize*, render target reset,
|
||||||
|
hot-plug de mandos (con notificación tras `markStartupComplete`), el toggle
|
||||||
|
del menú de servicio y el ratón.
|
||||||
|
- `source/core/input/global_inputs.cpp` — hotkeys de sistema, despachadas con
|
||||||
|
un mapa acción→lambda (`global_inputs.cpp:187`): fullscreen, zoom ±, audio,
|
||||||
|
autofire, idioma (CHANGE_LANG → `Section::RESET`, reinicia), VSync, integer
|
||||||
|
scale, info; más PostFX/shader/preset. **F10/RESET** pone `Section::name =
|
||||||
|
RESET` (reinicio) y **ESC/EXIT** pone `QUIT`.
|
||||||
|
|
||||||
|
### 5.3. Cómo llega la entrada a un jugador
|
||||||
|
|
||||||
|
Dentro de `Game`, `checkInput()` → `handlePlayersInput()` →
|
||||||
|
`handleNormalPlayerInput(player)` consulta `Input` y traduce a
|
||||||
|
`player->setInput(Input::Action)` y disparos (`handleFireInput`). El `Player`
|
||||||
|
sabe si usa teclado o un mando concreto (`uses_keyboard_`, `gamepad_`;
|
||||||
|
`player.hpp:217`). En modo demo, esta misma vía se alimenta de datos grabados
|
||||||
|
(§8).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Lógica del juego: la clase `Game`
|
||||||
|
|
||||||
|
`source/game/scenes/game.{hpp,cpp}` es la sección de gameplay y la clase más
|
||||||
|
grande del proyecto. Coordina jugadores, globos, balas, ítems, fases,
|
||||||
|
puntuación y efectos.
|
||||||
|
|
||||||
|
### 6.1. FSM de la partida
|
||||||
|
|
||||||
|
`Game::State` (`game.hpp:75`): `FADE_IN → ENTERING_PLAYER →
|
||||||
|
SHOWING_GET_READY_MESSAGE → PLAYING → COMPLETED / GAME_OVER`. `checkState()`
|
||||||
|
(`game.cpp`) detecta fin de juego (`stage_manager_->isGameCompleted()`) o game
|
||||||
|
over (`allPlayersAreGameOver()`); `setState()` hace la transición.
|
||||||
|
|
||||||
|
### 6.2. El frame de `Game`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void Game::iterate() { // game.cpp
|
||||||
|
const float DELTA_TIME = calculateDeltaTime();
|
||||||
|
checkInput();
|
||||||
|
update(DELTA_TIME);
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
void Game::update(float dt) {
|
||||||
|
screen_->update(dt);
|
||||||
|
Audio::update();
|
||||||
|
updateDemo(dt); // no-op si no es demo
|
||||||
|
updateGameStates(dt); // dispatch por State
|
||||||
|
fillCanvas(); // dibuja la zona de juego en canvas_
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`updateGameStates` despacha a un `updateGameState<Estado>` por cada valor de la
|
||||||
|
FSM (`game.hpp:218`).
|
||||||
|
|
||||||
|
### 6.3. Sistemas que orquesta
|
||||||
|
|
||||||
|
`Game` posee (vía `unique_ptr`) los managers y objetos del nivel
|
||||||
|
(`game.hpp:136`):
|
||||||
|
|
||||||
|
- **`StageManager`** — progresión por "poder": cada fase necesita
|
||||||
|
`power_to_complete`; el juego se completa al acumular el poder total. También
|
||||||
|
define umbrales de **amenaza** (`menace`) por fase. Implementa `IStageInfo`
|
||||||
|
(`stage.hpp:51`), interfaz mínima que se inyecta a jugador y globos.
|
||||||
|
- **`BalloonManager`** — despliega formaciones (`deployRandomFormation`),
|
||||||
|
globos hijos al explotar uno, *power balls*, ajusta velocidad
|
||||||
|
(`Balloon::GAME_TEMPO`) y calcula la amenaza en pantalla (§7).
|
||||||
|
- **`BulletManager`** — pool de balas; las colisiones se resuelven con
|
||||||
|
**callbacks** que registra `Game` (`setBalloonCollisionCallback`,
|
||||||
|
`setTabeCollisionCallback`, `setOutOfBoundsCallback`; `bullet_manager.hpp:49`),
|
||||||
|
manteniendo la lógica de juego dentro de `Game`.
|
||||||
|
- **`Background`**, **`Fade` ×2**, **`Tabe`** (enemigo especial volador),
|
||||||
|
**`Scoreboard`**, **`PauseManager`**.
|
||||||
|
- Listas de `Item` (power-ups y puntos), `SmartSprite` y `PathSprite`.
|
||||||
|
|
||||||
|
### 6.4. Mecánicas destacadas
|
||||||
|
|
||||||
|
- **Ítems / power-ups** (`game.hpp:268`): café (toque extra),
|
||||||
|
máquina de café (power-up), *power ball*, reloj (= **detener el tiempo**,
|
||||||
|
`enableTimeStopItem`), e ítems de puntos. La probabilidad de soltar ítem la
|
||||||
|
decide `dropItem()` con *odds* configurables (`Helper`, `game.hpp:100`).
|
||||||
|
- **Sistema de amenaza** (`updateMenace`/`setMenace`): si la amenaza cae por
|
||||||
|
debajo de un umbral, se generan más globos.
|
||||||
|
- **Multijugador**: `players_` es un `vector<shared_ptr<Player>>` (1 o 2). Un
|
||||||
|
`players_draw_list_` separado mantiene el z-order de dibujo
|
||||||
|
(`buildPlayerDrawList`, `sendPlayerToBack`/`bringPlayerToFront`;
|
||||||
|
`game.hpp:338`).
|
||||||
|
- **Récords**: al perder con buena puntuación, el jugador entra en
|
||||||
|
`ENTERING_NAME` (`enter_name.*`, `manage_hiscore_table.*`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Entidades y managers de gameplay
|
||||||
|
|
||||||
|
`source/game/entities/`:
|
||||||
|
|
||||||
|
- **`Player`** (`player.hpp`) — la entidad más compleja. Hereda de
|
||||||
|
`AnimatedSprite`. Tiene **tres ejes de estado** independientes:
|
||||||
|
`walking_state_`, `firing_state_` y `playing_state_` (`player.hpp:266`). El
|
||||||
|
disparo usa un **sistema de dos líneas**: una funcional (cooldown, `canFire`)
|
||||||
|
y otra visual (animaciones `NORMAL→AIMING→RECOILING→THREAT_POSE`,
|
||||||
|
`player.hpp:296`). Soporta power-up, invulnerabilidad con parpadeo, *continue*
|
||||||
|
y entrada de nombre. Puede controlarse por teclado o por un `Gamepad`
|
||||||
|
concreto.
|
||||||
|
- **`Balloon`** (`balloon.hpp`) — el enemigo básico; al explotar puede crear
|
||||||
|
globos hijos. `Balloon::GAME_TEMPO` define velocidades por progreso.
|
||||||
|
- **`Bullet`** (`bullet.hpp`) — proyectil con tipo (UP/LEFT/RIGHT) y color
|
||||||
|
(según power-up del jugador).
|
||||||
|
- **`Item`** — power-ups y objetos de puntos que caen.
|
||||||
|
- **`Explosions`** — efectos de explosión (lo posee `BalloonManager`).
|
||||||
|
- **`Tabe`** — enemigo/objeto especial volador con su propia lógica de impacto.
|
||||||
|
|
||||||
|
`source/game/gameplay/` contiene los **managers y sistemas** (no entidades en
|
||||||
|
sí): `BalloonManager`, `BulletManager`, `StageManager`, `Difficulty`,
|
||||||
|
`Scoreboard`, `balloon_formations` (lee `formations.txt`), `cooldown`,
|
||||||
|
`enter_name`, `manage_hiscore_table`, `game_logo`.
|
||||||
|
|
||||||
|
El patrón general aquí **no es un `EntityManager` polimórfico único** (como en
|
||||||
|
el proyecto hermano), sino **managers especializados por tipo** + listas
|
||||||
|
homogéneas en `Game`, con **callbacks** para cruzar responsabilidades sin
|
||||||
|
acoplar (caso de `BulletManager`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Modo demo y attract mode
|
||||||
|
|
||||||
|
> **A diferencia de muchos juegos, aquí el modo demo SÍ existe — pero NO es
|
||||||
|
> IA.** Es **reproducción de input pregrabado**.
|
||||||
|
|
||||||
|
### 8.1. Formato de los datos
|
||||||
|
|
||||||
|
`source/core/system/demo.hpp`: cada fotograma de demo es un `DemoKeys` con seis
|
||||||
|
banderas (`left`, `right`, `no_input`, `fire`, `fire_left`, `fire_right`). Una
|
||||||
|
demo es un `vector<DemoKeys>` de `TOTAL_DEMO_DATA = 2000` fotogramas. Hay tres
|
||||||
|
ficheros: `data/demo/demo{1,2,3}.bin`, leídos por `loadDemoDataFromFile`
|
||||||
|
(`demo.cpp:11`).
|
||||||
|
|
||||||
|
### 8.2. Reproducción
|
||||||
|
|
||||||
|
Cuando `Game` se construye con `DEMO_ON` (sección `GAME_DEMO`), `initDemo()`
|
||||||
|
(`game.cpp`) carga todas las demos del `Asset` y **asigna una a cada jugador de
|
||||||
|
forma aleatoria** (`shuffle`), elige una fase de inicio al azar, da cafés
|
||||||
|
aleatorios, pone los marcadores en modo `DEMO` y silencia los globos. Luego cada
|
||||||
|
frame, `demoHandlePlayerInput()` lee el fotograma actual y lo inyecta por la
|
||||||
|
**misma vía de input que un humano**:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// game.cpp — demoHandlePlayerInput
|
||||||
|
const auto& demo_data = demo_data_vec.at(demo_.index % demo_data_vec.size());
|
||||||
|
if (demo_data.left == 1) player->setInput(Input::Action::LEFT);
|
||||||
|
else if (demo_data.right == 1) player->setInput(Input::Action::RIGHT);
|
||||||
|
...
|
||||||
|
if (demo_data.fire == 1) handleFireInput(player, Bullet::Type::UP);
|
||||||
|
```
|
||||||
|
|
||||||
|
No hay toma de decisiones: el jugador "demo" repite exactamente las pulsaciones
|
||||||
|
grabadas. `demoHandlePassInput()` permite **salir** con cualquier botón,
|
||||||
|
volviendo a `TITLE` y dejando armado el siguiente attract (`TITLE_TO_DEMO`).
|
||||||
|
|
||||||
|
### 8.3. Attract mode
|
||||||
|
|
||||||
|
El Title alterna `TITLE_TO_DEMO` ↔ `TITLE_TO_LOGO` (`title.cpp:51`): tras su
|
||||||
|
*timeout*, una vez lanza la demo y la siguiente vuelve al logo, en bucle de
|
||||||
|
atracción típico de recreativa.
|
||||||
|
|
||||||
|
### 8.4. Grabación y autoplay
|
||||||
|
|
||||||
|
- **`#ifdef RECORDING`** (`demo.cpp:43`, `game.hpp:349`): build especial que
|
||||||
|
arranca directamente en GAME y **graba** las pulsaciones a un `.bin` con
|
||||||
|
`saveDemoFile`. Así se generan las demos.
|
||||||
|
- **`autoplay`** (debug): en `_DEBUG`, `debug_config.autoplay` permite alimentar
|
||||||
|
datos de demo a los jugadores en una partida normal (`game.hpp:354`,
|
||||||
|
`initDemo`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Recursos
|
||||||
|
|
||||||
|
### 9.1. `Resource` (singleton)
|
||||||
|
|
||||||
|
`source/core/resources/resource.hpp`. Cachea por nombre texturas, música,
|
||||||
|
sonidos, ficheros de texto/fuentes, animaciones y **datos de demo**
|
||||||
|
(`getDemoData`). Dos modos (`LoadingMode`):
|
||||||
|
|
||||||
|
- **`PRELOAD`** — carga incremental al arranque con `beginLoad()` +
|
||||||
|
`loadStep(budget_ms)` + `renderProgress()` (la sección Preload pinta la
|
||||||
|
barra). Es el modo por defecto.
|
||||||
|
- **`LAZY_LOAD`** — carga bajo demanda (seleccionable vía `debug.yaml`).
|
||||||
|
|
||||||
|
### 9.2. `Asset` y el pack
|
||||||
|
|
||||||
|
`source/core/resources/asset.*` mantiene el **índice de ficheros** a partir del
|
||||||
|
manifiesto `data/config/assets.txt` (`director.cpp:296`) y valida que no falte
|
||||||
|
ninguno (`Asset::check()`). La lectura física pasa por
|
||||||
|
`ResourceHelper::loadFile`, que sirve desde **`resources.pack`** y hace
|
||||||
|
*fallback* al filesystem en builds de desarrollo (en Release nativo es estricto:
|
||||||
|
solo el pack; `director.cpp:143`). `resource_pack.*` y `resource_loader.*`
|
||||||
|
implementan el formato del pack y la carga.
|
||||||
|
|
||||||
|
Formatos: imágenes vía `stb_image` + `gif` propio; audio `.ogg` vía
|
||||||
|
`stb_vorbis`; texto/JSON vía `nlohmann/json`; configs vía `fkyaml`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Audio
|
||||||
|
|
||||||
|
`source/core/audio/audio.hpp` — `Audio` singleton sobre `jail_audio`
|
||||||
|
(primer-party, no librería externa) y `audio_adapter`. API: `playMusic(name,
|
||||||
|
loop, crossfade_ms)`, `playSound(name, Group)`, control de volumen por **grupos**
|
||||||
|
(`Group::GAME`, `INTERFACE`, …), `pause/resume/stop`, *crossfade* y *fade out*
|
||||||
|
(`audio.hpp:49`). `Audio::update()` se llama cada frame desde las secciones
|
||||||
|
(p.ej. `Game::update`). El build `NO_AUDIO` compila sin audio.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Configuración, parámetros y constantes
|
||||||
|
|
||||||
|
El proyecto tiene **tres capas de configuración** que conviene no confundir:
|
||||||
|
|
||||||
|
1. **`Options`** (`source/game/options.hpp`) — opciones persistentes del
|
||||||
|
usuario, agrupadas en structs (`Window`, `Video`, `Audio`, `Settings`,
|
||||||
|
`Gamepad`, `Keyboard`) más presets de shaders (`PostFXPreset`,
|
||||||
|
`CrtPiPreset`). Se guardan en `config.yaml` / `controllers.json` /
|
||||||
|
`postfx.yaml` / `crtpi.yaml`. Incluye `params_preset` ∈ {`classic`,
|
||||||
|
`arcade`, `red`} (`options.hpp:339`).
|
||||||
|
2. **`param` / `Param`** (`source/utils/param.hpp`) — parámetros de *gameplay y
|
||||||
|
layout* (dimensiones del juego, `play_area`, ajustes de globos, scoreboard,
|
||||||
|
título, fades, jugador, Tabe…). Se cargan de ficheros de texto
|
||||||
|
`param_320x240.txt` / `param_320x256.txt` / `classic.txt` con
|
||||||
|
`loadParamsFromFile` (`director.cpp:275`). El objeto global `param` lo leen
|
||||||
|
casi todos los subsistemas.
|
||||||
|
3. **Otros datos de juego**: `stages.txt` (fases, lo lee `StageManager`),
|
||||||
|
`formations.txt` (formaciones de globos), `assets.txt` (manifiesto).
|
||||||
|
|
||||||
|
Los **valores de fallback compilados** viven en
|
||||||
|
`source/core/system/defaults.hpp` (y `source/utils/defines.hpp` para constantes
|
||||||
|
base). En Debug, `debug.yaml` controla sección inicial, opciones, fase, modo de
|
||||||
|
carga, `autoplay` e `invincibility` (`director.cpp:318`).
|
||||||
|
|
||||||
|
### Builds condicionales (multiplataforma)
|
||||||
|
|
||||||
|
El juego se adapta por *defines* (ver `CLAUDE.md`): `WINDOWS_BUILD` /
|
||||||
|
`LINUX_BUILD` / `MACOS_BUILD`, `RELEASE_BUILD`, `MACOS_BUNDLE`, `ANBERNIC`
|
||||||
|
(handheld), `__EMSCRIPTEN__` (web), `NO_SHADERS`, `NO_AUDIO`, `RECORDING`,
|
||||||
|
`ARCADE`, `DEBUG`/`VERBOSE`. Aparecen sobre todo en `Director::init` y `Screen`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Localización
|
||||||
|
|
||||||
|
`source/core/locale/lang.*` — `Lang` carga el idioma desde **JSON** en
|
||||||
|
`data/lang/`. `Lang::setLanguage(Options::settings.language)` se llama en
|
||||||
|
`init()` y en cada `reset()`. Cambiar idioma en caliente (F9 / `CHANGE_LANG`)
|
||||||
|
fuerza un `Section::RESET` (reinicio del proceso) para recargarlo todo
|
||||||
|
(`global_inputs.cpp`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Convenciones y patrones recurrentes
|
||||||
|
|
||||||
|
- **Naming** (de `.clang-format`/`.clang-tidy`, resumido en `CLAUDE.md`):
|
||||||
|
clases `CamelCase`, métodos `camelBack`, variables/params `snake_case`,
|
||||||
|
miembros privados `snake_case_` (guion bajo final), constantes `UPPER_CASE`,
|
||||||
|
namespaces `CamelCase`, valores de enum `UPPER_CASE`. clang-tidy trata los
|
||||||
|
warnings como errores.
|
||||||
|
- **Singletons con init/destroy manual**: `Screen`, `Resource`, `Audio`,
|
||||||
|
`Input`, `Asset`, `ServiceMenu`, `Notifier`, `Lang`. Se crean/destruyen en
|
||||||
|
orden explícito en `Director::init` / `shutdownSubsystems` (`director.cpp:227`)
|
||||||
|
— no se confía en destructores estáticos.
|
||||||
|
- **Estado de flujo por variable global** (`Section::name`): patrón central; no
|
||||||
|
hay objetos de transición tipados.
|
||||||
|
- **Time-based en todo**: cada sistema recibe `delta_time`; las constantes de
|
||||||
|
tiempo se documentan como "N frames a 60fps → segundos" (p.ej.
|
||||||
|
`game.hpp:85`).
|
||||||
|
- **Callbacks para desacoplar**: `BulletManager` y `StageManager` reciben
|
||||||
|
`std::function` desde `Game` para no conocer la lógica de colisión/puntuación.
|
||||||
|
- **Interfaz mínima `IStageInfo`** (`stage_interface.hpp`): se inyecta a
|
||||||
|
jugador y globos para que consulten amenaza/poder sin ver todo el
|
||||||
|
`StageManager`.
|
||||||
|
- **Managers por tipo + listas homogéneas** en `Game`, en vez de un contenedor
|
||||||
|
de entidades polimórfico.
|
||||||
|
- **Comentarios** en español/valenciano; muchos `#include` llevan comentario
|
||||||
|
"// Para X" indicando qué símbolo justifican (estilo IWYU).
|
||||||
|
- **Multiplataforma por `#ifdef`** (ver §11). Conviene leerlos al tocar
|
||||||
|
arranque o render.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. Guía de navegación: "si quieres tocar X, mira Y"
|
||||||
|
|
||||||
|
| Quiero… | Empieza por… |
|
||||||
|
|---|---|
|
||||||
|
| Entender el arranque | `source/core/system/director.cpp` (`init`, `iterate`) |
|
||||||
|
| Cambiar el flujo de pantallas | `source/core/system/section.hpp` + `handleSectionTransition` |
|
||||||
|
| Añadir/editar una pantalla | `source/game/scenes/` (crea `iterate()`+`handleEvent()`) y un `case` en `director.cpp` |
|
||||||
|
| La barra de carga / arranque lento | `Resource::beginLoad/loadStep` + `scenes/preload.*` |
|
||||||
|
| Cómo se dibuja todo | `Game::fillCanvas` + `Game::render` + `Screen::renderPresent` (`screen.cpp:156`) |
|
||||||
|
| Sprites / animaciones | `source/core/rendering/sprite/` + `texture.hpp` |
|
||||||
|
| Shaders / CRT / post-FX | `source/core/rendering/sdl3gpu/` + `data/shaders/` + `Options` presets |
|
||||||
|
| Efectos (shake/flash/fade) | `screen.hpp` (structs) + `core/rendering/fade.*` |
|
||||||
|
| Controles / mandos | `source/core/input/input.hpp` (`Keyboard`/`Gamepad`/`checkAction`) |
|
||||||
|
| Hotkeys F1–F12 / reset | `source/core/input/global_inputs.cpp` |
|
||||||
|
| Eventos globales / hot-plug | `source/core/system/global_events.cpp` |
|
||||||
|
| Lógica de partida y estados | `source/game/scenes/game.cpp` (`updateGameState*`) |
|
||||||
|
| Globos y formaciones | `gameplay/balloon_manager.*` + `entities/balloon.*` + `formations.txt` |
|
||||||
|
| Balas y colisiones | `gameplay/bullet_manager.*` (callbacks) + `entities/bullet.*` |
|
||||||
|
| Fases / progresión / dificultad | `gameplay/stage.*` (`StageManager`) + `stages.txt` + `gameplay/difficulty.*` |
|
||||||
|
| El jugador (movimiento, disparo) | `entities/player.*` (sistema de disparo de dos líneas) |
|
||||||
|
| Ítems y power-ups | `entities/item.*` + `Game::dropItem/createItem` |
|
||||||
|
| Récords / entrada de nombre | `gameplay/manage_hiscore_table.*`, `gameplay/enter_name.*` |
|
||||||
|
| **Modo demo / attract** | `core/system/demo.*`, `Game::initDemo/demoHandle*`, `scenes/title.cpp` |
|
||||||
|
| Grabar nuevas demos | build con `RECORDING` + `Game::updateRecording` |
|
||||||
|
| Cargar un recurso | `core/resources/resource.hpp` + `asset.*` + `assets.txt` |
|
||||||
|
| Audio (música/SFX) | `core/audio/audio.hpp` |
|
||||||
|
| Opciones del usuario | `game/options.hpp` (+ `config.yaml`) |
|
||||||
|
| Parámetros de gameplay/layout | `utils/param.hpp` + `param_320x*.txt` |
|
||||||
|
| Valores por defecto | `core/system/defaults.hpp`, `utils/defines.hpp` |
|
||||||
|
| Idiomas | `core/locale/lang.*` + `data/lang/` |
|
||||||
|
| Menú de servicio / notificaciones | `game/ui/service_menu.*`, `game/ui/notifier.*` |
|
||||||
|
| Empaquetar datos | `tools/` (`pack_resources`) + `make resources.pack` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Documento generado a partir de la lectura directa del código en el commit
|
||||||
|
actual de la rama `main`. Si algo aquí no cuadra con el código, el código
|
||||||
|
manda: actualiza este documento.*
|
||||||
@@ -1,19 +1,5 @@
|
|||||||
### JailDesigner - Custom mappings
|
|
||||||
|
|
||||||
# Mandos recreativa CCAE
|
|
||||||
0300457e790000000600000010010000,DragonRise Inc. Generic USB Joystick,platform:Linux,a:b0,b:b1,x:b2,y:b6,back:b5,leftx:a0,lefty:a1,
|
|
||||||
|
|
||||||
# RAP4
|
|
||||||
030086650d0f00008c000000140100003853140,Generic X-Box pad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,
|
|
||||||
|
|
||||||
# Mad Catz FightStick Alpha PS4
|
|
||||||
03007fcb380700008081000011010000184833152,Mad Catz FightStick Alpha PS4,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b13,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,
|
|
||||||
|
|
||||||
# Mando custom de Dani en madera + Agetec
|
|
||||||
030020617900000006000000100100001216,DragonRise Inc. Generic USB Joystick,platform:Linux,a:b2,b:b1,x:b0,y:b6,start:b5,leftx:a0,lefty:a1,
|
|
||||||
|
|
||||||
# Game Controller DB for SDL in 2.0.16 format
|
# Game Controller DB for SDL in 2.0.16 format
|
||||||
# Source: https://github.com/gabomdq/SDL_GameControllerDB
|
# Source: https://github.com/mdqinc/SDL_GameControllerDB
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,
|
03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
@@ -24,6 +10,7 @@
|
|||||||
03000000d0160000060d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
|
03000000d0160000060d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
|
||||||
03000000d0160000070d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
|
03000000d0160000070d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
|
||||||
03000000d0160000600a000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
|
03000000d0160000600a000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows,
|
||||||
|
03000000c82d00001930000000000000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b11,platform:Windows,
|
||||||
03000000c82d00000031000000000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00000031000000000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00000531000000000000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00000531000000000000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00000951000000000000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows,
|
03000000c82d00000951000000000000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows,
|
||||||
@@ -61,9 +48,10 @@
|
|||||||
03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00000851000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00000851000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000361000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000361000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000960000000000000,8BitDo Pro 3,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000131000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000131000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000231000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000231000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000331000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000331000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
@@ -87,14 +75,16 @@
|
|||||||
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000260000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000260000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
03000000c82d00000261000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00000261000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00001130000000000000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001230000000000000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00001230000000000000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c82d00001330000000000000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c82d00001260000000000000,8BitDo Ultimate 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001b30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00001b30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c82d00001c30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001d30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00001d30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001530000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00001530000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001630000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00001630000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001730000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00001730000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001130000000000000,8BitDo Ultimate Wired,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
|
||||||
03000000c82d00001330000000000000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
|
|
||||||
03000000c82d00000121000000000000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c82d00000121000000000000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
|
03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
@@ -135,6 +125,7 @@
|
|||||||
03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000050b00000579000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000050b00000579000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000050b00000679000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000050b00000679000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
030000006a0e00001140000000000000,Atari CX Controller,a:b0,leftx:a0,lefty:a1,platform:Windows,
|
||||||
03000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,start:b3,platform:Windows,
|
03000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,start:b3,platform:Windows,
|
||||||
03000000503200000210000000000000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
|
03000000503200000210000000000000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000380800001889000000000000,AtGames Legends Gamer Pro,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b14,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
03000000380800001889000000000000,AtGames Legends Gamer Pro,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b14,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
@@ -150,6 +141,7 @@
|
|||||||
03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
03000000bc2000005250000000000000,Beitong G3,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a3,righty:a4,start:b15,x:b3,y:b4,platform:Windows,
|
03000000bc2000005250000000000000,Beitong G3,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a3,righty:a4,start:b15,x:b3,y:b4,platform:Windows,
|
||||||
030000000d0500000208000000000000,Belkin Nostromo N40,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
030000000d0500000208000000000000,Belkin Nostromo N40,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000000d0500000308000000000000,Belkin Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,
|
||||||
03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000bc2000000055000000000000,Betop BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000bc2000000055000000000000,Betop BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000790000000700000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
03000000790000000700000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
@@ -186,7 +178,7 @@
|
|||||||
030000001a1c00000001000000000000,Datel Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
030000001a1c00000001000000000000,Datel Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000791d00000103000000000000,Dual Box Wii,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
03000000791d00000103000000000000,Dual Box Wii,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000c0160000e105000000000000,Dual Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
03000000151a00006222000000000000,Dual Plus PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows,
|
030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows,
|
||||||
030000004f04000012b3000000000000,Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
030000004f04000012b3000000000000,Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
||||||
030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
||||||
@@ -201,7 +193,8 @@
|
|||||||
03000095090000010000000000000000,Elecom JC-U609,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,
|
03000095090000010000000000000000,Elecom JC-U609,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
0300004112000000e500000000000000,Elecom JC-U909Z,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,
|
0300004112000000e500000000000000,Elecom JC-U909Z,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
03000041120000001050000000000000,Elecom JC-U911,a:b1,b:b2,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b0,x:b4,y:b5,platform:Windows,
|
03000041120000001050000000000000,Elecom JC-U911,a:b1,b:b2,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b0,x:b4,y:b5,platform:Windows,
|
||||||
030000006e0500000520000000000000,Elecom P301U PlayStation Controller Adapter,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
030000006e0500000520000000000000,Elecom P301U PlayStation Adapter,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000250900000218000000000000,Elecom PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000411200004450000000000000,Elecom U1012,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
03000000411200004450000000000000,Elecom U1012,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
030000006e0500000320000000000000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
030000006e0500000320000000000000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
030000006e0500000e20000000000000,Elecom U3912T,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
030000006e0500000e20000000000000,Elecom U3912T,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
@@ -236,17 +229,19 @@
|
|||||||
03000000b40400001224000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000b40400001224000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,
|
030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows,
|
||||||
0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
|
0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000790000004618000000000000,GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
|
03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000341a000005f7000000000000,GameCube Controller,a:b2,b:b3,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b1,y:b0,platform:Windows,
|
03000000341a000005f7000000000000,GameCube Controller,a:b2,b:b3,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b1,y:b0,platform:Windows,
|
||||||
03000000430b00000500000000000000,GameCube Controller,a:b0,b:b2,dpdown:b10,dpleft:b8,dpright:b9,dpup:b11,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a3,rightx:a5,righty:a2,start:b7,x:b1,y:b3,platform:Windows,
|
03000000430b00000500000000000000,GameCube Controller,a:b0,b:b2,dpdown:b10,dpleft:b8,dpright:b9,dpup:b11,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a3,rightx:a5,righty:a2,start:b7,x:b1,y:b3,platform:Windows,
|
||||||
03000000790000004718000000000000,GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
03000000790000004718000000000000,GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
|
||||||
030000008f0e00000d31000000000000,Gamepad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000008f0e00000d31000000000000,Gamepad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000ac0500003d03000000000000,GameSir G3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000ac0500003d03000000000000,GameSir G3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000373500002210000000000000,GameSir G7 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000ac0500001a06000000000000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000ac0500001a06000000000000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000373500000410000000000000,GameSir T4 Kaleid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000373500009410000000000000,GameSir Tegenaria Lite,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000373500009410000000000000,GameSir Tegenaria Lite,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
||||||
030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
@@ -255,7 +250,6 @@
|
|||||||
03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,
|
03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,
|
||||||
030000008f0e00001411000000000000,Gamo2 Divaller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000008f0e00001411000000000000,Gamo2 Divaller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000c9110000f055000000000000,GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
|
||||||
030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
@@ -353,7 +347,7 @@
|
|||||||
030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows,
|
03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows,
|
||||||
03000000242e0000ff0b000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Windows,
|
03000000242e0000ff0b000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Windows,
|
||||||
03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
|
03000000790000004e95000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows,
|
||||||
03000000242e00006a48000000000000,Hyperkin RetroN Sq,a:b3,b:b7,back:b5,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b0,rightshoulder:b1,start:b4,x:b2,y:b6,platform:Windows,
|
03000000242e00006a48000000000000,Hyperkin RetroN Sq,a:b3,b:b7,back:b5,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b0,rightshoulder:b1,start:b4,x:b2,y:b6,platform:Windows,
|
||||||
03000000242f00000a20000000000000,Hyperkin Scout,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
03000000242f00000a20000000000000,Hyperkin Scout,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000242e00000a20000000000000,Hyperkin Scout Premium SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
03000000242e00000a20000000000000,Hyperkin Scout Premium SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
@@ -375,18 +369,20 @@
|
|||||||
03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
|
03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,
|
03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows,
|
||||||
03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,
|
03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows,
|
||||||
03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000491900000204000000000000,Ipega PG9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000491900000204000000000000,Ipega PG9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000491900000304000000000000,Ipega PG9087,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
|
03000000491900000304000000000000,Ipega PG9087,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
|
030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
|
||||||
030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000250900000017000000000000,Joypad Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
|
03000000250900000017000000000000,Joypad Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000bd12000003c0000000000000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000bd12000003c0000000000000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000008b0100002301000000000000,Joytech JS-112,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a2,lefty:a3,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a0,righty:a1,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
03000000ff1100004033000000000000,JPD FFB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a2,start:b15,x:b3,y:b0,platform:Windows,
|
03000000ff1100004033000000000000,JPD FFB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a2,start:b15,x:b3,y:b0,platform:Windows,
|
||||||
03000000242f00002d00000000000000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
03000000242f00002d00000000000000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000242f00008a00000000000000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
03000000242f00008a00000000000000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
||||||
03000000c4100000c082000000000000,KADE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000c4100000c082000000000000,KADE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000828200000180000000000000,Keio,a:b4,b:b5,back:b8,leftshoulder:b2,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b1,platform:Windows,
|
03000000828200000180000000000000,Keio,a:b4,b:b5,back:b8,leftshoulder:b2,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000c4ac00001c80000000000000,KidzPlay Adventure PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000bd12000001e0000000000000,Leadership,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
03000000bd12000001e0000000000000,Leadership,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
030000006f0e00000103000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
030000006f0e00000103000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
@@ -394,7 +390,6 @@
|
|||||||
030000008f0e00001300000000000000,Logic3,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
030000008f0e00001300000000000000,Logic3,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,
|
|
||||||
030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
@@ -404,6 +399,7 @@
|
|||||||
030000006d0400001ac2000000000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
030000006d0400001ac2000000000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000006d04000009c2000000000000,Logitech WingMan,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
030000006d04000009c2000000000000,Logitech WingMan,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
030000006d0400000bc2000000000000,Logitech WingMan Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows,
|
030000006d0400000bc2000000000000,Logitech WingMan Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
|
030000006d04000011c2000000000000,Logitech WingMan Cordless,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,
|
||||||
030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
|
030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
|
||||||
03000000380700005645000000000000,Lynx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
03000000380700005645000000000000,Lynx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
@@ -430,19 +426,19 @@
|
|||||||
03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
|
030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
|
030000008f0e00001330000000000000,Mayflash Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
|
03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
|
||||||
030000008f0e00001330000000000000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
|
||||||
03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000790000004318000000000000,Mayflash GameCube Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
|
||||||
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
||||||
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000242f0000f400000000000000,Mayflash N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
||||||
03000000242f0000f500000000000000,Mayflash N64 Adapter,a:b2,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
03000000242f0000f500000000000000,Mayflash N64 Adapter,a:b2,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
||||||
03000000242f0000f400000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows,
|
03000000790000007918000000000000,Mayflash N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,righttrigger:b7,rightx:a3,righty:a2,start:b8,platform:Windows,
|
||||||
03000000790000007918000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,righttrigger:b7,rightx:a3,righty:a2,start:b8,platform:Windows,
|
|
||||||
030000008f0e00001030000000000000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
030000008f0e00001030000000000000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
||||||
0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
|
0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
|
||||||
03000000790000000318000000000000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
|
03000000790000000318000000000000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
@@ -472,7 +468,9 @@
|
|||||||
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows,
|
03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows,
|
||||||
03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,
|
03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows,
|
||||||
030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
03000000c9110000f055000000000000,Nacon GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000c21100000791000000000000,Nacon GC101 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006b140000010c000000000000,Nacon GC400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
0300000085320000170d000000000000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
0300000085320000170d000000000000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
0300000085320000190d000000000000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
0300000085320000190d000000000000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
@@ -482,25 +480,25 @@
|
|||||||
03000000eb0300000000000000000000,NeGcon Adapter,a:a2,b:b13,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,lefttrigger:a4,leftx:a1,righttrigger:b11,start:b3,x:a3,y:b12,platform:Windows,
|
03000000eb0300000000000000000000,NeGcon Adapter,a:a2,b:b13,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,lefttrigger:a4,leftx:a1,righttrigger:b11,start:b3,x:a3,y:b12,platform:Windows,
|
||||||
0300000038070000efbe000000000000,NEO SE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
0300000038070000efbe000000000000,NEO SE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows,
|
0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows,
|
||||||
03000000921200004b46000000000000,NES 2 port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,
|
03000000921200004b46000000000000,NES Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows,
|
||||||
03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
|
03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
|
||||||
03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
|
03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
|
||||||
03000000790000004518000000000000,NEXILUX GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
03000000790000004518000000000000,NEXiLUX GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,
|
030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,
|
03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows,
|
||||||
03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000ec110000e1a7000000000000,Nintendo Switch,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000007e0500006920000000000000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Windows,
|
030000007e0500006920000000000000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Windows,
|
||||||
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,
|
|
||||||
030000007e0500007320000000000000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Windows,
|
030000007e0500007320000000000000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Windows,
|
||||||
030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,
|
030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows,
|
||||||
030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows,
|
030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
|
03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
|
||||||
03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,
|
03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows,
|
||||||
030000005509000000b4000000000000,NVIDIA Virtual,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
030000005509000000b4000000000000,NVIDIA Virtual,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000120c00000288000000000000,Nyko Air Flo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
030000004b120000014d000000000000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000004b120000014d000000000000,NYKO Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
|
||||||
03000000d62000001d57000000000000,Nyko Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000d62000001d57000000000000,Nyko Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000120c00000288000000000000,Nyko Airflo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
||||||
03000000791d00000900000000000000,Nyko Playpad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000791d00000900000000000000,Nyko Playpad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000782300000a10000000000000,Onlive Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,
|
03000000782300000a10000000000000,Onlive Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,
|
||||||
030000000d0f00000401000000000000,Onyx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
030000000d0f00000401000000000000,Onyx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
@@ -521,8 +519,8 @@
|
|||||||
03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000d620000013a7000000000000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000d620000013a7000000000000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000d62000003340000000000000,PowerA OPS Pro Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000d62000002640000000000000,PowerA OPS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000d62000002640000000000000,PowerA OPS Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000d62000003340000000000000,PowerA OPS Pro Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000d620000014a7000000000000,PowerA Spectra Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000d620000014a7000000000000,PowerA Spectra Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
@@ -540,13 +538,11 @@
|
|||||||
03000000250900008888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
03000000250900008888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000151a00006222000000000000,PS2 Dual Plus Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
|
||||||
03000000120a00000100000000000000,PS3 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000120a00000100000000000000,PS3 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000120c00001307000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000120c00001307000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000120c00001cf1000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000120c00001cf1000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000120c0000f90e000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000120c0000f90e000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000250900000118000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
03000000250900000118000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000250900000218000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
|
||||||
03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,
|
03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,
|
||||||
030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,
|
030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
030000004f1f00000800000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
030000004f1f00000800000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
@@ -609,7 +605,7 @@
|
|||||||
030000009b2800006300000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
|
030000009b2800006300000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
|
||||||
030000009b2800006400000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
|
030000009b2800006400000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
|
||||||
030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
|
030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
|
||||||
030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,
|
030000009b2800004400000000000000,Raphnet PlayStation Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,
|
||||||
030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
030000009b2800000500000000000000,Raphnet Saturn Adapter 2.0,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
|
030000009b2800000500000000000000,Raphnet Saturn Adapter 2.0,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000009b2800000300000000000000,Raphnet SNES Adapter,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
|
030000009b2800000300000000000000,Raphnet SNES Adapter,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows,
|
||||||
@@ -637,7 +633,7 @@
|
|||||||
03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000321500000011000000000000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
03000000321500000011000000000000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows,
|
03000000921200004547000000000000,Retro Bit Sega Genesis Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows,
|
||||||
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
|
03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000632500007805000000000000,Retro Fighters Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
03000000632500007805000000000000,Retro Fighters Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
@@ -658,6 +654,7 @@
|
|||||||
030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000830500000052000000000000,Rockfire CosmoVoyager,a:b0,b:b1,x:b3,y:b4,back:b8,guide:b10,start:b9,leftshoulder:b6,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,misc1:b11,lefttrigger:b7,righttrigger:b2,platform:Windows,
|
||||||
03000000830500007030000000000000,Rockfire Space Ranger,a:b0,b:b1,back:b5,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b9,righttrigger:b8,start:b2,x:b3,y:b4,platform:Windows,
|
03000000830500007030000000000000,Rockfire Space Ranger,a:b0,b:b1,back:b5,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b9,righttrigger:b8,start:b2,x:b3,y:b4,platform:Windows,
|
||||||
03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
|
03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
|
||||||
03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
|
03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows,
|
||||||
@@ -692,7 +689,9 @@
|
|||||||
03000000c01100004150000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
03000000c01100004150000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
||||||
03000000c01100004450000000000000,Sanwa Online Grip,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b14,x:b3,y:b4,platform:Windows,
|
03000000c01100004450000000000000,Sanwa Online Grip,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b14,x:b3,y:b4,platform:Windows,
|
||||||
03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
|
03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows,
|
||||||
|
030000009d0d00001130000000000000,Sanwa PlayStation Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
03000000830500006120000000000000,Sanwa Smart Grip II,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,x:b1,y:b3,platform:Windows,
|
03000000830500006120000000000000,Sanwa Smart Grip II,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,x:b1,y:b3,platform:Windows,
|
||||||
|
03000000630600000201000000000000,Sanwa Virtua Grip,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,x:b0,y:b1,platform:Windows,
|
||||||
03000000c01100000051000000000000,Satechi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000c01100000051000000000000,Satechi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
030000004f04000028b3000000000000,Score A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
030000004f04000028b3000000000000,Score A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
@@ -704,6 +703,7 @@
|
|||||||
03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows,
|
||||||
03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows,
|
030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows,
|
||||||
|
03000000632500002705000000000000,ShanWan Q36,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows,
|
||||||
03000000140300000918000000000000,SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
|
03000000140300000918000000000000,SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
@@ -714,12 +714,12 @@
|
|||||||
030000008f0e00000910000000000000,Sony DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
|
030000008f0e00000910000000000000,Sony DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
|
||||||
03000000317300000100000000000000,Sony DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000317300000100000000000000,Sony DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000666600006706000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
|
03000000666600006706000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d9040000160f000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000e30500009605000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
03000000e30500009605000000000000,Sony PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000fe1400002a23000000000000,Sony PlayStation Adapter,a:b0,b:b1,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,x:b2,y:b3,platform:Windows,
|
03000000fe1400002a23000000000000,Sony PlayStation Adapter,a:b0,b:b1,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,x:b2,y:b3,platform:Windows,
|
||||||
030000004c050000da0c000000000000,Sony PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
030000004c050000da0c000000000000,Sony PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000632500002306000000000000,Sony PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
|
03000000632500002306000000000000,Sony PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000f0250000c183000000000000,Sony PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000f0250000c183000000000000,Sony PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000d9040000160f000000000000,Sony PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
|
||||||
03000000ff000000cb01000000000000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
|
03000000ff000000cb01000000000000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
030000004c0500003713000000000000,Sony PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
030000004c0500003713000000000000,Sony PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000341a00000208000000000000,Speedlink 6555,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
|
03000000341a00000208000000000000,Speedlink 6555,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
@@ -757,19 +757,21 @@
|
|||||||
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
||||||
030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000004f0400000ed0000000000000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
030000004f0400000ed0000000000000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000004f04000008d0000000000000,Thrustmaster Ferrari 150 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
|
||||||
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
|
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
|
||||||
030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
||||||
030000004f04000003d0000000000000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
030000004f04000003d0000000000000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:-a3,leftx:a0,lefty:a1,paddle1:b6,paddle2:b7,rightshoulder:b5,rightstick:b11,righttrigger:-a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004f04000008d0000000000000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
030000004f04000009d0000000000000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000004f04000009d0000000000000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000011000000200000000000000,ThundeRobot G30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
||||||
03000000666600000288000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
03000000666600000288000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000666600000488000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
03000000666600000488000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
030000004f04000007d0000000000000,TMini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
030000004f04000007d0000000000000,TMini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000571d00002100000000000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Windows,
|
03000000571d00002100000000000000,Tomee NES Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Windows,
|
||||||
03000000571d00002000000000000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
|
03000000571d00002000000000000000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000c01100000055000000000000,Tronsmart,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
03000000c01100000055000000000000,Tronsmart,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d60600002a00000000000000,Trust 850F,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,x:b3,y:b4,platform:Windows,
|
||||||
030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,
|
030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,
|
||||||
@@ -816,7 +818,7 @@
|
|||||||
03000000c62400000053000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
03000000c62400000053000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000c6240000fdfa000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
03000000c6240000fdfa000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000380700002847000000000000,Xbox 360 Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
03000000380700002847000000000000,Xbox 360 Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
030000005e040000a102000000000000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
030000005e040000a102000000000000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows,
|
||||||
03000000120c00001088000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2~,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5~,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
03000000120c00001088000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2~,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5~,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
@@ -848,15 +850,20 @@
|
|||||||
03000000172700004431000000000000,Xiaomi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
03000000172700004431000000000000,Xiaomi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000172700003350000000000000,Xiaomi XMGP01YM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000172700003350000000000000,Xiaomi XMGP01YM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
03000000bc2000005060000000000000,Xiaomi XMGP01YM,+lefty:+a2,+righty:+a5,-lefty:-a1,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
|
03000000bc2000005060000000000000,Xiaomi XMGP01YM,+lefty:+a2,+righty:+a5,-lefty:-a1,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c0160000e105000000000000,XinMo Dual Arcade,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows,
|
030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
030000002c3600000100000000000000,Yawman Arrow,+rightx:h0.2,+righty:h0.4,-rightx:h0.8,-righty:h0.1,a:b4,b:b5,back:b6,dpdown:b15,dpleft:b14,dpright:b16,dpup:b13,leftshoulder:b10,leftstick:b0,lefttrigger:-a4,leftx:a0,lefty:a1,paddle1:b11,paddle2:b12,rightshoulder:b8,rightstick:b9,righttrigger:+a4,start:b3,x:b1,y:b2,platform:Windows,
|
030000002c3600000100000000000000,Yawman Arrow,+rightx:h0.2,+righty:h0.4,-rightx:h0.8,-righty:h0.1,a:b4,b:b5,back:b6,dpdown:b15,dpleft:b14,dpright:b16,dpup:b13,leftshoulder:b10,leftstick:b0,lefttrigger:-a4,leftx:a0,lefty:a1,paddle1:b11,paddle2:b12,rightshoulder:b8,rightstick:b9,righttrigger:+a4,start:b3,x:b1,y:b2,platform:Windows,
|
||||||
03000000790000004f18000000000000,ZDT Android Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
03000000790000004f18000000000000,ZDT Android Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000073500000400000000000000,Zenaim Arcade Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
03000000120c00000500000000000000,Zeroplus Adapter,a:b2,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,
|
03000000120c00000500000000000000,Zeroplus Adapter,a:b2,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
03000000120c0000101e000000000000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
03000000120c0000101e000000000000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
|
||||||
# Mac OS X
|
# Mac OS X
|
||||||
030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000c82d00001930000000000000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
|
||||||
|
03000000c82d00001930000000020000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
|
||||||
|
03000000c82d00001930000001000000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
|
||||||
03000000c82d00000031000001000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000c82d00000031000001000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000c82d00000531000000020000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000c82d00000531000000020000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
|
03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
|
||||||
@@ -889,6 +896,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000960000000000000,8BitDo Pro 3,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000131000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000131000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000231000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000231000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000331000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000331000001000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
@@ -900,7 +908,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00004028000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00004028000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000260000001000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000260000001000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
03000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
03000000c82d00001230000000010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000c82d00001230000000010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
@@ -925,6 +933,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000050b00000579000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b42,paddle1:b9,paddle2:b11,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
|
03000000050b00000579000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b42,paddle1:b9,paddle2:b11,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b23,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
|
03000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b23,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
030000006a0e00001140000001000000,Atari CX Wireless Controller,a:b0,leftx:a0,lefty:a1,platform:Mac OS X,
|
||||||
03000000503200000110000045010000,Atari VCS Classic,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b3,start:b2,platform:Mac OS X,
|
03000000503200000110000045010000,Atari VCS Classic,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b3,start:b2,platform:Mac OS X,
|
||||||
03000000503200000110000047010000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b3,start:b2,platform:Mac OS X,
|
03000000503200000110000047010000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b3,start:b2,platform:Mac OS X,
|
||||||
03000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Mac OS X,
|
03000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
@@ -939,6 +948,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000120c0000200e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
03000000120c0000200e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000120c0000210e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
03000000120c0000210e000000010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000501d00009e61000001000000,CoreOrbits GamerPad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000d8140000cecf000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
|
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000a306000022f6000001030000,Cyborg V3 Rumble Pad PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000a306000022f6000001030000,Cyborg V3 Rumble Pad PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
@@ -948,7 +958,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000151900004000000001000000,Flydigi Vader 2,a:b14,b:b15,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Mac OS X,
|
03000000151900004000000001000000,Flydigi Vader 2,a:b14,b:b15,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Mac OS X,
|
||||||
03000000b40400001124000001040000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000b40400001124000001040000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000b40400001224000003030000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000b40400001224000003030000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
|
03000000790000004618000000010000,GameCube Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
|
||||||
03000000ac0500001a06000002020000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000ac0500001a06000002020000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000373500000411000023000000,GameSir X4A Xbox Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000373500000411000023000000,GameSir X4A Xbox Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000ad1b000001f9000000000000,Gamestop BB070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
03000000ad1b000001f9000000000000,Gamestop BB070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
@@ -981,8 +991,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000000d0f00006600000000000000,Horipad FPS Plus 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000000d0f00006600000000000000,Horipad FPS Plus 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000000d0f0000ee00000000010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000000d0f0000ee00000000010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000000d0f0000c100000072050000,Horipad Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000000d0f0000c100000072050000,Horipad Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f0000f600000000010000,Horipad Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000242e0000ff0b000000010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Mac OS X,
|
03000000242e0000ff0b000000010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Mac OS X,
|
||||||
03000000790000004e95000000010000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Mac OS X,
|
03000000790000004e95000000010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Mac OS X,
|
||||||
03000000830500006020000000000000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
|
03000000830500006020000000000000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
|
||||||
03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,
|
03000000ef0500000300000000020000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Mac OS X,
|
||||||
03000000fd0500000030000010010000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Mac OS X,
|
03000000fd0500000030000010010000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Mac OS X,
|
||||||
@@ -990,6 +1001,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,
|
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000242f00002d00000007010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
03000000242f00002d00000007010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
030000006d04000019c2000000000000,Logitech Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006d04000019c2000000000000,Logitech Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000019c2000000020000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
@@ -997,6 +1009,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000006d0400001ac2000004000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000006d04000018c2000000010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006d04000018c2000000010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000380700005032000000010000,Mad Catz PS3 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000380700005032000000010000,Mad Catz PS3 Fightpad Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000380700008433000000010000,Mad Catz PS3 Fightstick TE S Plus,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000380700008433000000010000,Mad Catz PS3 Fightstick TE S Plus,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
@@ -1004,7 +1017,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000380700008483000000010000,Mad Catz PS4 Fightstick TE S Plus,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
03000000380700008483000000010000,Mad Catz PS4 Fightstick TE S Plus,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||||
0300000049190000020400001b010000,Manba One,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
0300000049190000020400001b010000,Manba One,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
03000000790000000600000007010000,Marvo GT-004,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
030000008f0e00001330000011010000,Mayflash Controller Adapter,a:b2,b:b4,back:b16,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b12,lefttrigger:b16,leftx:a0,lefty:a2,rightshoulder:b14,rightx:a6~,righty:a4,start:b18,x:b0,y:b6,platform:Mac OS X,
|
030000008f0e00001330000011010000,Mayflash Adapter,a:b2,b:b4,back:b16,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b12,lefttrigger:b16,leftx:a0,lefty:a2,rightshoulder:b14,rightx:a6~,righty:a4,start:b18,x:b0,y:b6,platform:Mac OS X,
|
||||||
03000000790000004318000000010000,Mayflash GameCube Adapter,a:b4,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
|
03000000790000004318000000010000,Mayflash GameCube Adapter,a:b4,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X,
|
||||||
03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,
|
03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,
|
||||||
@@ -1025,8 +1038,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000853200008906000000010000,Nacon Revolution X Unlimited,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000853200008906000000010000,Nacon Revolution X Unlimited,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000632500007505000000020000,NeoGeo mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,
|
03000000632500007505000000020000,NeoGeo mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000921200004b46000003020000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X,
|
03000000921200004b46000003020000,NES Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X,
|
||||||
030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X,
|
030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000ec110000e1a7000001010000,Nintendo Switch,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
030000007e0500006920000001010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Mac OS X,
|
030000007e0500006920000001010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||||
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
@@ -1040,10 +1054,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,righttrigger:a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Mac OS X,
|
0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,righttrigger:a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000006f0e00000901000002010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
|
030000008f0e00000300000000000000,Piranha Xtreme PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000100800000300000006010000,PlayStation Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
03000000d620000011a7000000020000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000d620000011a7000010050000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000d620000011a7000010050000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000100800000300000006010000,PS2 Adapter,a:b2,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
|
||||||
030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
||||||
030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
||||||
030000004c0500006802000072050000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
030000004c0500006802000072050000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
||||||
@@ -1072,7 +1086,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000632500008005000000010000,Redgear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
03000000632500008005000000010000,Redgear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
03000000632500002305000000010000,Redragon Saturn,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
03000000632500002305000000010000,Redragon Saturn,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
03000000921200004547000000020000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b2,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,lefttrigger:b14,rightshoulder:b10,righttrigger:b4,start:b12,x:b6,y:b8,platform:Mac OS X,
|
03000000921200004547000000020000,Retro Bit Sega Genesis Adapter,a:b0,b:b2,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,lefttrigger:b14,rightshoulder:b10,righttrigger:b4,start:b12,x:b6,y:b8,platform:Mac OS X,
|
||||||
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000790000001100000005010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
|
03000000830500006020000000010000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
@@ -1106,7 +1120,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
||||||
030000000d0f0000f600000000010000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
|
||||||
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000457500002211000000010000,SZMY Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000e40a00000307000001000000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
|
03000000e40a00000307000001000000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
|
||||||
03000000e40a00000207000001000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
|
03000000e40a00000207000001000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Mac OS X,
|
||||||
@@ -1117,13 +1130,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
|
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
|
||||||
030000004f0400000ed0000000020000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
030000004f0400000ed0000000020000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
|
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
|
||||||
03000000571d00002100000021000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Mac OS X,
|
03000000571d00002100000021000000,Tomee NES Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Mac OS X,
|
||||||
03000000bd12000015d0000000010000,Tomee Retro Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
03000000bd12000015d0000000010000,Tomee Retro Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000571d00002000000021000000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
03000000bd12000015d0000000000000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
03000000bd12000015d0000000000000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
03000000571d00002000000021000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Mac OS X,
|
|
||||||
030000005f140000c501000000020000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
030000005f140000c501000000020000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
|
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
|
||||||
03000000632500002605000000010000,Uberwith Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000632500002605000000010000,Uberwith Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000c0160000e105000000040000,Ultimate Atari Fight Stick,a:b2,b:b4,back:b18,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b8,righttrigger:b10,start:b16,x:b0,y:b6,platform:Mac OS X,
|
||||||
03000000151900005678000010010000,Uniplay U6,a:b3,b:b6,back:b25,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,leftstick:b31,lefttrigger:b21,leftx:a1,lefty:a3,rightshoulder:b19,rightstick:b33,righttrigger:b23,rightx:a4,righty:a5,start:b27,x:b11,y:b13,platform:Mac OS X,
|
03000000151900005678000010010000,Uniplay U6,a:b3,b:b6,back:b25,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b17,leftstick:b31,lefttrigger:b21,leftx:a1,lefty:a3,rightshoulder:b19,rightstick:b33,righttrigger:b23,rightx:a4,righty:a5,start:b27,x:b11,y:b13,platform:Mac OS X,
|
||||||
030000006f0e00000302000025040000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
030000006f0e00000302000025040000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||||
030000006f0e00000702000003060000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
030000006f0e00000702000003060000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X,
|
||||||
@@ -1157,11 +1171,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000005e040000130b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
030000005e040000130b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
030000005e040000130b000022050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
030000005e040000130b000022050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
030000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
030000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
030000005e040000220b000021050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
|
03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
03000000120c0000100e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000120c0000100e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
03000000120c0000101e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
03000000120c0000101e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
|
||||||
# Linux
|
# Linux
|
||||||
|
03000000c82d00001930000011010000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Linux,
|
||||||
|
05000000c82d00001930000001000000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Linux,
|
||||||
03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000c82d00000631000000010000,8BitDo Adapter 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000c82d00000631000000010000,8BitDo Adapter 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux,
|
03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux,
|
||||||
@@ -1169,7 +1186,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
05000000c82d00006a28000000010000,8BitDo GameCube,a:b0,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b9,paddle2:b8,rightshoulder:b10,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b1,y:b4,platform:Linux,
|
05000000c82d00006a28000000010000,8BitDo GameCube,a:b0,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b9,paddle2:b8,rightshoulder:b10,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b1,y:b4,platform:Linux,
|
||||||
03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
@@ -1199,6 +1216,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
03000000c82d00000020000000000000,8BitDo Pro 2 for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000c82d00000020000000000000,8BitDo Pro 2 for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
06000000c82d00000020000006010000,8BitDo Pro 2 for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
06000000c82d00000020000006010000,8BitDo Pro 2 for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000960000011010000,8BitDo Pro 3,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
@@ -1222,6 +1240,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000c82d00000260000011010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
03000000c82d00000260000011010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000631000010010000,8BitDo Ultimate,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000631000014010000,8BitDo Ultimate,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000760000011010000,8BitDo Ultimate,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00001130000011010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000c82d00001230000011010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000c82d00001330000011010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
05000000c82d00001230000000010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
05000000c82d00001230000000010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000c82d00000a31000014010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000c82d00000a31000014010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000c82d00001d30000011010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000c82d00001d30000011010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
@@ -1229,12 +1253,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000c82d00001530000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000c82d00001530000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000c82d00001630000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000c82d00001630000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000c82d00001730000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000c82d00001730000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000c82d00001130000011010000,8BitDo Ultimate Wired,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
|
||||||
03000000c82d00000631000010010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
03000000c82d00000631000014010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
|
||||||
03000000c82d00001230000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
|
||||||
03000000c82d00001330000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
|
||||||
03000000c82d00000121000011010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000c82d00000121000011010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
05000000c82d00000121000000010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
05000000c82d00000121000000010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
|
05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
@@ -1264,6 +1282,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
|
05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
|
||||||
03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000006a0e00001140000010010000,Atari CX Controller,a:b0,leftx:a0,lefty:a1,platform:Linux,
|
||||||
03000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
|
03000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
|
||||||
03000000503200000110000011010000,Atari VCS Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
|
03000000503200000110000011010000,Atari VCS Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
|
||||||
05000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
|
05000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux,
|
||||||
@@ -1285,6 +1304,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000bc2000004d50000011010000,Beitong A1T2 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000bc2000004d50000011010000,Beitong A1T2 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000000d0500000308000010010000,Belkin Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
|
||||||
05000000bc2000000055000001000000,Betop AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
05000000bc2000000055000001000000,Betop AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
@@ -1297,9 +1317,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000af1e00002400000010010000,Clockwork Pi DevTerm,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b9,x:b3,y:b0,platform:Linux,
|
03000000af1e00002400000010010000,Clockwork Pi DevTerm,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
|
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
|
||||||
|
03000000632500007a05000001020000,Cosmic Byte Ares Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
|
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000005e0400008e02000002010000,Data Frog S80,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
|
|
||||||
03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
@@ -1316,8 +1336,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000b40400001224000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000b40400001224000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
06000000d73700000124000000000000,Flydigi Vader 5 Pro,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,misc1:b11,misc2:b12,misc3:b13,misc4:b14,paddle1:b15,paddle2:b17,paddle3:b16,paddle4:b18,misc5:b19,platform:Linux,
|
||||||
030000007e0500003703000000000000,GameCube Adapter,a:b0,b:b1,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
|
030000007e0500003703000000000000,GameCube Adapter,a:b0,b:b1,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux,
|
||||||
19000000030000000300000002030000,GameForce Controller,a:b1,b:b0,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
19000000030000000300000002030000,GameForce Controller,a:b1,b:b0,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b15,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000373500000b10000019010000,GameSir Cyclone 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
@@ -1325,12 +1347,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000ac0500007a05000011010000,GameSir G5,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000ac0500007a05000011010000,GameSir G5,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000373500009710000001020000,GameSir Kaleid Flux,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000373500009710000001020000,GameSir Kaleid Flux,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000ac0500001a06000011010000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000ac0500001a06000011010000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000373500000410000044010000,GameSir T4 Kaleid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000373500009410000010010000,GameSir Tegenaria Lite,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000373500009410000010010000,GameSir Tegenaria Lite,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000f025000021c1000010010000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000f0250000c283000010010000,Gioteck VX2 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
03000000f0250000c283000010010000,Gioteck VX2 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
190000004b4800000010000000010000,GO-Advance Controller,a:b1,b:b0,back:b10,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b13,start:b15,x:b2,y:b3,platform:Linux,
|
190000004b4800000010000000010000,GO-Advance Controller,a:b1,b:b0,back:b10,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,leftshoulder:b4,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b13,start:b15,x:b2,y:b3,platform:Linux,
|
||||||
190000004b4800000010000001010000,GO-Advance Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b13,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b16,righttrigger:b15,start:b17,x:b2,y:b3,platform:Linux,
|
190000004b4800000010000001010000,GO-Advance Controller,a:b1,b:b0,back:b12,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b13,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b16,righttrigger:b15,start:b17,x:b2,y:b3,platform:Linux,
|
||||||
@@ -1344,7 +1368,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
|
030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
|
||||||
030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
0500000047532067616d657061640000,GS Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
030000008a2e0000dd10000011010000,Hand Held Legend GC Ultimate,a:b0,b:b2,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,misc2:b24,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b1,y:b3,platform:Linux,
|
030000008a2e0000dd10000011010000,Hand Held Legend GC Ultimate,a:b0,b:b2,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,misc2:b24,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b1,y:b3,platform:Linux,
|
||||||
030000008a2e0000df10000011010000,Hand Held Legend ProGCC,a:b1,b:b0,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b3,y:b2,platform:Linux,
|
030000008a2e0000df10000011010000,Hand Held Legend ProGCC,a:b1,b:b0,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b3,y:b2,platform:Linux,
|
||||||
@@ -1382,14 +1406,19 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000000d0f0000ab01000011010000,Horipad Steam,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc2:b2,paddle1:b19,paddle2:b18,paddle3:b15,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
030000000d0f0000ab01000011010000,Horipad Steam,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc2:b2,paddle1:b19,paddle2:b18,paddle3:b15,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
050000000d0f00009601000091000000,Horipad Steam,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc2:b2,paddle1:b19,paddle2:b18,paddle3:b15,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
050000000d0f00009601000091000000,Horipad Steam,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc2:b2,paddle1:b19,paddle2:b18,paddle3:b15,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
050000000d0f0000f600000001000000,Horipad Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
03000000341a000005f7000010010000,HuiJia GameCube Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
05000000242e00000b20000001000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Linux,
|
05000000242e00000b20000001000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Linux,
|
||||||
03000000242e0000ff0b000011010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Linux,
|
03000000242e0000ff0b000011010000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Linux,
|
||||||
03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Linux,
|
03000000242e00006a38000010010000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Linux,
|
||||||
03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000f00300008d03000011010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000f00300008d03000011010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000f00300008d04000000010000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000830500006020000010010000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
03000000830500006020000010010000,iBuffalo Super Famicom Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||||
|
03000000d80400004aea000011010000,icedragon.io STAC Dance Pad,a:b0,b:b1,back:b4,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000d80400004bea000011010000,icedragon.io STAC Dance Pad,a:b0,b:b1,back:b4,x:b2,y:b3,platform:Linux,
|
||||||
|
030000008a2e0000d910000011010000,icedragon.io STAC2 Dance Pad,a:b0,b:b1,back:b4,x:b2,y:b3,platform:Linux,
|
||||||
|
030000008a2e0000e910000011010000,icedragon.io STAC2 Dance Pad,a:b8,b:b9,back:b12,x:b10,y:b11,platform:Linux,
|
||||||
030000008f0e00001330000001010000,iCode Retro Adapter,b:b3,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b1,start:b7,x:b2,y:b0,platform:Linux,
|
030000008f0e00001330000001010000,iCode Retro Adapter,b:b3,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b9,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b1,start:b7,x:b2,y:b0,platform:Linux,
|
||||||
050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||||
@@ -1416,7 +1445,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006d040000d1ca000011010000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006d040000d1ca000011010000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
|
||||||
030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
@@ -1425,8 +1453,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
|
030000006d04000019c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
|
030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
|
||||||
|
030000006d04000011c2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
|
||||||
05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
@@ -1444,7 +1473,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000120c00000500000000010000,Manta DualShock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
03000000120c00000500000000010000,Manta DualShock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
030000008f0e00001330000010010000,Mayflash Controller Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
030000008f0e00001330000010010000,Mayflash Adapter,a:b1,b:b2,back:b8,dpdown:h0.8,dpleft:h0.2,dpright:h0.1,dpup:h0.4,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3~,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
|
03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
|
||||||
@@ -1475,6 +1504,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000005e040000ea02000008040000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000ea02000008040000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000ea0200000f050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000ea0200000f050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
060000005e040000120b000014050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000000b000007040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000000b000007040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b12,paddle2:b14,paddle3:b13,paddle4:b15,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
@@ -1498,20 +1528,21 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
||||||
030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000f70600000100000000010000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Linux,
|
03000000f70600000100000000010000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Linux,
|
||||||
030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000006b1400000906000014010000,Nacon Asymmetric PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
0300000085320000030c000011010000,Nacon GC100,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000853200000706000012010000,Nacon GC100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
05000000853200000503000000010000,Nacon MG-X Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
030000006b140000010c000010010000,Nacon GC400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000853200000503000000010000,Nacon MGX Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
0300000085320000170d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
0300000085320000170d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||||
0300000085320000190d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
0300000085320000190d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||||
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux,
|
0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
03000000790000004518000010010000,NEXiLUX GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux,
|
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
|
03000000790000004618000010010000,Nintendo GameCube Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux,
|
03000000ec110000e1a7000010010000,Nintendo Switch,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
030000007e0500006920000011010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Linux,
|
030000007e0500006920000011010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
060000004e696e74656e646f20537700,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
060000004e696e74656e646f20537700,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||||
060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||||
@@ -1526,7 +1557,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
050000005a1d00000218000003000000,Nokia GC 5000,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
050000005a1d00000218000003000000,Nokia GC 5000,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
|
|
||||||
030000007e0500007320000011010000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Linux,
|
030000007e0500007320000011010000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Linux,
|
||||||
030000007e0500001920000011810000,NSO N64 Controller,+rightx:b2,+righty:b3,-rightx:b4,-righty:b10,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b7,righttrigger:b9,start:b11,platform:Linux,
|
030000007e0500001920000011810000,NSO N64 Controller,+rightx:b2,+righty:b3,-rightx:b4,-righty:b10,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b7,righttrigger:b9,start:b11,platform:Linux,
|
||||||
050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
|
050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux,
|
||||||
@@ -1538,8 +1568,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000550900001472000011010000,NVIDIA Controller,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b8,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
|
03000000550900001472000011010000,NVIDIA Controller,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b8,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
05000000550900001472000001000000,NVIDIA Controller,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b8,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
|
05000000550900001472000001000000,NVIDIA Controller,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b8,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
030000004b120000014d000000010000,NYKO Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
030000004b120000014d000000010000,Nyko Airflo EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
03000000451300000830000010010000,Nyko CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
|
19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
|
||||||
19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
|
19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
|
||||||
05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
|
05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
|
||||||
@@ -1584,8 +1614,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000d62000000b20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000d62000000b20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000250900000017000010010000,PS/SS/N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b5,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2~,righty:a3,start:b8,platform:Linux,
|
03000000250900000017000010010000,PS SS N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b5,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2~,righty:a3,start:b8,platform:Linux,
|
||||||
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000120c0000160e000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||||
030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
@@ -1635,11 +1666,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||||
030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
|
030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
|
||||||
030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,
|
030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux,
|
||||||
0300132d9b2800006500000000000000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
030000009b2800006500000000000000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||||
0300132d9b2800006500000001010000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
030000009b2800006500000001010000,Raphnet GameCube Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||||
|
03000000401700007f05000001010000,Raphnet GC and N64 Adapter,a:b5,b:b3,back:b8,dpdown:b10,dpleft:b12,dpright:b11,dpup:b9,leftshoulder:b6,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:-a5,rightx:a2,righty:a3,start:b1,x:b4,y:b2,platform:Linux,
|
||||||
030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||||
030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||||
|
030000009b2800003c00000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
|
||||||
030000009b2800006100000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
|
030000009b2800006100000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
|
||||||
|
030000009b2800006300000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
|
||||||
030000009b2800006400000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
|
030000009b2800006400000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux,
|
||||||
030000009b2800008000000020020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
|
030000009b2800008000000020020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
|
||||||
030000009b2800008000000001010000,Raphnet Wii Classic Adapter V3,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
|
030000009b2800008000000001010000,Raphnet Wii Classic Adapter V3,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux,
|
||||||
@@ -1661,7 +1695,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000321500000b10000011010000,Razer Wolverine PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
03000000321500000b10000011010000,Razer Wolverine PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||||
0300000032150000140a000001010000,Razer Wolverine Ultimate Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
0300000032150000140a000001010000,Razer Wolverine Ultimate Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000000d0f0000c100000010010000,Retro Bit Legacy16,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b12,leftshoulder:b4,lefttrigger:b6,misc1:b13,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
030000000d0f0000c100000010010000,Retro Bit Legacy16,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b12,leftshoulder:b4,lefttrigger:b6,misc1:b13,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000000d0f0000c100000072056800,Retro Bit Legacy16,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b5,leftshoulder:b9,lefttrigger:+a4,misc1:b11,rightshoulder:b10,righttrigger:+a5,start:b6,x:b3,y:b2,platform:Linux,
|
|
||||||
03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux,
|
03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
0300000003040000c197000011010000,Retrode Adapter,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
|
0300000003040000c197000011010000,Retrode Adapter,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
|
||||||
190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
@@ -1695,36 +1728,23 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000952e00004e43000011010000,Scuf Envision,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,
|
03000000952e00004e43000011010000,Scuf Envision,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,
|
03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux,
|
||||||
03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux,
|
03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
|
|
||||||
03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,
|
03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux,
|
||||||
03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000632500002605000010010000,Shanwan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000632500002605000010010000,ShanWan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000632500007505000010010000,Shanwan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
03000000632500007505000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000bc2000000055000010010000,Shanwan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000bc2000000055000010010000,ShanWan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
|
||||||
03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000250900000500000000010000,SmartJoy PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
||||||
030000004b2900000430000011000000,Snakebyte Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000004b2900000430000011000000,Snakebyte Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000790000002601000011010000,SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||||
03000000666600006706000000010000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
|
03000000666600006706000000010000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000d9040000160f000000010000,Sony PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
030000004c050000da0c000011010000,Sony PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
030000004c050000da0c000011010000,Sony PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000d9040000160f000000010000,Sony PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
|
||||||
03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
|
03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000004c0500003713000011010000,Sony PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
030000004c0500003713000011010000,Sony PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
|
||||||
030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
|
||||||
03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
|
||||||
03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
|
||||||
03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
03000000de2800000512000010010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux,
|
|
||||||
03000000de2800000512000011010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux,
|
|
||||||
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux,
|
050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux,
|
||||||
03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
@@ -1742,7 +1762,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000e40a00000307000011010000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
|
03000000e40a00000307000011010000,Taito Egret II Mini Control Panel,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
|
||||||
03000000e40a00000207000011010000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
|
03000000e40a00000207000011010000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,guide:b9,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Linux,
|
||||||
03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
|
03000000ba2200000701000001010000,Technology Innovation PlayStation Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
|
03000000591c00002400000010010000,THEC64 Joystick,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000591c00002600000010010000,THEGamepad,a:b2,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
|
03000000591c00002600000010010000,THEGamepad,a:b2,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
|
||||||
@@ -1772,11 +1792,24 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,
|
03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux,
|
||||||
030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
06000000f51000000870000003010000,Turtle Beach Recon,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
06000000f51000000870000003010000,Turtle Beach Recon,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
03000000100800000100000010010000,Twin PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000c0160000e105000010010000,Ultimate Atari Fight Stick,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,platform:Linux,
|
||||||
03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
03000000151900005678000010010000,Uniplay U6,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
|
03000000790000000600000007010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
|
03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
|
||||||
|
03000000de2800000112000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800000112000011010000,Valve Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
||||||
|
03000000de2800000211000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800000211000011010000,Valve Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
||||||
|
03000000de2800004211000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800004211000011010000,Valve Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
||||||
|
03000000de280000fc11000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000de2800000212000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000de2800000511000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000de2800000611000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800000512000010010000,Valve Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux,
|
||||||
|
03000000de2800000512000011010000,Valve Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux,
|
||||||
03000000790000001a18000011010000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
03000000790000001a18000011010000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000790000001b18000011010000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
03000000790000001b18000011010000,Venom PS4 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux,
|
||||||
@@ -1785,24 +1818,30 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
05000000434f4d4d414e440000000000,VX Gaming Command Series,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
05000000434f4d4d414e440000000000,VX Gaming Command Series,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000002010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000047010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000072050000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000a102000030060000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000a102000030060000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000006f0e00001503000000020000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000006f0e00001503000000020000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
0000000058626f782047616d65706100,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
0000000058626f782047616d65706100,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||||
030000005e0400008e02000072050000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||||
030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
050000005e040000200b000013050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
050000005e040000200b000017050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
050000005e040000200b000023050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
050000005e040000220b000017050000,Xbox One Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
@@ -1838,12 +1877,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
060000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
060000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
060000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
060000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
060000005e040000120b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
|
||||||
050000005e040000130b000022050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
050000005e040000130b000022050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
060000005e040000120b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
050000005e040000200b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
|
||||||
050000005e040000200b000023050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
|
||||||
050000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
|
||||||
03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
|
05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
|
03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
|
||||||
@@ -1852,6 +1887,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
03000000120c0000182e000011010000,Zeroplus PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
03000000120c0000182e000011010000,Zeroplus PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000790000002201000011010000,ZhiXu GuliKit D,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
|
||||||
# Android
|
# Android
|
||||||
38653964633230666463343334313533,8BitDo Adapter,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
38653964633230666463343334313533,8BitDo Adapter,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
@@ -1962,7 +1998,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
65656436646661313232656661616130,Hori PC Engine Mini Controller,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,start:b18,platform:Android,
|
65656436646661313232656661616130,Hori PC Engine Mini Controller,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,start:b18,platform:Android,
|
||||||
31303433326562636431653534636633,Hori Real Arcade Pro 3,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
|
31303433326562636431653534636633,Hori Real Arcade Pro 3,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
|
||||||
32656664353964393561366362333636,Hori Switch Split Pad Pro,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
|
32656664353964393561366362333636,Hori Switch Split Pad Pro,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
|
||||||
30306539356238653637313730656134,HORIPAD Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
|
30306539356238653637313730656134,Horipad Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
|
||||||
48797065726b696e2050616400000000,Hyperkin Admiral N64 Controller,+rightx:b6,+righty:b7,-rightx:b17,-righty:b5,a:b1,b:b0,leftshoulder:b3,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b20,start:b18,platform:Android,
|
48797065726b696e2050616400000000,Hyperkin Admiral N64 Controller,+rightx:b6,+righty:b7,-rightx:b17,-righty:b5,a:b1,b:b0,leftshoulder:b3,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b20,start:b18,platform:Android,
|
||||||
62333331353131353034386136626636,Hyperkin Admiral N64 Controller,+rightx:b6,+righty:b7,-rightx:b17,-righty:b5,a:b1,b:b0,leftshoulder:b3,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b20,start:b18,platform:Android,
|
62333331353131353034386136626636,Hyperkin Admiral N64 Controller,+rightx:b6,+righty:b7,-rightx:b17,-righty:b5,a:b1,b:b0,leftshoulder:b3,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b20,start:b18,platform:Android,
|
||||||
31306635363562663834633739396333,Hyperkin N64 Adapter,a:b1,b:b19,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a2,righty:a3,start:b18,platform:Android,
|
31306635363562663834633739396333,Hyperkin N64 Adapter,a:b1,b:b19,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a2,righty:a3,start:b18,platform:Android,
|
||||||
@@ -1986,6 +2022,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
4c6f6769746563682047616d65706164,Logitech F710,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
4c6f6769746563682047616d65706164,Logitech F710,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
64396331333230326333313330336533,Logitech F710,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
64396331333230326333313330336533,Logitech F710,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
39653365373864633935383236363438,Logitech G Cloud,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
39653365373864633935383236363438,Logitech G Cloud,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
33373336396634316434323337666361,Logitech RumblePad 2,a:b22,b:b23,back:b29,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b24,platform:Android,
|
||||||
416d617a6f6e2047616d6520436f6e74,Luna Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
|
416d617a6f6e2047616d6520436f6e74,Luna Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
|
||||||
4c756e612047616d6570616400000000,Luna Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
4c756e612047616d6570616400000000,Luna Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
30363066623539323534363639323363,Magic NS,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
|
30363066623539323534363639323363,Magic NS,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
|
||||||
@@ -2029,7 +2066,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
4f5559412047616d6520436f6e74726f,OUYA Controller,a:b0,b:b2,dpdown:b18,dpleft:b15,dpright:b6,dpup:b17,leftshoulder:b3,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b19,platform:Android,
|
4f5559412047616d6520436f6e74726f,OUYA Controller,a:b0,b:b2,dpdown:b18,dpleft:b15,dpright:b6,dpup:b17,leftshoulder:b3,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b19,platform:Android,
|
||||||
506572666f726d616e63652044657369,PDP PS3 Rock Candy Controller,a:b1,b:b17,back:h0.2,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b0,y:b2,platform:Android,
|
506572666f726d616e63652044657369,PDP PS3 Rock Candy Controller,a:b1,b:b17,back:h0.2,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b0,y:b2,platform:Android,
|
||||||
61653962353232366130326530363061,Pokken,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,rightshoulder:b20,righttrigger:b10,start:b18,x:b0,y:b2,platform:Android,
|
61653962353232366130326530363061,Pokken,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,rightshoulder:b20,righttrigger:b10,start:b18,x:b0,y:b2,platform:Android,
|
||||||
32666633663735353234363064386132,PS2,a:b23,b:b22,back:b29,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a3,righty:a2,start:b30,x:b24,y:b21,platform:Android,
|
32666633663735353234363064386132,PS2 Controller,a:b23,b:b22,back:b29,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a3,righty:a2,start:b30,x:b24,y:b21,platform:Android,
|
||||||
050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
536f6e7920504c415953544154494f4e,PS3 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
536f6e7920504c415953544154494f4e,PS3 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
61363034663839376638653463633865,PS3 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
61363034663839376638653463633865,PS3 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
@@ -2083,7 +2120,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
526574726f5553422e636f6d20534e45,RetroUSB SNES RetroPort,a:b1,b:b20,back:b19,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b2,x:b0,y:b3,platform:Android,
|
526574726f5553422e636f6d20534e45,RetroUSB SNES RetroPort,a:b1,b:b20,back:b19,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b2,x:b0,y:b3,platform:Android,
|
||||||
64643037633038386238303966376137,RetroUSB SNES RetroPort,a:b1,b:b20,back:b19,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b2,x:b0,y:b3,platform:Android,
|
64643037633038386238303966376137,RetroUSB SNES RetroPort,a:b1,b:b20,back:b19,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b9,rightshoulder:b10,start:b2,x:b0,y:b3,platform:Android,
|
||||||
37656564346533643138636436356230,Rock Candy Switch Controller,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,misc1:b7,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
|
37656564346533643138636436356230,Rock Candy Switch Controller,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,misc1:b7,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android,
|
||||||
33373336396634316434323337666361,RumblePad 2,a:b22,b:b23,back:b29,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b25,lefttrigger:b27,leftx:a0,lefty:a1,rightshoulder:b26,righttrigger:b28,rightx:a2,righty:a3,start:b30,x:b21,y:b24,platform:Android,
|
|
||||||
36363537303435333566386638366333,Samsung EIGP20,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
36363537303435333566386638366333,Samsung EIGP20,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
53616d73756e672047616d6520506164,Samsung EIGP20,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
53616d73756e672047616d6520506164,Samsung EIGP20,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
66386565396238363534313863353065,Sanwa PlayOnline Mobile,a:b21,b:b22,back:b23,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b24,platform:Android,
|
66386565396238363534313863353065,Sanwa PlayOnline Mobile,a:b21,b:b22,back:b23,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b24,platform:Android,
|
||||||
@@ -2102,8 +2138,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
576972656c65737320436f6e74726f6c,Sony PlayStation Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
576972656c65737320436f6e74726f6c,Sony PlayStation Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
63303964303462366136616266653561,Sony PSP,a:b21,b:b22,back:b27,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b28,x:b23,y:b24,platform:Android,
|
63303964303462366136616266653561,Sony PSP,a:b21,b:b22,back:b27,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b28,x:b23,y:b24,platform:Android,
|
||||||
63376637643462343766333462383235,Sony Vita,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a3,righty:a4,start:b18,x:b0,y:b2,platform:Android,
|
63376637643462343766333462383235,Sony Vita,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftx:a0,lefty:a1,rightshoulder:b20,rightx:a3,righty:a4,start:b18,x:b0,y:b2,platform:Android,
|
||||||
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
|
|
||||||
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
|
|
||||||
0500000011010000201400000f7e0f00,SteelSeries Nimbus,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,x:b19,y:b2,platform:Android,
|
0500000011010000201400000f7e0f00,SteelSeries Nimbus,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,righttrigger:b10,rightx:a2,righty:a3,x:b19,y:b2,platform:Android,
|
||||||
35306436396437373135383665646464,SteelSeries Nimbus Plus,a:b0,b:b1,leftshoulder:b3,leftstick:b17,lefttrigger:b9,leftx:a0,rightshoulder:b20,rightstick:b18,righttrigger:b10,rightx:a2,x:b19,y:b2,platform:Android,
|
35306436396437373135383665646464,SteelSeries Nimbus Plus,a:b0,b:b1,leftshoulder:b3,leftstick:b17,lefttrigger:b9,leftx:a0,rightshoulder:b20,rightstick:b18,righttrigger:b10,rightx:a2,x:b19,y:b2,platform:Android,
|
||||||
33313930373536613937326534303931,Taito Egret II Mini Control Panel,a:b25,b:b23,back:b27,guide:b30,leftx:a0,lefty:a1,rightshoulder:b21,righttrigger:b22,start:b28,x:b29,y:b24,platform:Android,
|
33313930373536613937326534303931,Taito Egret II Mini Control Panel,a:b25,b:b23,back:b27,guide:b30,leftx:a0,lefty:a1,rightshoulder:b21,righttrigger:b22,start:b28,x:b29,y:b24,platform:Android,
|
||||||
@@ -2113,6 +2147,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
38346162326232346533316164363336,THEGamepad,a:b23,b:b22,back:b27,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b28,x:b24,y:b21,platform:Android,
|
38346162326232346533316164363336,THEGamepad,a:b23,b:b22,back:b27,leftshoulder:b25,leftx:a0,lefty:a1,rightshoulder:b26,start:b28,x:b24,y:b21,platform:Android,
|
||||||
050000004f0400000ed00000fffe3f00,Thrustmaster eSwap Pro Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
050000004f0400000ed00000fffe3f00,Thrustmaster eSwap Pro Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
5477696e20555342204a6f7973746963,Twin Joystick,a:b22,b:b21,back:b28,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,
|
5477696e20555342204a6f7973746963,Twin Joystick,a:b22,b:b21,back:b28,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,
|
||||||
|
05000000de2800000511000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
|
||||||
|
05000000de2800000611000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
|
||||||
30623739343039643830333266346439,Valve Steam Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,paddle1:b24,paddle2:b23,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
30623739343039643830333266346439,Valve Steam Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,paddle1:b24,paddle2:b23,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
31643365666432386133346639383937,Valve Steam Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,paddle1:b24,paddle2:b23,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
31643365666432386133346639383937,Valve Steam Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,paddle1:b24,paddle2:b23,rightshoulder:b10,rightstick:b8,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
30386438313564306161393537333663,Wii Classic Adapter,a:b23,b:b22,back:b29,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android,
|
30386438313564306161393537333663,Wii Classic Adapter,a:b23,b:b22,back:b29,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a2,righty:a3,start:b30,x:b24,y:b21,platform:Android,
|
||||||
@@ -2146,8 +2182,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
050000005e040000ea02000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
050000005e040000ea02000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
050000005e040000120b000000783f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
|
050000005e040000120b000000783f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
|
||||||
050000005e040000120b000000783f80,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
050000005e040000120b000000783f80,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
65633038363832353634653836396239,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
65633038363832353634653836396239,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
050000001727000044310000ffff3f00,XiaoMi Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
|
050000001727000044310000ffff3f00,XiaoMi Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
|
||||||
@@ -2175,6 +2211,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,platform:iOS,
|
050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,platform:iOS,
|
||||||
050000007e05000009200000df870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:iOS,
|
050000007e05000009200000df870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:iOS,
|
||||||
050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:iOS,
|
050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:iOS,
|
||||||
|
05000000ac050000040000008e586d04,PlayStation VR2 Sense Controller (L),+leftx:+a3,+lefty:+a1,-leftx:+a2,-lefty:+a4,back:b2,leftstick:b4,lefttrigger:+a7,paddle2:b3,x:b0,y:b1,platform:iOS,
|
||||||
|
05000000ac050000040000000eb86d04,PlayStation VR2 Sense Controller (R),+rightx:+a3,+righty:+a1,-rightx:+a2,-righty:+a4,a:b0,b:b1,paddle1:b3,rightstick:b4,righttrigger:+a7,start:b2,platform:iOS,
|
||||||
050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
||||||
@@ -2184,11 +2222,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
|||||||
050000004c050000e60c0000ff870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS,
|
050000004c050000e60c0000ff870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS,
|
||||||
05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
|
05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
|
||||||
05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
|
05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
|
||||||
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
|
05000000de2800000511000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
|
||||||
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
|
05000000de2800000611000001000000,Valve Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
|
||||||
050000005e040000050b0000df070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
050000005e040000050b0000df070001,Xbox Elite Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
050000005e040000050b0000ff070001,Xbox Elite Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
||||||
|
050000005e040000e0020000df070000,Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
|
050000005e040000e0020000ff070000,Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
||||||
050000005e040000130b0000df870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
050000005e040000130b0000df870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
050000005e040000130b0000ff870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
050000005e040000130b0000ff870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
||||||
050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
|
||||||
050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
#include "audio.hpp"
|
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_G...
|
|
||||||
|
|
||||||
#include <algorithm> // Para clamp
|
|
||||||
#include <iostream> // Para std::cout
|
|
||||||
|
|
||||||
// Implementación de stb_vorbis (debe estar ANTES de incluir jail_audio.hpp).
|
|
||||||
// clang-format off
|
|
||||||
#undef STB_VORBIS_HEADER_ONLY
|
|
||||||
#include "external/stb_vorbis.h"
|
|
||||||
// stb_vorbis.h filtra les macros L, C i R (i PLAYBACK_*) al TU. Les netegem
|
|
||||||
// perquè xocarien amb noms de paràmetres de plantilla en json.hpp i altres.
|
|
||||||
#undef L
|
|
||||||
#undef C
|
|
||||||
#undef R
|
|
||||||
#undef PLAYBACK_MONO
|
|
||||||
#undef PLAYBACK_LEFT
|
|
||||||
#undef PLAYBACK_RIGHT
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "external/jail_audio.hpp" // Para JA_FadeOutMusic, JA_Init, JA_PauseM...
|
|
||||||
#include "options.hpp" // Para AudioOptions, audio, MusicOptions
|
|
||||||
#include "resource.hpp" // Para Resource
|
|
||||||
|
|
||||||
// Singleton
|
|
||||||
Audio* Audio::instance = nullptr;
|
|
||||||
|
|
||||||
// Inicializa la instancia única del singleton
|
|
||||||
void Audio::init() { Audio::instance = new Audio(); }
|
|
||||||
|
|
||||||
// Libera la instancia
|
|
||||||
void Audio::destroy() { delete Audio::instance; }
|
|
||||||
|
|
||||||
// Obtiene la instancia
|
|
||||||
auto Audio::get() -> Audio* { return Audio::instance; }
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
Audio::Audio() { initSDLAudio(); }
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
Audio::~Audio() {
|
|
||||||
JA_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Método principal
|
|
||||||
void Audio::update() {
|
|
||||||
JA_Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reproduce la música
|
|
||||||
void Audio::playMusic(const std::string& name, const int loop) {
|
|
||||||
music_.name = name;
|
|
||||||
music_.loop = (loop != 0);
|
|
||||||
|
|
||||||
if (music_enabled_ && music_.state != MusicState::PLAYING) {
|
|
||||||
JA_PlayMusic(Resource::get()->getMusic(name), loop);
|
|
||||||
music_.state = MusicState::PLAYING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pausa la música
|
|
||||||
void Audio::pauseMusic() {
|
|
||||||
if (music_enabled_ && music_.state == MusicState::PLAYING) {
|
|
||||||
JA_PauseMusic();
|
|
||||||
music_.state = MusicState::PAUSED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continua la música pausada
|
|
||||||
void Audio::resumeMusic() {
|
|
||||||
if (music_enabled_ && music_.state == MusicState::PAUSED) {
|
|
||||||
JA_ResumeMusic();
|
|
||||||
music_.state = MusicState::PLAYING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detiene la música
|
|
||||||
void Audio::stopMusic() {
|
|
||||||
if (music_enabled_) {
|
|
||||||
JA_StopMusic();
|
|
||||||
music_.state = MusicState::STOPPED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reproduce un sonido
|
|
||||||
void Audio::playSound(const std::string& name, Group group) const {
|
|
||||||
if (sound_enabled_) {
|
|
||||||
JA_PlaySound(Resource::get()->getSound(name), 0, static_cast<int>(group));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detiene todos los sonidos
|
|
||||||
void Audio::stopAllSounds() const {
|
|
||||||
if (sound_enabled_) {
|
|
||||||
JA_StopChannel(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Realiza un fundido de salida de la música
|
|
||||||
void Audio::fadeOutMusic(int milliseconds) const {
|
|
||||||
if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) {
|
|
||||||
JA_FadeOutMusic(milliseconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consulta directamente el estado real de la música en jailaudio
|
|
||||||
auto Audio::getRealMusicState() -> MusicState {
|
|
||||||
JA_Music_state ja_state = JA_GetMusicState();
|
|
||||||
switch (ja_state) {
|
|
||||||
case JA_MUSIC_PLAYING:
|
|
||||||
return MusicState::PLAYING;
|
|
||||||
case JA_MUSIC_PAUSED:
|
|
||||||
return MusicState::PAUSED;
|
|
||||||
case JA_MUSIC_STOPPED:
|
|
||||||
case JA_MUSIC_INVALID:
|
|
||||||
case JA_MUSIC_DISABLED:
|
|
||||||
default:
|
|
||||||
return MusicState::STOPPED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el volumen de los sonidos
|
|
||||||
void Audio::setSoundVolume(int sound_volume, Group group) const {
|
|
||||||
if (sound_enabled_) {
|
|
||||||
sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME);
|
|
||||||
const float CONVERTED_VOLUME = (sound_volume / 100.0F) * (Options::audio.volume / 100.0F);
|
|
||||||
JA_SetSoundVolume(CONVERTED_VOLUME, static_cast<int>(group));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece el volumen de la música
|
|
||||||
void Audio::setMusicVolume(int music_volume) const {
|
|
||||||
if (music_enabled_) {
|
|
||||||
music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME);
|
|
||||||
const float CONVERTED_VOLUME = (music_volume / 100.0F) * (Options::audio.volume / 100.0F);
|
|
||||||
JA_SetMusicVolume(CONVERTED_VOLUME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aplica la configuración
|
|
||||||
void Audio::applySettings() {
|
|
||||||
enable(Options::audio.enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establecer estado general
|
|
||||||
void Audio::enable(bool value) {
|
|
||||||
enabled_ = value;
|
|
||||||
|
|
||||||
setSoundVolume(enabled_ ? Options::audio.sound.volume : MIN_VOLUME);
|
|
||||||
setMusicVolume(enabled_ ? Options::audio.music.volume : MIN_VOLUME);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa SDL Audio
|
|
||||||
void Audio::initSDLAudio() {
|
|
||||||
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
|
||||||
std::cout << "SDL_AUDIO could not initialize! SDL Error: " << SDL_GetError() << '\n';
|
|
||||||
} else {
|
|
||||||
JA_Init(FREQUENCY, SDL_AUDIO_S16LE, 2);
|
|
||||||
enable(Options::audio.enabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string> // Para string
|
|
||||||
#include <utility> // Para move
|
|
||||||
|
|
||||||
// --- Clase Audio: gestor de audio (singleton) ---
|
|
||||||
class Audio {
|
|
||||||
public:
|
|
||||||
// --- Enums ---
|
|
||||||
enum class Group : int {
|
|
||||||
ALL = -1, // Todos los grupos
|
|
||||||
GAME = 0, // Sonidos del juego
|
|
||||||
INTERFACE = 1 // Sonidos de la interfaz
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class MusicState {
|
|
||||||
PLAYING, // Reproduciendo música
|
|
||||||
PAUSED, // Música pausada
|
|
||||||
STOPPED, // Música detenida
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- Constantes ---
|
|
||||||
static constexpr int MAX_VOLUME = 100; // Volumen máximo
|
|
||||||
static constexpr int MIN_VOLUME = 0; // Volumen mínimo
|
|
||||||
static constexpr int FREQUENCY = 48000; // Frecuencia de audio
|
|
||||||
|
|
||||||
// --- Métodos de singleton ---
|
|
||||||
static void init(); // Inicializa el objeto Audio
|
|
||||||
static void destroy(); // Libera el objeto Audio
|
|
||||||
static auto get() -> Audio*; // Obtiene el puntero al objeto Audio
|
|
||||||
Audio(const Audio&) = delete; // Evitar copia
|
|
||||||
auto operator=(const Audio&) -> Audio& = delete; // Evitar asignación
|
|
||||||
|
|
||||||
// --- Método principal ---
|
|
||||||
static void update();
|
|
||||||
|
|
||||||
// --- Control de Música ---
|
|
||||||
void playMusic(const std::string& name, int loop = -1); // Reproducir música en bucle
|
|
||||||
void pauseMusic(); // Pausar reproducción de música
|
|
||||||
void resumeMusic(); // Continua la música pausada
|
|
||||||
void stopMusic(); // Detener completamente la música
|
|
||||||
void fadeOutMusic(int milliseconds) const; // Fundido de salida de la música
|
|
||||||
|
|
||||||
// --- Control de Sonidos ---
|
|
||||||
void playSound(const std::string& name, Group group = Group::GAME) const; // Reproducir sonido puntual
|
|
||||||
void stopAllSounds() const; // Detener todos los sonidos
|
|
||||||
|
|
||||||
// --- Configuración General ---
|
|
||||||
void enable(bool value); // Establecer estado general
|
|
||||||
void toggleEnabled() { enabled_ = !enabled_; } // Alternar estado general
|
|
||||||
void applySettings(); // Aplica la configuración
|
|
||||||
|
|
||||||
// --- Configuración de Sonidos ---
|
|
||||||
void enableSound() { sound_enabled_ = true; } // Habilitar sonidos
|
|
||||||
void disableSound() { sound_enabled_ = false; } // Deshabilitar sonidos
|
|
||||||
void enableSound(bool value) { sound_enabled_ = value; } // Establecer estado de sonidos
|
|
||||||
void toggleSound() { sound_enabled_ = !sound_enabled_; } // Alternar estado de sonidos
|
|
||||||
|
|
||||||
// --- Configuración de Música ---
|
|
||||||
void enableMusic() { music_enabled_ = true; } // Habilitar música
|
|
||||||
void disableMusic() { music_enabled_ = false; } // Deshabilitar música
|
|
||||||
void enableMusic(bool value) { music_enabled_ = value; } // Establecer estado de música
|
|
||||||
void toggleMusic() { music_enabled_ = !music_enabled_; } // Alternar estado de música
|
|
||||||
|
|
||||||
// --- Control de Volumen ---
|
|
||||||
void setSoundVolume(int volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
|
||||||
void setMusicVolume(int volume) const; // Ajustar volumen de música
|
|
||||||
|
|
||||||
// --- Getters para debug ---
|
|
||||||
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
|
|
||||||
[[nodiscard]] auto isSoundEnabled() const -> bool { return sound_enabled_; }
|
|
||||||
[[nodiscard]] auto isMusicEnabled() const -> bool { return music_enabled_; }
|
|
||||||
[[nodiscard]] auto getMusicState() const -> MusicState { return music_.state; }
|
|
||||||
[[nodiscard]] static auto getRealMusicState() -> MusicState; // Consulta directamente a jailaudio
|
|
||||||
[[nodiscard]] auto getCurrentMusicName() const -> const std::string& { return music_.name; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// --- Estructuras privadas ---
|
|
||||||
struct Music {
|
|
||||||
MusicState state; // Estado actual de la música (reproduciendo, detenido, en pausa)
|
|
||||||
std::string name; // Última pista de música reproducida
|
|
||||||
bool loop; // Indica si la última pista de música se debe reproducir en bucle
|
|
||||||
|
|
||||||
// Constructor para inicializar la música con valores predeterminados
|
|
||||||
Music()
|
|
||||||
: state(MusicState::STOPPED),
|
|
||||||
loop(false) {}
|
|
||||||
|
|
||||||
// Constructor para inicializar con valores específicos
|
|
||||||
Music(MusicState init_state, std::string init_name, bool init_loop)
|
|
||||||
: state(init_state),
|
|
||||||
name(std::move(init_name)),
|
|
||||||
loop(init_loop) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- Variables de estado ---
|
|
||||||
Music music_; // Estado de la música
|
|
||||||
bool enabled_ = true; // Estado general del audio
|
|
||||||
bool sound_enabled_ = true; // Estado de los efectos de sonido
|
|
||||||
bool music_enabled_ = true; // Estado de la música
|
|
||||||
|
|
||||||
// --- Métodos internos ---
|
|
||||||
void initSDLAudio(); // Inicializa SDL Audio
|
|
||||||
|
|
||||||
// --- Constructores y destructor privados (singleton) ---
|
|
||||||
Audio(); // Constructor privado
|
|
||||||
~Audio(); // Destructor privado
|
|
||||||
|
|
||||||
// --- Instancia singleton ---
|
|
||||||
static Audio* instance; // Instancia única de Audio
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
#include "core/audio/audio.hpp"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h> // Para SDL_GetError, SDL_Init
|
||||||
|
|
||||||
|
#include <algorithm> // Para clamp
|
||||||
|
#include <iostream> // Para std::cout
|
||||||
|
|
||||||
|
// Implementación de stb_vorbis (debe estar ANTES de incluir jail_audio.hpp).
|
||||||
|
// clang-format off
|
||||||
|
#undef STB_VORBIS_HEADER_ONLY
|
||||||
|
// stb_vorbis.c (codi de tercers) dispara -Wtautological-compare; el silenciem
|
||||||
|
// només per a aquesta inclusió sense afectar el nostre codi.
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wtautological-compare"
|
||||||
|
// NOLINTNEXTLINE(bugprone-suspicious-include) — stb_vorbis és single-file: el TU principal inclou el .c per portar la implementació.
|
||||||
|
#include "external/stb_vorbis.c"
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
// stb_vorbis.c filtra les macros L, C i R (i PLAYBACK_*) al TU. Les netegem
|
||||||
|
// perquè xocarien amb noms de paràmetres de plantilla en altres headers.
|
||||||
|
#undef L
|
||||||
|
#undef C
|
||||||
|
#undef R
|
||||||
|
#undef PLAYBACK_MONO
|
||||||
|
#undef PLAYBACK_LEFT
|
||||||
|
#undef PLAYBACK_RIGHT
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#include "core/audio/audio_adapter.hpp" // Para AudioResource::getMusic/getSound
|
||||||
|
#include "core/audio/jail_audio.hpp" // Para JA_*
|
||||||
|
#include "game/options.hpp" // Para Options::audio
|
||||||
|
|
||||||
|
// Singleton
|
||||||
|
Audio* Audio::instance = nullptr;
|
||||||
|
|
||||||
|
// Inicializa la instancia única del singleton
|
||||||
|
void Audio::init() { Audio::instance = new Audio(); }
|
||||||
|
|
||||||
|
// Libera la instancia
|
||||||
|
void Audio::destroy() {
|
||||||
|
delete Audio::instance;
|
||||||
|
Audio::instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtiene la instancia
|
||||||
|
auto Audio::get() -> Audio* { return Audio::instance; }
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
Audio::Audio() { initSDLAudio(); }
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
Audio::~Audio() {
|
||||||
|
Ja::quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Método principal
|
||||||
|
void Audio::update() {
|
||||||
|
Ja::update();
|
||||||
|
|
||||||
|
// Sincronizar estado: detectar cuando la música se para (ej. fade-out completado)
|
||||||
|
if (instance != nullptr && instance->music_.state == MusicState::PLAYING && Ja::getMusicState() != Ja::MusicState::PLAYING) {
|
||||||
|
instance->music_.state = MusicState::STOPPED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reproduce la música por nombre (con crossfade opcional)
|
||||||
|
void Audio::playMusic(const std::string& name, const int loop, const int crossfade_ms) {
|
||||||
|
bool new_loop = (loop != 0);
|
||||||
|
|
||||||
|
// Si ya está sonando exactamente la misma pista y mismo modo loop, no hacemos nada
|
||||||
|
if (music_.state == MusicState::PLAYING && music_.name == name && music_.loop == new_loop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!music_enabled_) { return; }
|
||||||
|
|
||||||
|
auto* resource = AudioResource::getMusic(name);
|
||||||
|
if (resource == nullptr) { return; }
|
||||||
|
|
||||||
|
if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) {
|
||||||
|
Ja::crossfadeMusic(resource, crossfade_ms, loop);
|
||||||
|
} else {
|
||||||
|
if (music_.state == MusicState::PLAYING) {
|
||||||
|
Ja::stopMusic();
|
||||||
|
}
|
||||||
|
Ja::playMusic(resource, loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
music_.name = name;
|
||||||
|
music_.loop = new_loop;
|
||||||
|
music_.state = MusicState::PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reproduce la música por puntero (con crossfade opcional)
|
||||||
|
void Audio::playMusic(Ja::Music* music, const int loop, const int crossfade_ms) {
|
||||||
|
if (!music_enabled_ || music == nullptr) { return; }
|
||||||
|
|
||||||
|
if (crossfade_ms > 0 && music_.state == MusicState::PLAYING) {
|
||||||
|
Ja::crossfadeMusic(music, crossfade_ms, loop);
|
||||||
|
} else {
|
||||||
|
if (music_.state == MusicState::PLAYING) {
|
||||||
|
Ja::stopMusic();
|
||||||
|
}
|
||||||
|
Ja::playMusic(music, loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
music_.name.clear(); // nom desconegut quan es passa per punter
|
||||||
|
music_.loop = (loop != 0);
|
||||||
|
music_.state = MusicState::PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pausa la música
|
||||||
|
void Audio::pauseMusic() {
|
||||||
|
if (music_enabled_ && music_.state == MusicState::PLAYING) {
|
||||||
|
Ja::pauseMusic();
|
||||||
|
music_.state = MusicState::PAUSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continua la música pausada
|
||||||
|
void Audio::resumeMusic() {
|
||||||
|
if (music_enabled_ && music_.state == MusicState::PAUSED) {
|
||||||
|
Ja::resumeMusic();
|
||||||
|
music_.state = MusicState::PLAYING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detiene la música
|
||||||
|
void Audio::stopMusic() {
|
||||||
|
if (music_enabled_) {
|
||||||
|
Ja::stopMusic();
|
||||||
|
music_.state = MusicState::STOPPED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reproduce un sonido por nombre
|
||||||
|
void Audio::playSound(const std::string& name, Group group) const {
|
||||||
|
if (sound_enabled_) {
|
||||||
|
Ja::playSound(AudioResource::getSound(name), 0, static_cast<int>(group));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reproduce un sonido por puntero directo
|
||||||
|
void Audio::playSound(Ja::Sound* sound, Group group) const {
|
||||||
|
if (sound_enabled_ && sound != nullptr) {
|
||||||
|
Ja::playSound(sound, 0, static_cast<int>(group));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detiene todos los sonidos
|
||||||
|
void Audio::stopAllSounds() const {
|
||||||
|
if (sound_enabled_) {
|
||||||
|
Ja::stopChannel(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Realiza un fundido de salida de la música
|
||||||
|
void Audio::fadeOutMusic(int milliseconds) const {
|
||||||
|
if (music_enabled_ && getRealMusicState() == MusicState::PLAYING) {
|
||||||
|
Ja::fadeOutMusic(milliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consulta directamente el estado real de la música en jailaudio
|
||||||
|
auto Audio::getRealMusicState() -> MusicState {
|
||||||
|
Ja::MusicState ja_state = Ja::getMusicState();
|
||||||
|
switch (ja_state) {
|
||||||
|
case Ja::MusicState::PLAYING:
|
||||||
|
return MusicState::PLAYING;
|
||||||
|
case Ja::MusicState::PAUSED:
|
||||||
|
return MusicState::PAUSED;
|
||||||
|
case Ja::MusicState::STOPPED:
|
||||||
|
case Ja::MusicState::INVALID:
|
||||||
|
case Ja::MusicState::DISABLED:
|
||||||
|
default:
|
||||||
|
return MusicState::STOPPED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece el volumen de los sonidos (float 0.0..1.0)
|
||||||
|
void Audio::setSoundVolume(float sound_volume, Group group) const {
|
||||||
|
if (sound_enabled_) {
|
||||||
|
sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME);
|
||||||
|
const float CONVERTED_VOLUME = sound_volume * Options::audio.volume;
|
||||||
|
Ja::setSoundVolume(CONVERTED_VOLUME, static_cast<int>(group));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establece el volumen de la música (float 0.0..1.0)
|
||||||
|
void Audio::setMusicVolume(float music_volume) const {
|
||||||
|
if (music_enabled_) {
|
||||||
|
music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME);
|
||||||
|
const float CONVERTED_VOLUME = music_volume * Options::audio.volume;
|
||||||
|
Ja::setMusicVolume(CONVERTED_VOLUME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplica la configuración
|
||||||
|
void Audio::applySettings() {
|
||||||
|
enable(Options::audio.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Establecer estado general
|
||||||
|
void Audio::enable(bool value) {
|
||||||
|
enabled_ = value;
|
||||||
|
|
||||||
|
setSoundVolume(enabled_ ? Options::audio.sound.volume : MIN_VOLUME);
|
||||||
|
setMusicVolume(enabled_ ? Options::audio.music.volume : MIN_VOLUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicializa SDL Audio
|
||||||
|
void Audio::initSDLAudio() {
|
||||||
|
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
||||||
|
std::cout << "SDL_AUDIO could not initialize! SDL Error: " << SDL_GetError() << '\n';
|
||||||
|
} else {
|
||||||
|
Ja::init(FREQUENCY, SDL_AUDIO_S16LE, 2);
|
||||||
|
enable(Options::audio.enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath> // Para std::lround
|
||||||
|
#include <cstdint> // Para int8_t, uint8_t
|
||||||
|
#include <string> // Para string
|
||||||
|
|
||||||
|
namespace Ja {
|
||||||
|
struct Music;
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
|
|
||||||
|
// --- Clase Audio: gestor de audio (singleton) ---
|
||||||
|
// Implementació canònica, byte-idèntica entre projectes.
|
||||||
|
// Els volums es manegen internament com a float 0.0–1.0; la capa de
|
||||||
|
// presentació (menús, notificacions) usa les helpers toPercent/fromPercent
|
||||||
|
// per mostrar 0–100 a l'usuari.
|
||||||
|
class Audio {
|
||||||
|
public:
|
||||||
|
// --- Enums ---
|
||||||
|
enum class Group : std::int8_t {
|
||||||
|
ALL = -1, // Todos los grupos
|
||||||
|
GAME = 0, // Sonidos del juego
|
||||||
|
INTERFACE = 1 // Sonidos de la interfaz
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MusicState : std::uint8_t {
|
||||||
|
PLAYING, // Reproduciendo música
|
||||||
|
PAUSED, // Música pausada
|
||||||
|
STOPPED, // Música detenida
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Constantes ---
|
||||||
|
static constexpr float MAX_VOLUME = 1.0F; // Volumen máximo (float 0..1)
|
||||||
|
static constexpr float MIN_VOLUME = 0.0F; // Volumen mínimo (float 0..1)
|
||||||
|
static constexpr float VOLUME_STEP = 0.05F; // Pas estàndard per a UI (5%)
|
||||||
|
static constexpr int FREQUENCY = 48000; // Frecuencia de audio
|
||||||
|
static constexpr int DEFAULT_CROSSFADE_MS = 1500; // Duració del crossfade per defecte (ms)
|
||||||
|
|
||||||
|
// --- Singleton ---
|
||||||
|
static void init(); // Inicializa el objeto Audio
|
||||||
|
static void destroy(); // Libera el objeto Audio
|
||||||
|
static auto get() -> Audio*; // Obtiene el puntero al objeto Audio
|
||||||
|
Audio(const Audio&) = delete; // Evitar copia
|
||||||
|
auto operator=(const Audio&) -> Audio& = delete; // Evitar asignación
|
||||||
|
|
||||||
|
static void update(); // Actualización del sistema de audio
|
||||||
|
|
||||||
|
// --- Control de música ---
|
||||||
|
void playMusic(const std::string& name, int loop = -1, int crossfade_ms = 0); // Reproducir música por nombre (con crossfade opcional)
|
||||||
|
void playMusic(Ja::Music* music, int loop = -1, int crossfade_ms = 0); // Reproducir música por puntero (con crossfade opcional)
|
||||||
|
void pauseMusic(); // Pausar reproducción de música
|
||||||
|
void resumeMusic(); // Continua la música pausada
|
||||||
|
void stopMusic(); // Detener completamente la música
|
||||||
|
void fadeOutMusic(int milliseconds) const; // Fundido de salida de la música
|
||||||
|
|
||||||
|
// --- Control de sonidos ---
|
||||||
|
void playSound(const std::string& name, Group group = Group::GAME) const; // Reproducir sonido puntual por nombre
|
||||||
|
void playSound(Ja::Sound* sound, Group group = Group::GAME) const; // Reproducir sonido puntual por puntero
|
||||||
|
void stopAllSounds() const; // Detener todos los sonidos
|
||||||
|
|
||||||
|
// --- Control de volumen (API interna: float 0.0..1.0) ---
|
||||||
|
void setSoundVolume(float volume, Group group = Group::ALL) const; // Ajustar volumen de efectos
|
||||||
|
void setMusicVolume(float volume) const; // Ajustar volumen de música
|
||||||
|
|
||||||
|
// --- Helpers de conversió per a la capa de presentació ---
|
||||||
|
// UI (menús, notificacions) manega enters 0..100; internament viu float 0..1.
|
||||||
|
static auto toPercent(float volume) -> int {
|
||||||
|
return static_cast<int>(std::lround(volume * 100.0F));
|
||||||
|
}
|
||||||
|
static constexpr auto fromPercent(int percent) -> float {
|
||||||
|
return static_cast<float>(percent) / 100.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Configuración general ---
|
||||||
|
void enable(bool value); // Establecer estado general
|
||||||
|
void toggleEnabled() { enabled_ = !enabled_; } // Alternar estado general
|
||||||
|
void applySettings(); // Aplica la configuración
|
||||||
|
|
||||||
|
// --- Configuración de sonidos ---
|
||||||
|
void enableSound() { sound_enabled_ = true; } // Habilitar sonidos
|
||||||
|
void disableSound() { sound_enabled_ = false; } // Deshabilitar sonidos
|
||||||
|
void enableSound(bool value) { sound_enabled_ = value; } // Establecer estado de sonidos
|
||||||
|
void toggleSound() { sound_enabled_ = !sound_enabled_; } // Alternar estado de sonidos
|
||||||
|
|
||||||
|
// --- Configuración de música ---
|
||||||
|
void enableMusic() { music_enabled_ = true; } // Habilitar música
|
||||||
|
void disableMusic() { music_enabled_ = false; } // Deshabilitar música
|
||||||
|
void enableMusic(bool value) { music_enabled_ = value; } // Establecer estado de música
|
||||||
|
void toggleMusic() { music_enabled_ = !music_enabled_; } // Alternar estado de música
|
||||||
|
|
||||||
|
// --- Consultas de estado ---
|
||||||
|
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
|
||||||
|
[[nodiscard]] auto isSoundEnabled() const -> bool { return sound_enabled_; }
|
||||||
|
[[nodiscard]] auto isMusicEnabled() const -> bool { return music_enabled_; }
|
||||||
|
[[nodiscard]] auto getMusicState() const -> MusicState { return music_.state; }
|
||||||
|
[[nodiscard]] static auto getRealMusicState() -> MusicState;
|
||||||
|
[[nodiscard]] auto getCurrentMusicName() const -> const std::string& { return music_.name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// --- Tipos anidados ---
|
||||||
|
struct Music {
|
||||||
|
MusicState state{MusicState::STOPPED}; // Estado actual de la música
|
||||||
|
std::string name; // Última pista de música reproducida
|
||||||
|
bool loop{false}; // Indica si se reproduce en bucle
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Métodos ---
|
||||||
|
Audio(); // Constructor privado
|
||||||
|
~Audio(); // Destructor privado
|
||||||
|
void initSDLAudio(); // Inicializa SDL Audio
|
||||||
|
|
||||||
|
// --- Variables miembro ---
|
||||||
|
static Audio* instance; // Instancia única de Audio
|
||||||
|
|
||||||
|
Music music_; // Estado de la música
|
||||||
|
bool enabled_{true}; // Estado general del audio
|
||||||
|
bool sound_enabled_{true}; // Estado de los efectos de sonido
|
||||||
|
bool music_enabled_{true}; // Estado de la música
|
||||||
|
};
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#include "core/audio/audio_adapter.hpp"
|
||||||
|
|
||||||
|
#include "core/resources/resource.hpp"
|
||||||
|
|
||||||
|
namespace AudioResource {
|
||||||
|
auto getMusic(const std::string& name) -> Ja::Music* {
|
||||||
|
return Resource::get()->getMusic(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto getSound(const std::string& name) -> Ja::Sound* {
|
||||||
|
return Resource::get()->getSound(name);
|
||||||
|
}
|
||||||
|
} // namespace AudioResource
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// --- Audio Resource Adapter ---
|
||||||
|
// Aquest fitxer exposa una interfície comuna a Audio per obtenir Ja::Music* /
|
||||||
|
// Ja::Sound* per nom. Cada projecte la implementa en audio_adapter.cpp
|
||||||
|
// delegant al seu singleton de recursos (Resource::get(), Resource::Cache::get(),
|
||||||
|
// etc.). Això permet que audio.hpp/audio.cpp siguin idèntics entre projectes.
|
||||||
|
|
||||||
|
#include <string> // Para string
|
||||||
|
|
||||||
|
namespace Ja {
|
||||||
|
struct Music;
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
|
|
||||||
|
namespace AudioResource {
|
||||||
|
auto getMusic(const std::string& name) -> Ja::Music*;
|
||||||
|
auto getSound(const std::string& name) -> Ja::Sound*;
|
||||||
|
} // namespace AudioResource
|
||||||
@@ -0,0 +1,699 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// --- Includes ---
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define STB_VORBIS_HEADER_ONLY
|
||||||
|
// NOLINTNEXTLINE(bugprone-suspicious-include) — stb_vorbis és single-file: la macro de dalt limita a només-declaracions.
|
||||||
|
#include "external/stb_vorbis.c" // Para stb_vorbis_open_memory i streaming
|
||||||
|
|
||||||
|
// Deleter stateless per a buffers reservats amb `SDL_malloc` / `SDL_LoadWAV*`.
|
||||||
|
// Compatible amb `std::unique_ptr<Uint8[], SdlFreeDeleter>` — zero size
|
||||||
|
// overhead gràcies a EBO, igual que un unique_ptr amb default_delete.
|
||||||
|
struct SdlFreeDeleter {
|
||||||
|
void operator()(Uint8* p) const noexcept {
|
||||||
|
if (p != nullptr) { SDL_free(p); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Ja {
|
||||||
|
|
||||||
|
// --- Public Enums ---
|
||||||
|
enum class ChannelState : std::uint8_t {
|
||||||
|
INVALID,
|
||||||
|
FREE,
|
||||||
|
PLAYING,
|
||||||
|
PAUSED,
|
||||||
|
DISABLED,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MusicState : std::uint8_t {
|
||||||
|
INVALID,
|
||||||
|
PLAYING,
|
||||||
|
PAUSED,
|
||||||
|
STOPPED,
|
||||||
|
DISABLED,
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Constants ---
|
||||||
|
inline constexpr int MAX_SIMULTANEOUS_CHANNELS = 20;
|
||||||
|
inline constexpr int MAX_GROUPS = 2;
|
||||||
|
inline constexpr SDL_AudioSpec DEFAULT_SPEC{.format = SDL_AUDIO_S16, .channels = 2, .freq = 48000};
|
||||||
|
|
||||||
|
// --- Struct Definitions ---
|
||||||
|
struct Sound {
|
||||||
|
SDL_AudioSpec spec{DEFAULT_SPEC};
|
||||||
|
Uint32 length{0};
|
||||||
|
// Buffer descomprimit (PCM) propietat del sound. Reservat per SDL_LoadWAV
|
||||||
|
// via SDL_malloc; el deleter `SdlFreeDeleter` allibera amb SDL_free.
|
||||||
|
std::unique_ptr<Uint8[], SdlFreeDeleter> buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// L'ordre (punters primer, ints després, enum de 8 bits al final) minimitza
|
||||||
|
// el padding a 64-bit (evita avisos de clang-analyzer-optin.performance.Padding).
|
||||||
|
struct Channel {
|
||||||
|
Sound* sound{nullptr};
|
||||||
|
SDL_AudioStream* stream{nullptr};
|
||||||
|
int pos{0};
|
||||||
|
int times{0};
|
||||||
|
int group{0};
|
||||||
|
ChannelState state{ChannelState::FREE};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Music {
|
||||||
|
SDL_AudioSpec spec{DEFAULT_SPEC};
|
||||||
|
|
||||||
|
// OGG comprimit en memòria. Propietat nostra; es copia des del buffer
|
||||||
|
// d'entrada una sola vegada en loadMusic i es descomprimix en chunks
|
||||||
|
// per streaming. Com que stb_vorbis guarda un punter persistent al
|
||||||
|
// `.data()` d'aquest vector, no el podem resize'jar un cop establert
|
||||||
|
// (una reallocation invalidaria el punter que el decoder conserva).
|
||||||
|
std::vector<Uint8> ogg_data;
|
||||||
|
stb_vorbis* vorbis{nullptr}; // handle del decoder, viu tot el cicle del Music
|
||||||
|
|
||||||
|
std::string filename;
|
||||||
|
|
||||||
|
int times{0}; // loops restants (-1 = infinit, 0 = un sol play)
|
||||||
|
SDL_AudioStream* stream{nullptr};
|
||||||
|
MusicState state{MusicState::INVALID};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FadeState {
|
||||||
|
bool active{false};
|
||||||
|
Uint64 start_time{0};
|
||||||
|
int duration_ms{0};
|
||||||
|
float initial_volume{0.0F};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OutgoingMusic {
|
||||||
|
SDL_AudioStream* stream{nullptr};
|
||||||
|
FadeState fade;
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Internal Global State (inline, C++17) ---
|
||||||
|
inline Music* current_music{nullptr};
|
||||||
|
inline Channel channels[MAX_SIMULTANEOUS_CHANNELS];
|
||||||
|
|
||||||
|
inline SDL_AudioSpec audio_spec{DEFAULT_SPEC};
|
||||||
|
inline float music_volume{1.0F};
|
||||||
|
inline float sound_volume[MAX_GROUPS];
|
||||||
|
inline bool music_enabled{true};
|
||||||
|
inline bool sound_enabled{true};
|
||||||
|
inline SDL_AudioDeviceID sdl_audio_device{0};
|
||||||
|
|
||||||
|
inline OutgoingMusic outgoing_music;
|
||||||
|
inline FadeState incoming_fade;
|
||||||
|
|
||||||
|
// --- Forward Declarations ---
|
||||||
|
inline void stopMusic();
|
||||||
|
inline void stopChannel(int channel);
|
||||||
|
inline auto playSoundOnChannel(Sound* sound, int channel, int loop = 0, int group = 0) -> int;
|
||||||
|
inline void crossfadeMusic(Music* music, int crossfade_ms, int loop = -1);
|
||||||
|
|
||||||
|
// --- Music streaming internals ---
|
||||||
|
// Bytes-per-sample per canal (sempre s16)
|
||||||
|
inline constexpr int MUSIC_BYTES_PER_SAMPLE = 2;
|
||||||
|
// Quants shorts decodifiquem per crida a get_samples_short_interleaved.
|
||||||
|
// 8192 shorts = 4096 samples/channel en estèreo ≈ 85ms de so a 48kHz.
|
||||||
|
inline constexpr int MUSIC_CHUNK_SHORTS = 8192;
|
||||||
|
// Umbral d'audio per davant del cursor de reproducció. Mantenim ≥ 0.5 s a
|
||||||
|
// l'SDL_AudioStream per absorbir jitter de frame i evitar underruns.
|
||||||
|
inline constexpr float MUSIC_LOW_WATER_SECONDS = 0.5F;
|
||||||
|
|
||||||
|
// Decodifica un chunk del vorbis i el volca a l'stream. Retorna samples
|
||||||
|
// decodificats per canal (0 = EOF de l'stream vorbis).
|
||||||
|
inline auto feedMusicChunk(Music* music) -> int {
|
||||||
|
if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { return 0; }
|
||||||
|
|
||||||
|
short chunk[MUSIC_CHUNK_SHORTS];
|
||||||
|
const int NUM_CHANNELS = music->spec.channels;
|
||||||
|
const int SAMPLES_PER_CHANNEL = stb_vorbis_get_samples_short_interleaved(
|
||||||
|
music->vorbis,
|
||||||
|
NUM_CHANNELS,
|
||||||
|
chunk,
|
||||||
|
MUSIC_CHUNK_SHORTS);
|
||||||
|
if (SAMPLES_PER_CHANNEL <= 0) { return 0; }
|
||||||
|
|
||||||
|
const int BYTES = SAMPLES_PER_CHANNEL * NUM_CHANNELS * MUSIC_BYTES_PER_SAMPLE;
|
||||||
|
SDL_PutAudioStreamData(music->stream, chunk, BYTES);
|
||||||
|
return SAMPLES_PER_CHANNEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reompli l'stream fins que tinga ≥ MUSIC_LOW_WATER_SECONDS bufferats.
|
||||||
|
// En arribar a EOF del vorbis, aplica el loop (times) o deixa drenar.
|
||||||
|
inline void pumpMusic(Music* music) {
|
||||||
|
if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { return; }
|
||||||
|
|
||||||
|
const int BYTES_PER_SECOND = music->spec.freq * music->spec.channels * MUSIC_BYTES_PER_SAMPLE;
|
||||||
|
const int LOW_WATER_BYTES = static_cast<int>(MUSIC_LOW_WATER_SECONDS * static_cast<float>(BYTES_PER_SECOND));
|
||||||
|
|
||||||
|
while (SDL_GetAudioStreamAvailable(music->stream) < LOW_WATER_BYTES) {
|
||||||
|
const int DECODED = feedMusicChunk(music);
|
||||||
|
if (DECODED > 0) { continue; }
|
||||||
|
|
||||||
|
// EOF: si queden loops, rebobinar; si no, tallar i deixar drenar.
|
||||||
|
if (music->times != 0) {
|
||||||
|
stb_vorbis_seek_start(music->vorbis);
|
||||||
|
if (music->times > 0) { music->times--; }
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-carrega `duration_ms` de so dins l'stream actual abans que l'stream
|
||||||
|
// siga robat per outgoing_music (crossfade o fade-out). Imprescindible amb
|
||||||
|
// streaming: l'stream robat no es pot re-alimentar perquè perd la referència
|
||||||
|
// al seu vorbis decoder. No aplica loop — si el vorbis s'esgota abans, parem.
|
||||||
|
inline void preFillOutgoing(Music* music, int duration_ms) {
|
||||||
|
if ((music == nullptr) || (music->vorbis == nullptr) || (music->stream == nullptr)) { return; }
|
||||||
|
|
||||||
|
const int BYTES_PER_SECOND = music->spec.freq * music->spec.channels * MUSIC_BYTES_PER_SAMPLE;
|
||||||
|
const int NEEDED_BYTES = static_cast<int>((static_cast<std::int64_t>(duration_ms) * BYTES_PER_SECOND) / 1000);
|
||||||
|
|
||||||
|
while (SDL_GetAudioStreamAvailable(music->stream) < NEEDED_BYTES) {
|
||||||
|
const int DECODED = feedMusicChunk(music);
|
||||||
|
if (DECODED <= 0) { break; } // EOF: deixem drenar el que hi haja
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- update() helpers ---
|
||||||
|
inline void updateOutgoingFade() {
|
||||||
|
if ((outgoing_music.stream == nullptr) || !outgoing_music.fade.active) { return; }
|
||||||
|
|
||||||
|
const Uint64 NOW = SDL_GetTicks();
|
||||||
|
const Uint64 ELAPSED = NOW - outgoing_music.fade.start_time;
|
||||||
|
if (ELAPSED >= static_cast<Uint64>(outgoing_music.fade.duration_ms)) {
|
||||||
|
SDL_DestroyAudioStream(outgoing_music.stream);
|
||||||
|
outgoing_music.stream = nullptr;
|
||||||
|
outgoing_music.fade.active = false;
|
||||||
|
} else {
|
||||||
|
const float PERCENT = static_cast<float>(ELAPSED) / static_cast<float>(outgoing_music.fade.duration_ms);
|
||||||
|
SDL_SetAudioStreamGain(outgoing_music.stream, outgoing_music.fade.initial_volume * (1.0F - PERCENT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void updateIncomingFade() {
|
||||||
|
if (!incoming_fade.active) { return; }
|
||||||
|
|
||||||
|
const Uint64 NOW = SDL_GetTicks();
|
||||||
|
const Uint64 ELAPSED = NOW - incoming_fade.start_time;
|
||||||
|
if (ELAPSED >= static_cast<Uint64>(incoming_fade.duration_ms)) {
|
||||||
|
incoming_fade.active = false;
|
||||||
|
SDL_SetAudioStreamGain(current_music->stream, music_volume);
|
||||||
|
} else {
|
||||||
|
const float PERCENT = static_cast<float>(ELAPSED) / static_cast<float>(incoming_fade.duration_ms);
|
||||||
|
SDL_SetAudioStreamGain(current_music->stream, music_volume * PERCENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void updateCurrentMusic() {
|
||||||
|
if (!music_enabled || (current_music == nullptr) || current_music->state != MusicState::PLAYING) { return; }
|
||||||
|
|
||||||
|
updateIncomingFade();
|
||||||
|
|
||||||
|
// Streaming: rellenem l'stream fins al low-water-mark i parem si el
|
||||||
|
// vorbis s'ha esgotat i no queden loops.
|
||||||
|
pumpMusic(current_music);
|
||||||
|
if (current_music->times == 0 && SDL_GetAudioStreamAvailable(current_music->stream) == 0) {
|
||||||
|
stopMusic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void updateSoundChannels() {
|
||||||
|
if (!sound_enabled) { return; }
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_SIMULTANEOUS_CHANNELS; ++i) {
|
||||||
|
auto& ch = channels[i];
|
||||||
|
if (ch.state != ChannelState::PLAYING) { continue; }
|
||||||
|
|
||||||
|
if (ch.times != 0) {
|
||||||
|
if (static_cast<Uint32>(SDL_GetAudioStreamAvailable(ch.stream)) < (ch.sound->length / 2)) {
|
||||||
|
SDL_PutAudioStreamData(ch.stream, ch.sound->buffer.get(), ch.sound->length);
|
||||||
|
if (ch.times > 0) { ch.times--; }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (SDL_GetAudioStreamAvailable(ch.stream) == 0) { stopChannel(i); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void update() {
|
||||||
|
updateOutgoingFade();
|
||||||
|
updateCurrentMusic();
|
||||||
|
updateSoundChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void init(int freq, SDL_AudioFormat format, int num_channels) {
|
||||||
|
audio_spec = {.format = format, .channels = num_channels, .freq = freq};
|
||||||
|
if (sdl_audio_device != 0) { SDL_CloseAudioDevice(sdl_audio_device); }
|
||||||
|
sdl_audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec);
|
||||||
|
if (sdl_audio_device == 0) { std::cout << "Failed to initialize SDL audio!" << '\n'; }
|
||||||
|
for (auto& ch : channels) { ch.state = ChannelState::FREE; }
|
||||||
|
std::ranges::fill(sound_volume, 0.5F);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void quit() {
|
||||||
|
if (outgoing_music.stream != nullptr) {
|
||||||
|
SDL_DestroyAudioStream(outgoing_music.stream);
|
||||||
|
outgoing_music.stream = nullptr;
|
||||||
|
}
|
||||||
|
if (sdl_audio_device != 0) { SDL_CloseAudioDevice(sdl_audio_device); }
|
||||||
|
sdl_audio_device = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Music Functions ---
|
||||||
|
inline auto loadMusic(const Uint8* buffer, Uint32 length) -> Music* {
|
||||||
|
if ((buffer == nullptr) || length == 0) { return nullptr; }
|
||||||
|
|
||||||
|
// Allocem el Music primer per aprofitar el seu `std::vector<Uint8>`
|
||||||
|
// com a propietari del OGG comprimit. stb_vorbis guarda un punter
|
||||||
|
// persistent al buffer; com que ací no el resize'jem, el .data() és
|
||||||
|
// estable durant tot el cicle de vida del music.
|
||||||
|
auto* music = new Music();
|
||||||
|
music->ogg_data.assign(buffer, buffer + length);
|
||||||
|
|
||||||
|
int vorbis_error = 0;
|
||||||
|
music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(),
|
||||||
|
static_cast<int>(length),
|
||||||
|
&vorbis_error,
|
||||||
|
nullptr);
|
||||||
|
if (music->vorbis == nullptr) {
|
||||||
|
std::cout << "loadMusic: stb_vorbis_open_memory failed (error " << vorbis_error << ")" << '\n';
|
||||||
|
delete music;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stb_vorbis_info INFO = stb_vorbis_get_info(music->vorbis);
|
||||||
|
music->spec.channels = INFO.channels;
|
||||||
|
music->spec.freq = static_cast<int>(INFO.sample_rate);
|
||||||
|
music->spec.format = SDL_AUDIO_S16;
|
||||||
|
music->state = MusicState::STOPPED;
|
||||||
|
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload amb filename — els callers l'usen per poder comparar la música
|
||||||
|
// en curs amb getMusicFilename() i no rearrancar-la si ja és la mateixa.
|
||||||
|
inline auto loadMusic(Uint8* buffer, Uint32 length, const char* filename) -> Music* {
|
||||||
|
Music* music = loadMusic(static_cast<const Uint8*>(buffer), length);
|
||||||
|
if ((music != nullptr) && (filename != nullptr)) { music->filename = filename; }
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto loadMusic(const char* filename) -> Music* {
|
||||||
|
// Carreguem primer el arxiu en memòria i després el descomprimim.
|
||||||
|
FILE* f = std::fopen(filename, "rb");
|
||||||
|
if (f == nullptr) { return nullptr; }
|
||||||
|
std::fseek(f, 0, SEEK_END);
|
||||||
|
const long FSIZE = std::ftell(f);
|
||||||
|
std::fseek(f, 0, SEEK_SET);
|
||||||
|
if (FSIZE <= 0) {
|
||||||
|
std::fclose(f);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto* buffer = static_cast<Uint8*>(std::malloc(static_cast<size_t>(FSIZE) + 1));
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
std::fclose(f);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (std::fread(buffer, FSIZE, 1, f) != 1) {
|
||||||
|
std::fclose(f);
|
||||||
|
std::free(buffer);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::fclose(f);
|
||||||
|
|
||||||
|
Music* music = loadMusic(static_cast<const Uint8*>(buffer), static_cast<Uint32>(FSIZE));
|
||||||
|
if (music != nullptr) { music->filename = filename; }
|
||||||
|
|
||||||
|
std::free(buffer);
|
||||||
|
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void playMusic(Music* music, int loop = -1) {
|
||||||
|
if (!music_enabled || (music == nullptr) || (music->vorbis == nullptr)) { return; }
|
||||||
|
|
||||||
|
stopMusic();
|
||||||
|
|
||||||
|
current_music = music;
|
||||||
|
current_music->state = MusicState::PLAYING;
|
||||||
|
current_music->times = loop;
|
||||||
|
|
||||||
|
// Rebobinem l'stream de vorbis al principi. Cobreix tant play-per-primera-
|
||||||
|
// vegada com replays/canvis de track que tornen a la mateixa pista.
|
||||||
|
stb_vorbis_seek_start(current_music->vorbis);
|
||||||
|
|
||||||
|
current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &audio_spec);
|
||||||
|
if (current_music->stream == nullptr) {
|
||||||
|
std::cout << "Failed to create audio stream!" << '\n';
|
||||||
|
current_music->state = MusicState::STOPPED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SDL_SetAudioStreamGain(current_music->stream, music_volume);
|
||||||
|
|
||||||
|
// Pre-cargem el buffer abans de bindejar per evitar un underrun inicial.
|
||||||
|
pumpMusic(current_music);
|
||||||
|
|
||||||
|
if (!SDL_BindAudioStream(sdl_audio_device, current_music->stream)) {
|
||||||
|
std::cout << "[ERROR] SDL_BindAudioStream failed!" << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto getMusicFilename(const Music* music = nullptr) -> const char* {
|
||||||
|
if (music == nullptr) { music = current_music; }
|
||||||
|
if ((music == nullptr) || music->filename.empty()) { return nullptr; }
|
||||||
|
return music->filename.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void pauseMusic() {
|
||||||
|
if (!music_enabled) { return; }
|
||||||
|
if ((current_music == nullptr) || current_music->state != MusicState::PLAYING) { return; }
|
||||||
|
|
||||||
|
current_music->state = MusicState::PAUSED;
|
||||||
|
SDL_UnbindAudioStream(current_music->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void resumeMusic() {
|
||||||
|
if (!music_enabled) { return; }
|
||||||
|
if ((current_music == nullptr) || current_music->state != MusicState::PAUSED) { return; }
|
||||||
|
|
||||||
|
current_music->state = MusicState::PLAYING;
|
||||||
|
SDL_BindAudioStream(sdl_audio_device, current_music->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void stopMusic() {
|
||||||
|
// Limpiar outgoing crossfade si existe
|
||||||
|
if (outgoing_music.stream != nullptr) {
|
||||||
|
SDL_DestroyAudioStream(outgoing_music.stream);
|
||||||
|
outgoing_music.stream = nullptr;
|
||||||
|
outgoing_music.fade.active = false;
|
||||||
|
}
|
||||||
|
incoming_fade.active = false;
|
||||||
|
|
||||||
|
if ((current_music == nullptr) || current_music->state == MusicState::INVALID || current_music->state == MusicState::STOPPED) { return; }
|
||||||
|
|
||||||
|
current_music->state = MusicState::STOPPED;
|
||||||
|
if (current_music->stream != nullptr) {
|
||||||
|
SDL_DestroyAudioStream(current_music->stream);
|
||||||
|
current_music->stream = nullptr;
|
||||||
|
}
|
||||||
|
// Deixem el handle de vorbis viu — es tanca en deleteMusic.
|
||||||
|
// Rebobinem perquè un futur playMusic comence des del principi.
|
||||||
|
if (current_music->vorbis != nullptr) {
|
||||||
|
stb_vorbis_seek_start(current_music->vorbis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fadeOutMusic(int milliseconds) {
|
||||||
|
if (!music_enabled) { return; }
|
||||||
|
if ((current_music == nullptr) || current_music->state != MusicState::PLAYING) { return; }
|
||||||
|
|
||||||
|
// Destruir outgoing anterior si existe
|
||||||
|
if (outgoing_music.stream != nullptr) {
|
||||||
|
SDL_DestroyAudioStream(outgoing_music.stream);
|
||||||
|
outgoing_music.stream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-omplim l'stream amb `milliseconds` de so: un cop robat, ja no
|
||||||
|
// tindrà accés al vorbis decoder i només podrà drenar el que tinga.
|
||||||
|
preFillOutgoing(current_music, milliseconds);
|
||||||
|
|
||||||
|
// Robar el stream del current_music al outgoing
|
||||||
|
outgoing_music.stream = current_music->stream;
|
||||||
|
outgoing_music.fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = milliseconds, .initial_volume = music_volume};
|
||||||
|
|
||||||
|
// Dejar current_music sin stream (ya lo tiene outgoing)
|
||||||
|
current_music->stream = nullptr;
|
||||||
|
current_music->state = MusicState::STOPPED;
|
||||||
|
if (current_music->vorbis != nullptr) { stb_vorbis_seek_start(current_music->vorbis); }
|
||||||
|
incoming_fade.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void crossfadeMusic(Music* music, int crossfade_ms, int loop) {
|
||||||
|
if (!music_enabled || (music == nullptr) || (music->vorbis == nullptr)) { return; }
|
||||||
|
|
||||||
|
// Destruir outgoing anterior si existe (crossfade durante crossfade)
|
||||||
|
if (outgoing_music.stream != nullptr) {
|
||||||
|
SDL_DestroyAudioStream(outgoing_music.stream);
|
||||||
|
outgoing_music.stream = nullptr;
|
||||||
|
outgoing_music.fade.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Robar el stream de la musica actual al outgoing para el fade-out.
|
||||||
|
// Pre-omplim amb `crossfade_ms` de so perquè no es quede en silenci
|
||||||
|
// abans d'acabar el fade (l'stream robat ja no pot alimentar-se).
|
||||||
|
if ((current_music != nullptr) && current_music->state == MusicState::PLAYING && (current_music->stream != nullptr)) {
|
||||||
|
preFillOutgoing(current_music, crossfade_ms);
|
||||||
|
outgoing_music.stream = current_music->stream;
|
||||||
|
outgoing_music.fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = crossfade_ms, .initial_volume = music_volume};
|
||||||
|
current_music->stream = nullptr;
|
||||||
|
current_music->state = MusicState::STOPPED;
|
||||||
|
if (current_music->vorbis != nullptr) { stb_vorbis_seek_start(current_music->vorbis); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iniciar la nueva pista con gain=0 (el fade-in la sube gradualmente)
|
||||||
|
current_music = music;
|
||||||
|
current_music->state = MusicState::PLAYING;
|
||||||
|
current_music->times = loop;
|
||||||
|
|
||||||
|
stb_vorbis_seek_start(current_music->vorbis);
|
||||||
|
current_music->stream = SDL_CreateAudioStream(¤t_music->spec, &audio_spec);
|
||||||
|
if (current_music->stream == nullptr) {
|
||||||
|
std::cout << "Failed to create audio stream for crossfade!" << '\n';
|
||||||
|
current_music->state = MusicState::STOPPED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SDL_SetAudioStreamGain(current_music->stream, 0.0F);
|
||||||
|
pumpMusic(current_music); // pre-carrega abans de bindejar
|
||||||
|
SDL_BindAudioStream(sdl_audio_device, current_music->stream);
|
||||||
|
|
||||||
|
// Configurar fade-in
|
||||||
|
incoming_fade = {.active = true, .start_time = SDL_GetTicks(), .duration_ms = crossfade_ms, .initial_volume = 0.0F};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto getMusicState() -> MusicState {
|
||||||
|
if (!music_enabled) { return MusicState::DISABLED; }
|
||||||
|
if (current_music == nullptr) { return MusicState::INVALID; }
|
||||||
|
|
||||||
|
return current_music->state;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void deleteMusic(Music* music) {
|
||||||
|
if (music == nullptr) { return; }
|
||||||
|
if (current_music == music) {
|
||||||
|
stopMusic();
|
||||||
|
current_music = nullptr;
|
||||||
|
}
|
||||||
|
if (music->stream != nullptr) { SDL_DestroyAudioStream(music->stream); }
|
||||||
|
if (music->vorbis != nullptr) { stb_vorbis_close(music->vorbis); }
|
||||||
|
// ogg_data (std::vector) i filename (std::string) s'alliberen sols
|
||||||
|
// al destructor de Music.
|
||||||
|
delete music;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto setMusicVolume(float volume) -> float {
|
||||||
|
music_volume = SDL_clamp(volume, 0.0F, 1.0F);
|
||||||
|
if ((current_music != nullptr) && (current_music->stream != nullptr)) {
|
||||||
|
SDL_SetAudioStreamGain(current_music->stream, music_volume);
|
||||||
|
}
|
||||||
|
return music_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setMusicPosition(float /*value*/) {
|
||||||
|
// No implementat amb el backend de streaming.
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto getMusicPosition() -> float {
|
||||||
|
return 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void enableMusic(bool value) {
|
||||||
|
if (!value && (current_music != nullptr) && (current_music->state == MusicState::PLAYING)) { stopMusic(); }
|
||||||
|
music_enabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Sound Functions ---
|
||||||
|
inline auto loadSound(std::uint8_t* buffer, std::uint32_t size) -> Sound* {
|
||||||
|
auto sound = std::make_unique<Sound>();
|
||||||
|
Uint8* raw = nullptr;
|
||||||
|
if (!SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size), true, &sound->spec, &raw, &sound->length)) {
|
||||||
|
std::cout << "Failed to load WAV from memory: " << SDL_GetError() << '\n';
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer
|
||||||
|
return sound.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto loadSound(const char* filename) -> Sound* {
|
||||||
|
auto sound = std::make_unique<Sound>();
|
||||||
|
Uint8* raw = nullptr;
|
||||||
|
if (!SDL_LoadWAV(filename, &sound->spec, &raw, &sound->length)) {
|
||||||
|
std::cout << "Failed to load WAV file: " << SDL_GetError() << '\n';
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer
|
||||||
|
return sound.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto playSound(Sound* sound, int loop = 0, int group = 0) -> int {
|
||||||
|
if (!sound_enabled || (sound == nullptr)) { return -1; }
|
||||||
|
|
||||||
|
int channel = 0;
|
||||||
|
while (channel < MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != ChannelState::FREE) { channel++; }
|
||||||
|
if (channel == MAX_SIMULTANEOUS_CHANNELS) {
|
||||||
|
// No hi ha canal lliure, reemplacem el primer
|
||||||
|
channel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return playSoundOnChannel(sound, channel, loop, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto playSoundOnChannel(Sound* sound, int channel, int loop, int group) -> int {
|
||||||
|
if (!sound_enabled || (sound == nullptr)) { return -1; }
|
||||||
|
if (channel < 0 || channel >= MAX_SIMULTANEOUS_CHANNELS) { return -1; }
|
||||||
|
|
||||||
|
stopChannel(channel);
|
||||||
|
|
||||||
|
channels[channel].sound = sound;
|
||||||
|
channels[channel].times = loop;
|
||||||
|
channels[channel].pos = 0;
|
||||||
|
channels[channel].group = group;
|
||||||
|
channels[channel].state = ChannelState::PLAYING;
|
||||||
|
channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &audio_spec);
|
||||||
|
|
||||||
|
if (channels[channel].stream == nullptr) {
|
||||||
|
std::cout << "Failed to create audio stream for sound!" << '\n';
|
||||||
|
channels[channel].state = ChannelState::FREE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer.get(), channels[channel].sound->length);
|
||||||
|
SDL_SetAudioStreamGain(channels[channel].stream, sound_volume[group]);
|
||||||
|
SDL_BindAudioStream(sdl_audio_device, channels[channel].stream);
|
||||||
|
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void deleteSound(Sound* sound) {
|
||||||
|
if (sound == nullptr) { return; }
|
||||||
|
for (int i = 0; i < MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||||
|
if (channels[i].sound == sound) { stopChannel(i); }
|
||||||
|
}
|
||||||
|
// buffer es destrueix automàticament via RAII (SdlFreeDeleter).
|
||||||
|
delete sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void pauseChannel(int channel) {
|
||||||
|
if (!sound_enabled) { return; }
|
||||||
|
|
||||||
|
if (channel == -1) {
|
||||||
|
for (auto& ch : channels) {
|
||||||
|
if (ch.state == ChannelState::PLAYING) {
|
||||||
|
ch.state = ChannelState::PAUSED;
|
||||||
|
SDL_UnbindAudioStream(ch.stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) {
|
||||||
|
if (channels[channel].state == ChannelState::PLAYING) {
|
||||||
|
channels[channel].state = ChannelState::PAUSED;
|
||||||
|
SDL_UnbindAudioStream(channels[channel].stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void resumeChannel(int channel) {
|
||||||
|
if (!sound_enabled) { return; }
|
||||||
|
|
||||||
|
if (channel == -1) {
|
||||||
|
for (auto& ch : channels) {
|
||||||
|
if (ch.state == ChannelState::PAUSED) {
|
||||||
|
ch.state = ChannelState::PLAYING;
|
||||||
|
SDL_BindAudioStream(sdl_audio_device, ch.stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) {
|
||||||
|
if (channels[channel].state == ChannelState::PAUSED) {
|
||||||
|
channels[channel].state = ChannelState::PLAYING;
|
||||||
|
SDL_BindAudioStream(sdl_audio_device, channels[channel].stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void stopChannel(int channel) {
|
||||||
|
if (channel == -1) {
|
||||||
|
for (auto& ch : channels) {
|
||||||
|
if (ch.state != ChannelState::FREE) {
|
||||||
|
if (ch.stream != nullptr) { SDL_DestroyAudioStream(ch.stream); }
|
||||||
|
ch.stream = nullptr;
|
||||||
|
ch.state = ChannelState::FREE;
|
||||||
|
ch.pos = 0;
|
||||||
|
ch.sound = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (channel >= 0 && channel < MAX_SIMULTANEOUS_CHANNELS) {
|
||||||
|
if (channels[channel].state != ChannelState::FREE) {
|
||||||
|
if (channels[channel].stream != nullptr) { SDL_DestroyAudioStream(channels[channel].stream); }
|
||||||
|
channels[channel].stream = nullptr;
|
||||||
|
channels[channel].state = ChannelState::FREE;
|
||||||
|
channels[channel].pos = 0;
|
||||||
|
channels[channel].sound = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto getChannelState(int channel) -> ChannelState {
|
||||||
|
if (!sound_enabled) { return ChannelState::DISABLED; }
|
||||||
|
if (channel < 0 || channel >= MAX_SIMULTANEOUS_CHANNELS) { return ChannelState::INVALID; }
|
||||||
|
|
||||||
|
return channels[channel].state;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto setSoundVolume(float volume, int group = -1) -> float {
|
||||||
|
const float V = SDL_clamp(volume, 0.0F, 1.0F);
|
||||||
|
|
||||||
|
if (group == -1) {
|
||||||
|
std::ranges::fill(sound_volume, V);
|
||||||
|
} else if (group >= 0 && group < MAX_GROUPS) {
|
||||||
|
sound_volume[group] = V;
|
||||||
|
} else {
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar volum als canals actius.
|
||||||
|
for (auto& ch : channels) {
|
||||||
|
if ((ch.state == ChannelState::PLAYING) || (ch.state == ChannelState::PAUSED)) {
|
||||||
|
if (group == -1 || ch.group == group) {
|
||||||
|
if (ch.stream != nullptr) {
|
||||||
|
SDL_SetAudioStreamGain(ch.stream, sound_volume[ch.group]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void enableSound(bool value) {
|
||||||
|
if (!value) {
|
||||||
|
stopChannel(-1);
|
||||||
|
}
|
||||||
|
sound_enabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto setVolume(float volume) -> float {
|
||||||
|
const float V = setMusicVolume(volume);
|
||||||
|
setSoundVolume(V, -1);
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ja
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
#include "define_buttons.hpp"
|
#include "core/input/define_buttons.hpp"
|
||||||
|
|
||||||
#include <algorithm> // Para __all_of_fn, all_of
|
#include <algorithm> // Para __all_of_fn, all_of, ranges::transform
|
||||||
|
#include <iterator> // Para back_inserter
|
||||||
#include <memory> // Para unique_ptr, allocator, shared_ptr, operator==, make_unique
|
#include <memory> // Para unique_ptr, allocator, shared_ptr, operator==, make_unique
|
||||||
|
|
||||||
#include "input.hpp" // Para Input
|
#include "core/input/input.hpp" // Para Input
|
||||||
#include "input_types.hpp" // Para InputAction
|
#include "core/locale/lang.hpp" // Para getText
|
||||||
#include "lang.hpp" // Para getText
|
#include "core/resources/resource.hpp" // Para Resource
|
||||||
#include "options.hpp" // Para Gamepad
|
#include "game/options.hpp" // Para Gamepad
|
||||||
#include "param.hpp" // Para Param, param, ParamGame, ParamServiceMenu
|
#include "game/ui/window_message.hpp" // Para WindowMessage
|
||||||
#include "resource.hpp" // Para Resource
|
#include "utils/param.hpp" // Para Param, param, ParamGame, ParamServiceMenu
|
||||||
#include "ui/window_message.hpp" // Para WindowMessage
|
#include "utils/utils.hpp" // Para Zone
|
||||||
#include "utils.hpp" // Para Zone
|
|
||||||
|
|
||||||
DefineButtons::DefineButtons()
|
DefineButtons::DefineButtons()
|
||||||
: input_(Input::get()) {
|
: input_(Input::get()) {
|
||||||
clearButtons();
|
clearButtons();
|
||||||
|
|
||||||
auto gamepads = input_->getGamepads();
|
const auto GAMEPADS = input_->getGamepads();
|
||||||
for (const auto& gamepad : gamepads) {
|
controller_names_.reserve(GAMEPADS.size());
|
||||||
controller_names_.emplace_back(Input::getControllerName(gamepad));
|
std::ranges::transform(GAMEPADS, std::back_inserter(controller_names_), Input::getControllerName);
|
||||||
}
|
|
||||||
|
|
||||||
// Crear la ventana de mensaje
|
// Crear la ventana de mensaje
|
||||||
WindowMessage::Config config(param.service_menu.window_message);
|
WindowMessage::Config config(param.service_menu.window_message);
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "input.hpp"
|
#include "core/input/input.hpp"
|
||||||
#include "ui/window_message.hpp"
|
#include "game/ui/window_message.hpp"
|
||||||
|
|
||||||
namespace Options {
|
namespace Options {
|
||||||
struct Gamepad;
|
struct Gamepad;
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "core/input/input_types.hpp" // Solo incluimos los tipos compartidos
|
||||||
#include "external/json.hpp"
|
#include "external/json.hpp"
|
||||||
#include "input_types.hpp" // Solo incluimos los tipos compartidos
|
|
||||||
|
|
||||||
// --- Estructuras ---
|
// --- Estructuras ---
|
||||||
struct GamepadConfig {
|
struct GamepadConfig {
|
||||||
@@ -64,7 +64,7 @@ class GamepadConfigManager {
|
|||||||
// Escribir al archivo
|
// Escribir al archivo
|
||||||
std::ofstream file(filename);
|
std::ofstream file(filename);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
return false; // NOLINT(readability-simplify-boolean-expr)
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
file << j.dump(4); // Formato con indentación de 4 espacios
|
file << j.dump(4); // Formato con indentación de 4 espacios
|
||||||
@@ -92,7 +92,7 @@ class GamepadConfigManager {
|
|||||||
configs.clear();
|
configs.clear();
|
||||||
|
|
||||||
if (!j.contains("gamepads") || !j["gamepads"].is_array()) {
|
if (!j.contains("gamepads") || !j["gamepads"].is_array()) {
|
||||||
return false; // NOLINT(readability-simplify-boolean-expr)
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& gamepad_json : j["gamepads"]) {
|
for (const auto& gamepad_json : j["gamepads"]) {
|
||||||
@@ -1,26 +1,28 @@
|
|||||||
#include "global_inputs.hpp"
|
#include "core/input/global_inputs.hpp"
|
||||||
|
|
||||||
#include <algorithm> // Para __any_of_fn, any_of
|
#include <algorithm> // Para __any_of_fn, any_of
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
#include <iterator> // Para pair
|
|
||||||
#include <string> // Para basic_string, operator+, allocator, char_traits, string, to_string
|
#include <string> // Para basic_string, operator+, allocator, char_traits, string, to_string
|
||||||
#include <utility> // Para pair
|
#include <utility> // Para pair
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "audio.hpp" // Para Audio
|
#include "core/audio/audio.hpp" // Para Audio
|
||||||
#include "input.hpp" // Para Input
|
#include "core/input/input.hpp" // Para Input
|
||||||
#include "input_types.hpp" // Para InputAction
|
#include "core/locale/lang.hpp" // Para getText, getLangFile, getLangName, getNextLangCode, loadFromFile
|
||||||
#include "lang.hpp" // Para getText, getLangFile, getLangName, getNextLangCode, loadFromFile
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "options.hpp" // Para Video, video, Settings, settings, Audio, audio, Window, window
|
#include "core/system/section.hpp" // Para Name, name, Options, options, AttractMode, attract_mode
|
||||||
#include "screen.hpp" // Para Screen
|
#include "game/options.hpp" // Para Video, video, Settings, settings, Audio, audio, Window, window
|
||||||
#include "section.hpp" // Para Name, name, Options, options, AttractMode, attract_mode
|
#include "game/ui/notifier.hpp" // Para Notifier
|
||||||
#include "ui/notifier.hpp" // Para Notifier
|
#include "game/ui/service_menu.hpp" // Para ServiceMenu
|
||||||
#include "ui/service_menu.hpp" // Para ServiceMenu
|
#include "utils/utils.hpp" // Para boolToOnOff
|
||||||
#include "utils.hpp" // Para boolToOnOff
|
|
||||||
|
|
||||||
namespace GlobalInputs {
|
namespace GlobalInputs {
|
||||||
// Termina
|
// Termina
|
||||||
void quit() {
|
void quit() {
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
// En la versión web no se permite salir: el navegador gestiona el cierre.
|
||||||
|
return;
|
||||||
|
#else
|
||||||
const std::string CODE = "QUIT";
|
const std::string CODE = "QUIT";
|
||||||
if (Notifier::get()->checkCode(CODE)) {
|
if (Notifier::get()->checkCode(CODE)) {
|
||||||
// Si la notificación de salir está activa, cambia de sección
|
// Si la notificación de salir está activa, cambia de sección
|
||||||
@@ -30,6 +32,7 @@ namespace GlobalInputs {
|
|||||||
// Si la notificación de salir no está activa, muestra la notificación
|
// Si la notificación de salir no está activa, muestra la notificación
|
||||||
Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 01"), std::string()}, -1, CODE);
|
Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 01"), std::string()}, -1, CODE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinicia
|
// Reinicia
|
||||||
@@ -79,21 +82,15 @@ namespace GlobalInputs {
|
|||||||
void nextPreset() {
|
void nextPreset() {
|
||||||
if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
|
if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
|
||||||
Screen::nextCrtPiPreset();
|
Screen::nextCrtPiPreset();
|
||||||
const std::string name = Options::crtpi_presets.empty() ? "" : Options::crtpi_presets.at(static_cast<size_t>(Options::video.shader.current_crtpi_preset)).name;
|
const std::string NAME = Options::crtpi_presets.empty() ? "" : Options::crtpi_presets.at(static_cast<size_t>(Options::video.shader.current_crtpi_preset)).name;
|
||||||
Notifier::get()->show({"CrtPi: " + name});
|
Notifier::get()->show({"CrtPi: " + NAME});
|
||||||
} else {
|
} else {
|
||||||
Screen::nextPostFXPreset();
|
Screen::nextPostFXPreset();
|
||||||
const std::string name = Options::postfx_presets.empty() ? "" : Options::postfx_presets.at(static_cast<size_t>(Options::video.shader.current_postfx_preset)).name;
|
const std::string NAME = Options::postfx_presets.empty() ? "" : Options::postfx_presets.at(static_cast<size_t>(Options::video.shader.current_postfx_preset)).name;
|
||||||
Notifier::get()->show({"PostFX: " + name});
|
Notifier::get()->show({"PostFX: " + NAME});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activa o desactiva el supersampling
|
|
||||||
void toggleSupersampling() {
|
|
||||||
Screen::toggleSupersampling();
|
|
||||||
Notifier::get()->show({"SS: " + std::string(Options::video.supersampling.enabled ? "ON" : "OFF")});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cambia al siguiente idioma
|
// Cambia al siguiente idioma
|
||||||
void setNextLang() {
|
void setNextLang() {
|
||||||
const std::string CODE = "LANG";
|
const std::string CODE = "LANG";
|
||||||
@@ -224,10 +221,6 @@ namespace GlobalInputs {
|
|||||||
nextPreset();
|
nextPreset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Input::get()->checkAction(Input::Action::TOGGLE_SUPERSAMPLING, Input::DO_NOT_ALLOW_REPEAT, Input::CHECK_KEYBOARD)) {
|
|
||||||
toggleSupersampling();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "input.hpp"
|
#include "core/input/input.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_GetGamepadAxis, SDL_GamepadAxis, SDL_GamepadButton, SDL_GetError, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogError, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, Sint16, SDL_Gamepad, SDL_LogCategory, SDL_Scancode
|
#include <SDL3/SDL.h> // Para SDL_GetGamepadAxis, SDL_GamepadAxis, SDL_GamepadButton, SDL_GetError, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogError, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, Sint16, SDL_Gamepad, SDL_LogCategory, SDL_Scancode
|
||||||
|
|
||||||
@@ -8,6 +8,41 @@
|
|||||||
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
|
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
|
||||||
#include <utility> // Para pair, move
|
#include <utility> // Para pair, move
|
||||||
|
|
||||||
|
// Emscripten-only: SDL 3.4+ ja no casa el GUID dels mandos de Chrome Android
|
||||||
|
// amb gamecontrollerdb (el gamepad.id d'Android no porta Vendor/Product, el
|
||||||
|
// parser extreu valors escombraries, el GUID resultant no està a la db i el
|
||||||
|
// gamepad queda obert amb un mapping incorrecte). Com el W3C Gamepad API
|
||||||
|
// garanteix el layout estàndard quan el navegador reporta mapping=="standard",
|
||||||
|
// injectem un mapping SDL amb eixe layout per al GUID del joystick abans
|
||||||
|
// d'obrir-lo com gamepad. Fora d'Emscripten és un no-op.
|
||||||
|
static void installWebStandardMapping(SDL_JoystickID jid) {
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
SDL_GUID guid = SDL_GetJoystickGUIDForID(jid);
|
||||||
|
char guidStr[33];
|
||||||
|
SDL_GUIDToString(guid, guidStr, sizeof(guidStr));
|
||||||
|
const char* name = SDL_GetJoystickNameForID(jid);
|
||||||
|
if (!name || !*name) name = "Standard Gamepad";
|
||||||
|
|
||||||
|
char mapping[512];
|
||||||
|
SDL_snprintf(mapping, sizeof(mapping),
|
||||||
|
"%s,%s,"
|
||||||
|
"a:b0,b:b1,x:b2,y:b3,"
|
||||||
|
"leftshoulder:b4,rightshoulder:b5,"
|
||||||
|
"lefttrigger:b6,righttrigger:b7,"
|
||||||
|
"back:b8,start:b9,"
|
||||||
|
"leftstick:b10,rightstick:b11,"
|
||||||
|
"dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,"
|
||||||
|
"guide:b16,"
|
||||||
|
"leftx:a0,lefty:a1,rightx:a2,righty:a3,"
|
||||||
|
"platform:Emscripten",
|
||||||
|
guidStr,
|
||||||
|
name);
|
||||||
|
SDL_AddGamepadMapping(mapping);
|
||||||
|
#else
|
||||||
|
(void)jid;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
Input* Input::instance = nullptr;
|
Input* Input::instance = nullptr;
|
||||||
|
|
||||||
@@ -83,53 +118,22 @@ auto Input::checkAction(Action action, bool repeat, bool check_keyboard, const s
|
|||||||
|
|
||||||
// Comprueba si hay almenos una acción activa
|
// Comprueba si hay almenos una acción activa
|
||||||
auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr<Gamepad>& gamepad) -> bool {
|
auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr<Gamepad>& gamepad) -> bool {
|
||||||
// Obtenemos el número total de acciones posibles para iterar sobre ellas.
|
const auto JUST_PRESSED = [](const auto& pair) { return pair.second.just_pressed; };
|
||||||
|
|
||||||
// --- Comprobación del Teclado ---
|
if (check_keyboard && std::ranges::any_of(keyboard_.bindings, JUST_PRESSED)) {
|
||||||
if (check_keyboard) {
|
return true;
|
||||||
for (const auto& pair : keyboard_.bindings) {
|
|
||||||
// Simplemente leemos el estado pre-calculado por Input::update().
|
|
||||||
// Ya no se llama a SDL_GetKeyboardState ni se modifica el estado '.active'.
|
|
||||||
if (pair.second.just_pressed) {
|
|
||||||
return true; // Se encontró una acción recién pulsada.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return gamepad != nullptr && std::ranges::any_of(gamepad->bindings, JUST_PRESSED);
|
||||||
// --- Comprobación del Mando ---
|
|
||||||
// Comprobamos si hay mandos y si el índice solicitado es válido.
|
|
||||||
if (gamepad != nullptr) {
|
|
||||||
// Iteramos sobre todas las acciones, no sobre el número de mandos.
|
|
||||||
for (const auto& pair : gamepad->bindings) {
|
|
||||||
// Leemos el estado pre-calculado para el mando y la acción específicos.
|
|
||||||
if (pair.second.just_pressed) {
|
|
||||||
return true; // Se encontró una acción recién pulsada en el mando.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si llegamos hasta aquí, no se detectó ninguna nueva pulsación.
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si hay algún botón pulsado
|
// Comprueba si hay algún botón pulsado
|
||||||
auto Input::checkAnyButton(bool repeat) -> bool {
|
auto Input::checkAnyButton(bool repeat) -> bool {
|
||||||
// Solo comprueba los botones definidos previamente
|
return std::ranges::any_of(BUTTON_INPUTS, [this, repeat](auto bi) {
|
||||||
for (auto bi : BUTTON_INPUTS) {
|
if (checkAction(bi, repeat, CHECK_KEYBOARD)) { return true; }
|
||||||
// Comprueba el teclado
|
return std::ranges::any_of(gamepads_, [this, bi, repeat](const auto& gamepad) {
|
||||||
if (checkAction(bi, repeat, CHECK_KEYBOARD)) {
|
return checkAction(bi, repeat, DO_NOT_CHECK_KEYBOARD, gamepad);
|
||||||
return true;
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
// Comprueba los mandos
|
|
||||||
for (const auto& gamepad : gamepads_) {
|
|
||||||
if (checkAction(bi, repeat, DO_NOT_CHECK_KEYBOARD, gamepad)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si hay algun mando conectado
|
// Comprueba si hay algun mando conectado
|
||||||
@@ -143,9 +147,8 @@ auto Input::getControllerName(const std::shared_ptr<Gamepad>& gamepad) -> std::s
|
|||||||
// Obtiene la lista de nombres de mandos
|
// Obtiene la lista de nombres de mandos
|
||||||
auto Input::getControllerNames() const -> std::vector<std::string> {
|
auto Input::getControllerNames() const -> std::vector<std::string> {
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
for (const auto& gamepad : gamepads_) {
|
names.reserve(gamepads_.size());
|
||||||
names.push_back(gamepad->name);
|
std::ranges::transform(gamepads_, std::back_inserter(names), [](const auto& gamepad) { return gamepad->name; });
|
||||||
}
|
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,21 +157,15 @@ auto Input::getNumGamepads() const -> int { return gamepads_.size(); }
|
|||||||
|
|
||||||
// Obtiene el gamepad a partir de un event.id
|
// Obtiene el gamepad a partir de un event.id
|
||||||
auto Input::getGamepad(SDL_JoystickID id) const -> std::shared_ptr<Input::Gamepad> {
|
auto Input::getGamepad(SDL_JoystickID id) const -> std::shared_ptr<Input::Gamepad> {
|
||||||
for (const auto& gamepad : gamepads_) {
|
const auto IT = std::ranges::find_if(gamepads_,
|
||||||
if (gamepad->instance_id == id) {
|
[id](const auto& gamepad) { return gamepad->instance_id == id; });
|
||||||
return gamepad;
|
return IT != gamepads_.end() ? *IT : nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Input::getGamepadByName(const std::string& name) const -> std::shared_ptr<Input::Gamepad> {
|
auto Input::getGamepadByName(const std::string& name) const -> std::shared_ptr<Input::Gamepad> {
|
||||||
for (const auto& gamepad : gamepads_) {
|
const auto IT = std::ranges::find_if(gamepads_,
|
||||||
if (gamepad && gamepad->name == name) {
|
[&name](const auto& gamepad) { return gamepad && gamepad->name == name; });
|
||||||
return gamepad;
|
return IT != gamepads_.end() ? *IT : nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el SDL_GamepadButton asignado a un action
|
// Obtiene el SDL_GamepadButton asignado a un action
|
||||||
@@ -303,20 +300,6 @@ void Input::addGamepadMappingsFromFile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::discoverGamepads() {
|
|
||||||
// Enumera los gamepads ya conectados sin drenar la cola de eventos de SDL
|
|
||||||
// (necesario con SDL_MAIN_USE_CALLBACKS, que entrega los eventos por SDL_AppEvent).
|
|
||||||
int count = 0;
|
|
||||||
SDL_JoystickID* joysticks = SDL_GetGamepads(&count);
|
|
||||||
if (joysticks == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
addGamepad(joysticks[i]);
|
|
||||||
}
|
|
||||||
SDL_free(joysticks);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Input::initSDLGamePad() {
|
void Input::initSDLGamePad() {
|
||||||
if (SDL_WasInit(SDL_INIT_GAMEPAD) != 1) {
|
if (SDL_WasInit(SDL_INIT_GAMEPAD) != 1) {
|
||||||
if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) {
|
if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) {
|
||||||
@@ -324,7 +307,9 @@ void Input::initSDLGamePad() {
|
|||||||
} else {
|
} else {
|
||||||
addGamepadMappingsFromFile();
|
addGamepadMappingsFromFile();
|
||||||
loadGamepadConfigs();
|
loadGamepadConfigs();
|
||||||
discoverGamepads();
|
// Los mandos ya conectados llegan como SDL_EVENT_GAMEPAD_ADDED en el
|
||||||
|
// primer pase del pump de eventos (antes del primer SDL_AppIterate),
|
||||||
|
// por lo que no hace falta enumerarlos aquí a mano.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,7 +321,7 @@ void Input::resetInputStates() {
|
|||||||
key.second.just_pressed = false;
|
key.second.just_pressed = false;
|
||||||
}
|
}
|
||||||
// Resetear todos los ControllerBindings.active a false
|
// Resetear todos los ControllerBindings.active a false
|
||||||
for (auto& gamepad : gamepads_) {
|
for (const auto& gamepad : gamepads_) {
|
||||||
for (auto& binding : gamepad->bindings) {
|
for (auto& binding : gamepad->bindings) {
|
||||||
binding.second.is_held = false;
|
binding.second.is_held = false;
|
||||||
binding.second.just_pressed = false;
|
binding.second.just_pressed = false;
|
||||||
@@ -375,11 +360,13 @@ auto Input::handleEvent(const SDL_Event& event) -> std::string {
|
|||||||
return addGamepad(event.gdevice.which);
|
return addGamepad(event.gdevice.which);
|
||||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||||
return removeGamepad(event.gdevice.which);
|
return removeGamepad(event.gdevice.which);
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Input::addGamepad(int device_index) -> std::string {
|
auto Input::addGamepad(int device_index) -> std::string {
|
||||||
|
installWebStandardMapping(device_index);
|
||||||
SDL_Gamepad* pad = SDL_OpenGamepad(device_index);
|
SDL_Gamepad* pad = SDL_OpenGamepad(device_index);
|
||||||
if (pad == nullptr) {
|
if (pad == nullptr) {
|
||||||
std::cerr << "Error al abrir el gamepad: " << SDL_GetError() << '\n';
|
std::cerr << "Error al abrir el gamepad: " << SDL_GetError() << '\n';
|
||||||
@@ -444,6 +431,27 @@ void Input::applyGamepadConfig(std::shared_ptr<Gamepad> gamepad) {
|
|||||||
return config.path == gamepad->path;
|
return config.path == gamepad->path;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fallback por nombre: si el mismo dispositivo se enchufa a otro puerto, su
|
||||||
|
// path cambia pero el nombre suele mantenerse. Recuperamos su configuración
|
||||||
|
// y actualizamos el path guardado al actual. Solo se acepta un match cuyo
|
||||||
|
// path guardado NO corresponda a otro mando ya conectado, para no arruinar
|
||||||
|
// setups con varios mandos idénticos en puertos distintos (cabinet arcade).
|
||||||
|
if (config_it == gamepad_configs_.end() && !gamepad->name.empty()) {
|
||||||
|
auto is_path_active = [this](const std::string& query_path) -> bool {
|
||||||
|
return std::ranges::any_of(gamepads_, [&query_path](const std::shared_ptr<Gamepad>& g) -> bool {
|
||||||
|
return g && g->path == query_path;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
config_it = std::ranges::find_if(gamepad_configs_, [&gamepad, &is_path_active](const GamepadConfig& config) -> bool {
|
||||||
|
return config.name == gamepad->name && !is_path_active(config.path);
|
||||||
|
});
|
||||||
|
if (config_it != gamepad_configs_.end()) {
|
||||||
|
std::cout << "Gamepad '" << gamepad->name << "' found by name, refreshing path to: " << gamepad->path << '\n';
|
||||||
|
config_it->path = gamepad->path;
|
||||||
|
saveGamepadConfigs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (config_it != gamepad_configs_.end()) {
|
if (config_it != gamepad_configs_.end()) {
|
||||||
// Se encontró una configuración específica para este puerto/dispositivo. La aplicamos.
|
// Se encontró una configuración específica para este puerto/dispositivo. La aplicamos.
|
||||||
std::cout << "Applying custom config for gamepad at path: " << gamepad->path << '\n';
|
std::cout << "Applying custom config for gamepad at path: " << gamepad->path << '\n';
|
||||||
@@ -453,7 +461,6 @@ void Input::applyGamepadConfig(std::shared_ptr<Gamepad> gamepad) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Opcional: Podrías añadir un fallback para buscar por nombre si no se encuentra por ruta.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad) {
|
void Input::saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad) {
|
||||||
@@ -524,19 +531,11 @@ auto Input::findAvailableGamepadByName(const std::string& gamepad_name) -> std::
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buscar por nombre
|
// Buscar por nombre
|
||||||
for (const auto& gamepad : gamepads_) {
|
auto by_name = std::ranges::find_if(gamepads_,
|
||||||
if (gamepad && gamepad->name == gamepad_name) {
|
[&gamepad_name](const auto& gamepad) { return gamepad && gamepad->name == gamepad_name; });
|
||||||
return gamepad;
|
if (by_name != gamepads_.end()) { return *by_name; }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si no se encuentra por nombre, devolver el primer gamepad válido
|
// Si no se encuentra por nombre, devolver el primer gamepad válido
|
||||||
for (const auto& gamepad : gamepads_) {
|
auto first_valid = std::ranges::find_if(gamepads_, [](const auto& gamepad) { return gamepad != nullptr; });
|
||||||
if (gamepad) {
|
return first_valid != gamepads_.end() ? *first_valid : nullptr;
|
||||||
return gamepad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si llegamos aquí, no hay gamepads válidos
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
@@ -6,11 +6,10 @@
|
|||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
#include <string> // Para string, basic_string
|
#include <string> // Para string, basic_string
|
||||||
#include <unordered_map> // Para unordered_map
|
#include <unordered_map> // Para unordered_map
|
||||||
#include <utility> // Para pair
|
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "gamepad_config_manager.hpp" // for GamepadConfig (ptr only), GamepadConfigs
|
#include "core/input/gamepad_config_manager.hpp" // for GamepadConfig (ptr only), GamepadConfigs
|
||||||
#include "input_types.hpp" // for InputAction
|
#include "core/input/input_types.hpp" // for InputAction
|
||||||
|
|
||||||
// --- Clase Input: gestiona la entrada de teclado y mandos (singleton) ---
|
// --- Clase Input: gestiona la entrada de teclado y mandos (singleton) ---
|
||||||
class Input {
|
class Input {
|
||||||
@@ -32,7 +31,7 @@ class Input {
|
|||||||
bool is_held; // Está pulsada ahora mismo
|
bool is_held; // Está pulsada ahora mismo
|
||||||
bool just_pressed; // Se acaba de pulsar en este fotograma
|
bool just_pressed; // Se acaba de pulsar en este fotograma
|
||||||
|
|
||||||
KeyState(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false)
|
explicit KeyState(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false)
|
||||||
: scancode(scancode),
|
: scancode(scancode),
|
||||||
is_held(is_held),
|
is_held(is_held),
|
||||||
just_pressed(just_pressed) {}
|
just_pressed(just_pressed) {}
|
||||||
@@ -45,7 +44,7 @@ class Input {
|
|||||||
bool axis_active; // Estado del eje
|
bool axis_active; // Estado del eje
|
||||||
bool trigger_active{false}; // Estado del trigger como botón digital
|
bool trigger_active{false}; // Estado del trigger como botón digital
|
||||||
|
|
||||||
ButtonState(int btn = static_cast<int>(SDL_GAMEPAD_BUTTON_INVALID), bool is_held = false, bool just_pressed = false, bool axis_act = false)
|
explicit ButtonState(int btn = static_cast<int>(SDL_GAMEPAD_BUTTON_INVALID), bool is_held = false, bool just_pressed = false, bool axis_act = false)
|
||||||
: button(btn),
|
: button(btn),
|
||||||
is_held(is_held),
|
is_held(is_held),
|
||||||
just_pressed(just_pressed),
|
just_pressed(just_pressed),
|
||||||
@@ -84,7 +83,6 @@ class Input {
|
|||||||
{Action::TOGGLE_VIDEO_POSTFX, KeyState(SDL_SCANCODE_F4)},
|
{Action::TOGGLE_VIDEO_POSTFX, KeyState(SDL_SCANCODE_F4)},
|
||||||
{Action::NEXT_SHADER, KeyState(SDL_SCANCODE_8)},
|
{Action::NEXT_SHADER, KeyState(SDL_SCANCODE_8)},
|
||||||
{Action::NEXT_POSTFX_PRESET, KeyState(SDL_SCANCODE_9)},
|
{Action::NEXT_POSTFX_PRESET, KeyState(SDL_SCANCODE_9)},
|
||||||
{Action::TOGGLE_SUPERSAMPLING, KeyState(SDL_SCANCODE_0)},
|
|
||||||
{Action::TOGGLE_VIDEO_INTEGER_SCALE, KeyState(SDL_SCANCODE_F5)},
|
{Action::TOGGLE_VIDEO_INTEGER_SCALE, KeyState(SDL_SCANCODE_F5)},
|
||||||
{Action::TOGGLE_VIDEO_VSYNC, KeyState(SDL_SCANCODE_F6)},
|
{Action::TOGGLE_VIDEO_VSYNC, KeyState(SDL_SCANCODE_F6)},
|
||||||
|
|
||||||
@@ -105,10 +103,20 @@ class Input {
|
|||||||
std::string path;
|
std::string path;
|
||||||
std::unordered_map<Action, ButtonState> bindings;
|
std::unordered_map<Action, ButtonState> bindings;
|
||||||
|
|
||||||
Gamepad(SDL_Gamepad* gamepad)
|
// Recorta el nombre del mando hasta el primer '(' o '[' y elimina espacios finales.
|
||||||
|
// Evita nombres como "Retroid Controller (vendor: 1001) ..." en las notificaciones.
|
||||||
|
static auto trimName(const char* raw) -> std::string {
|
||||||
|
std::string s(raw != nullptr ? raw : "");
|
||||||
|
const auto POS = s.find_first_of("([");
|
||||||
|
if (POS != std::string::npos) { s.erase(POS); }
|
||||||
|
while (!s.empty() && s.back() == ' ') { s.pop_back(); }
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit Gamepad(SDL_Gamepad* gamepad)
|
||||||
: pad(gamepad),
|
: pad(gamepad),
|
||||||
instance_id(SDL_GetJoystickID(SDL_GetGamepadJoystick(gamepad))),
|
instance_id(SDL_GetJoystickID(SDL_GetGamepadJoystick(gamepad))),
|
||||||
name(std::string(SDL_GetGamepadName(gamepad))),
|
name(trimName(SDL_GetGamepadName(gamepad))),
|
||||||
path(std::string(SDL_GetGamepadPath(pad))),
|
path(std::string(SDL_GetGamepadPath(pad))),
|
||||||
bindings{
|
bindings{
|
||||||
// Movimiento del jugador
|
// Movimiento del jugador
|
||||||
@@ -138,7 +146,7 @@ class Input {
|
|||||||
|
|
||||||
// Reasigna un botón a una acción
|
// Reasigna un botón a una acción
|
||||||
void rebindAction(Action action, SDL_GamepadButton new_button) {
|
void rebindAction(Action action, SDL_GamepadButton new_button) {
|
||||||
bindings[action] = static_cast<int>(new_button);
|
bindings[action] = ButtonState{static_cast<int>(new_button)};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -206,7 +214,6 @@ class Input {
|
|||||||
auto addGamepad(int device_index) -> std::string;
|
auto addGamepad(int device_index) -> std::string;
|
||||||
auto removeGamepad(SDL_JoystickID id) -> std::string;
|
auto removeGamepad(SDL_JoystickID id) -> std::string;
|
||||||
void addGamepadMappingsFromFile();
|
void addGamepadMappingsFromFile();
|
||||||
void discoverGamepads();
|
|
||||||
|
|
||||||
// --- Métodos para integración con GamepadConfigManager ---
|
// --- Métodos para integración con GamepadConfigManager ---
|
||||||
void loadGamepadConfigs();
|
void loadGamepadConfigs();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "input_types.hpp"
|
#include "core/input/input_types.hpp"
|
||||||
|
|
||||||
#include <utility> // Para pair
|
#include <utility> // Para pair
|
||||||
|
|
||||||
@@ -24,7 +24,6 @@ const std::unordered_map<InputAction, std::string> ACTION_TO_STRING = {
|
|||||||
{InputAction::TOGGLE_VIDEO_POSTFX, "TOGGLE_VIDEO_POSTFX"},
|
{InputAction::TOGGLE_VIDEO_POSTFX, "TOGGLE_VIDEO_POSTFX"},
|
||||||
{InputAction::NEXT_SHADER, "NEXT_SHADER"},
|
{InputAction::NEXT_SHADER, "NEXT_SHADER"},
|
||||||
{InputAction::NEXT_POSTFX_PRESET, "NEXT_POSTFX_PRESET"},
|
{InputAction::NEXT_POSTFX_PRESET, "NEXT_POSTFX_PRESET"},
|
||||||
{InputAction::TOGGLE_SUPERSAMPLING, "TOGGLE_SUPERSAMPLING"},
|
|
||||||
{InputAction::TOGGLE_VIDEO_INTEGER_SCALE, "TOGGLE_VIDEO_INTEGER_SCALE"},
|
{InputAction::TOGGLE_VIDEO_INTEGER_SCALE, "TOGGLE_VIDEO_INTEGER_SCALE"},
|
||||||
{InputAction::TOGGLE_VIDEO_VSYNC, "TOGGLE_VIDEO_VSYNC"},
|
{InputAction::TOGGLE_VIDEO_VSYNC, "TOGGLE_VIDEO_VSYNC"},
|
||||||
{InputAction::RESET, "RESET"},
|
{InputAction::RESET, "RESET"},
|
||||||
@@ -57,7 +56,6 @@ const std::unordered_map<std::string, InputAction> STRING_TO_ACTION = {
|
|||||||
{"TOGGLE_VIDEO_POSTFX", InputAction::TOGGLE_VIDEO_POSTFX},
|
{"TOGGLE_VIDEO_POSTFX", InputAction::TOGGLE_VIDEO_POSTFX},
|
||||||
{"NEXT_SHADER", InputAction::NEXT_SHADER},
|
{"NEXT_SHADER", InputAction::NEXT_SHADER},
|
||||||
{"NEXT_POSTFX_PRESET", InputAction::NEXT_POSTFX_PRESET},
|
{"NEXT_POSTFX_PRESET", InputAction::NEXT_POSTFX_PRESET},
|
||||||
{"TOGGLE_SUPERSAMPLING", InputAction::TOGGLE_SUPERSAMPLING},
|
|
||||||
{"TOGGLE_VIDEO_INTEGER_SCALE", InputAction::TOGGLE_VIDEO_INTEGER_SCALE},
|
{"TOGGLE_VIDEO_INTEGER_SCALE", InputAction::TOGGLE_VIDEO_INTEGER_SCALE},
|
||||||
{"TOGGLE_VIDEO_VSYNC", InputAction::TOGGLE_VIDEO_VSYNC},
|
{"TOGGLE_VIDEO_VSYNC", InputAction::TOGGLE_VIDEO_VSYNC},
|
||||||
{"RESET", InputAction::RESET},
|
{"RESET", InputAction::RESET},
|
||||||
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class InputAction : int { // Acciones de entrada posibles en el juego
|
enum class InputAction : std::uint8_t { // Acciones de entrada posibles en el juego
|
||||||
// Inputs de movimiento
|
// Inputs de movimiento
|
||||||
UP,
|
UP,
|
||||||
DOWN,
|
DOWN,
|
||||||
@@ -34,7 +35,6 @@ enum class InputAction : int { // Acciones de entrada posibles en el juego
|
|||||||
TOGGLE_VIDEO_POSTFX,
|
TOGGLE_VIDEO_POSTFX,
|
||||||
NEXT_SHADER,
|
NEXT_SHADER,
|
||||||
NEXT_POSTFX_PRESET,
|
NEXT_POSTFX_PRESET,
|
||||||
TOGGLE_SUPERSAMPLING,
|
|
||||||
TOGGLE_VIDEO_INTEGER_SCALE,
|
TOGGLE_VIDEO_INTEGER_SCALE,
|
||||||
TOGGLE_VIDEO_VSYNC,
|
TOGGLE_VIDEO_VSYNC,
|
||||||
RESET,
|
RESET,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "mouse.hpp"
|
#include "core/input/mouse.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_GetTicks, Uint32, SDL_HideCursor, SDL_Show...
|
#include <SDL3/SDL.h> // Para SDL_GetTicks, Uint32, SDL_HideCursor, SDL_Show...
|
||||||
|
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// --- Clase PauseManager: maneja el sistema de pausa del juego ---
|
// --- Clase PauseManager: maneja el sistema de pausa del juego ---
|
||||||
class PauseManager {
|
class PauseManager {
|
||||||
@@ -18,11 +20,11 @@ class PauseManager {
|
|||||||
|
|
||||||
// --- Operadores friend ---
|
// --- Operadores friend ---
|
||||||
friend auto operator|(Source a, Source b) -> Source {
|
friend auto operator|(Source a, Source b) -> Source {
|
||||||
return static_cast<Source>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b)); // NOLINT(readability-redundant-casting)
|
return static_cast<Source>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend auto operator&(Source a, Source b) -> Source {
|
friend auto operator&(Source a, Source b) -> Source {
|
||||||
return static_cast<Source>(static_cast<uint8_t>(a) & static_cast<uint8_t>(b)); // NOLINT(readability-redundant-casting)
|
return static_cast<Source>(static_cast<uint8_t>(a) & static_cast<uint8_t>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend auto operator~(Source a) -> uint8_t {
|
friend auto operator~(Source a) -> uint8_t {
|
||||||
@@ -48,7 +50,7 @@ class PauseManager {
|
|||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void setFlag(Source source, bool enable) { // Establece/quita una fuente de pausa específica
|
void setFlag(Source source, bool enable) { // Establece/quita una fuente de pausa específica
|
||||||
bool was_paused = isPaused();
|
const bool WAS_PAUSED = isPaused();
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
flags_ |= source;
|
flags_ |= source;
|
||||||
@@ -56,7 +58,8 @@ class PauseManager {
|
|||||||
flags_ &= ~source; // Ahora funciona: Source &= uint8_t
|
flags_ &= ~source; // Ahora funciona: Source &= uint8_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (was_paused != isPaused()) {
|
// cppcheck-suppress knownConditionTrueFalse // false-positive: flags_ ha estat modificat entre les dues crides a isPaused()
|
||||||
|
if (WAS_PAUSED != isPaused()) {
|
||||||
notifyPauseChanged();
|
notifyPauseChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,30 +91,16 @@ class PauseManager {
|
|||||||
return "Active";
|
return "Active";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
if (hasFlag(Source::PLAYER)) { parts.emplace_back("Player"); }
|
||||||
|
if (hasFlag(Source::SERVICE_MENU)) { parts.emplace_back("ServiceMenu"); }
|
||||||
|
if (hasFlag(Source::FOCUS_LOST)) { parts.emplace_back("FocusLoss"); }
|
||||||
|
|
||||||
std::string result = "Paused by: ";
|
std::string result = "Paused by: ";
|
||||||
bool first = true;
|
for (size_t i = 0; i < parts.size(); ++i) {
|
||||||
|
if (i > 0) { result += ", "; }
|
||||||
if (hasFlag(Source::PLAYER)) {
|
result += parts[i];
|
||||||
if (!first) {
|
|
||||||
result += ", ";
|
|
||||||
}
|
|
||||||
result += "Player";
|
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
if (hasFlag(Source::SERVICE_MENU)) {
|
|
||||||
if (!first) {
|
|
||||||
result += ", ";
|
|
||||||
}
|
|
||||||
result += "ServiceMenu";
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
if (hasFlag(Source::FOCUS_LOST)) {
|
|
||||||
if (!first) {
|
|
||||||
result += ", ";
|
|
||||||
}
|
|
||||||
result += "FocusLoss";
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void setCallback(std::function<void(bool)> callback) { // Permite cambiar el callback en runtime
|
void setCallback(std::function<void(bool)> callback) { // Permite cambiar el callback en runtime
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "lang.hpp"
|
#include "core/locale/lang.hpp"
|
||||||
|
|
||||||
|
#include <algorithm> // Para ranges::find_if
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
#include <exception> // Para exception
|
#include <exception> // Para exception
|
||||||
#include <fstream> // Para basic_ifstream, basic_istream, ifstream
|
#include <fstream> // Para basic_ifstream, basic_istream, ifstream
|
||||||
@@ -7,13 +8,13 @@
|
|||||||
#include <utility> // Para pair
|
#include <utility> // Para pair
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "asset.hpp" // Para Asset
|
#include "core/resources/asset.hpp" // Para Asset
|
||||||
#include "difficulty.hpp" // Para Difficulty
|
#include "core/resources/resource_helper.hpp" // Para ResourceHelper
|
||||||
#include "external/json.hpp" // Para basic_json, iteration_proxy_value, oper...
|
#include "external/json.hpp" // Para basic_json, iteration_proxy_value, oper...
|
||||||
#include "options.hpp" // Para SettingsOpt...
|
#include "game/gameplay/difficulty.hpp" // Para Difficulty
|
||||||
#include "resource_helper.hpp" // Para ResourceHelper
|
#include "game/options.hpp" // Para SettingsOpt...
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using Json = nlohmann::json;
|
||||||
|
|
||||||
namespace Lang {
|
namespace Lang {
|
||||||
std::unordered_map<std::string, std::string> texts;
|
std::unordered_map<std::string, std::string> texts;
|
||||||
@@ -32,12 +33,12 @@ namespace Lang {
|
|||||||
auto resource_data = ResourceHelper::loadFile(file_path);
|
auto resource_data = ResourceHelper::loadFile(file_path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
json j;
|
Json j;
|
||||||
|
|
||||||
if (!resource_data.empty()) {
|
if (!resource_data.empty()) {
|
||||||
// Cargar desde datos del pack
|
// Cargar desde datos del pack
|
||||||
std::string content(resource_data.begin(), resource_data.end());
|
std::string content(resource_data.begin(), resource_data.end());
|
||||||
j = json::parse(content);
|
j = Json::parse(content);
|
||||||
} else {
|
} else {
|
||||||
// Fallback a filesystem directo
|
// Fallback a filesystem directo
|
||||||
std::ifstream rfile(file_path);
|
std::ifstream rfile(file_path);
|
||||||
@@ -80,35 +81,23 @@ namespace Lang {
|
|||||||
|
|
||||||
// Obtiene un idioma del vector de idiomas a partir de un código
|
// Obtiene un idioma del vector de idiomas a partir de un código
|
||||||
auto getLanguage(Code code) -> Language {
|
auto getLanguage(Code code) -> Language {
|
||||||
for (const auto& lang : languages) {
|
const auto IT = std::ranges::find_if(languages,
|
||||||
if (lang.code == code) {
|
[code](const auto& lang) { return lang.code == code; });
|
||||||
return lang;
|
return IT != languages.end() ? *IT : languages[0];
|
||||||
}
|
|
||||||
}
|
|
||||||
// Si no se encuentra, devuelve el primero por defecto
|
|
||||||
return languages[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Devuelve el código de un idioma a partir de un nombre
|
// Devuelve el código de un idioma a partir de un nombre
|
||||||
auto getCodeFromName(const std::string& name) -> Code {
|
auto getCodeFromName(const std::string& name) -> Code {
|
||||||
for (const auto& lang : languages) {
|
const auto IT = std::ranges::find_if(languages,
|
||||||
if (lang.name == name) {
|
[&name](const auto& lang) { return lang.name == name; });
|
||||||
return lang.code;
|
return IT != languages.end() ? IT->code : languages[0].code;
|
||||||
}
|
|
||||||
}
|
|
||||||
// Si no se encuentra, devuelve el primero por defecto
|
|
||||||
return languages[0].code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Devuelve el nombre de un idioma a partir de un código
|
// Devuelve el nombre de un idioma a partir de un código
|
||||||
auto getNameFromCode(Code code) -> std::string {
|
auto getNameFromCode(Code code) -> std::string {
|
||||||
for (const auto& lang : languages) {
|
const auto IT = std::ranges::find_if(languages,
|
||||||
if (lang.code == code) {
|
[code](const auto& lang) { return lang.code == code; });
|
||||||
return lang.name;
|
return IT != languages.end() ? IT->name : languages[0].name;
|
||||||
}
|
|
||||||
}
|
|
||||||
// Si no se encuentra, devuelve el nombre del primer idioma por defecto
|
|
||||||
return languages[0].name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza los nombres de los idiomas
|
// Actualiza los nombres de los idiomas
|
||||||
@@ -155,13 +144,10 @@ namespace Lang {
|
|||||||
|
|
||||||
// Obtiene una fichero a partir de un lang::Code
|
// Obtiene una fichero a partir de un lang::Code
|
||||||
auto getLanguageFileName(Lang::Code code) -> std::string {
|
auto getLanguageFileName(Lang::Code code) -> std::string {
|
||||||
for (const auto& lang : languages) {
|
const auto IT = std::ranges::find_if(languages,
|
||||||
if (lang.code == code) {
|
[code](const auto& lang) { return lang.code == code; });
|
||||||
return Asset::get()->getPath(lang.file_name);
|
const auto& file = (IT != languages.end()) ? IT->file_name : languages[0].file_name;
|
||||||
}
|
return Asset::get()->getPath(file);
|
||||||
}
|
|
||||||
// Si no se encuentra, devuelve el fichero del primer idioma por defecto
|
|
||||||
return Asset::get()->getPath(languages[0].file_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el idioma
|
// Establece el idioma
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // Para std::uint8_t
|
||||||
#include <string> // Para string, basic_string
|
#include <string> // Para string, basic_string
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
// --- Namespace Lang: gestión de idiomas y textos ---
|
// --- Namespace Lang: gestión de idiomas y textos ---
|
||||||
namespace Lang {
|
namespace Lang {
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class Code : int {
|
enum class Code : std::uint8_t {
|
||||||
SPANISH = 0, // Español
|
SPANISH = 0, // Español
|
||||||
VALENCIAN = 1, // Valenciano
|
VALENCIAN = 1, // Valenciano
|
||||||
ENGLISH = 2 // Inglés
|
ENGLISH = 2 // Inglés
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
|
// NOLINTNEXTLINE(bugprone-reserved-identifier) -- requerido por <cmath> para exponer M_PI en MSVC
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include "background.hpp"
|
#include "core/rendering/background.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetRenderTarget, SDL_RenderTexture, SDL_SetTextureAlphaMod, SDL_SetTextureBlendMode, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_TextureAccess, SDL_FPoint
|
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetRenderTarget, SDL_RenderTexture, SDL_SetTextureAlphaMod, SDL_SetTextureBlendMode, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_TextureAccess, SDL_FPoint
|
||||||
|
|
||||||
@@ -8,14 +9,14 @@
|
|||||||
#include <string> // Para basic_string
|
#include <string> // Para basic_string
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
#include "animated_sprite.hpp" // Para AnimatedSprite
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "moving_sprite.hpp" // Para MovingSprite
|
#include "core/rendering/sprite/animated_sprite.hpp" // Para AnimatedSprite
|
||||||
#include "param.hpp" // Para Param, ParamBackground, param
|
#include "core/rendering/sprite/moving_sprite.hpp" // Para MovingSprite
|
||||||
#include "resource.hpp" // Para Resource
|
#include "core/rendering/sprite/sprite.hpp" // Para Sprite
|
||||||
#include "screen.hpp" // Para Screen
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
#include "sprite.hpp" // Para Sprite
|
#include "core/resources/resource.hpp" // Para Resource
|
||||||
#include "texture.hpp" // Para Texture
|
#include "utils/param.hpp" // Para Param, ParamBackground, param
|
||||||
#include "utils.hpp" // Para easeOutCubic
|
#include "utils/utils.hpp" // Para easeOutCubic
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Background::Background(float total_progress_to_complete)
|
Background::Background(float total_progress_to_complete)
|
||||||
@@ -29,10 +30,10 @@ Background::Background(float total_progress_to_complete)
|
|||||||
moon_texture_(Resource::get()->getTexture("game_moon.png")),
|
moon_texture_(Resource::get()->getTexture("game_moon.png")),
|
||||||
grass_sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("game_grass.png"), Resource::get()->getAnimation("game_grass.ani"))),
|
grass_sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("game_grass.png"), Resource::get()->getAnimation("game_grass.ani"))),
|
||||||
|
|
||||||
total_progress_to_complete_(total_progress_to_complete),
|
TOTAL_PROGRESS_TO_COMPLETE(total_progress_to_complete),
|
||||||
progress_per_stage_(total_progress_to_complete_ / STAGES),
|
PROGRESS_PER_STAGE(TOTAL_PROGRESS_TO_COMPLETE / STAGES),
|
||||||
sun_completion_progress_(total_progress_to_complete_ * SUN_COMPLETION_FACTOR),
|
SUM_COMPLETION_PROGRESS(TOTAL_PROGRESS_TO_COMPLETE * SUN_COMPLETION_FACTOR),
|
||||||
minimum_completed_progress_(total_progress_to_complete_ * MINIMUM_COMPLETED_PROGRESS_PERCENTAGE),
|
MINIMUM_COMPLETED_PROGRESS(TOTAL_PROGRESS_TO_COMPLETE * MINIMUM_COMPLETED_PROGRESS_PERCENTAGE),
|
||||||
|
|
||||||
rect_(SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(gradients_texture_->getWidth() / 2), .h = static_cast<float>(gradients_texture_->getHeight() / 2)}),
|
rect_(SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(gradients_texture_->getWidth() / 2), .h = static_cast<float>(gradients_texture_->getHeight() / 2)}),
|
||||||
src_rect_({.x = 0, .y = 0, .w = 320, .h = 240}),
|
src_rect_({.x = 0, .y = 0, .w = 320, .h = 240}),
|
||||||
@@ -82,11 +83,11 @@ void Background::initializeSprites() {
|
|||||||
const float TOP_CLOUDS_Y = base_ - 165;
|
const float TOP_CLOUDS_Y = base_ - 165;
|
||||||
const float BOTTOM_CLOUDS_Y = base_ - 101;
|
const float BOTTOM_CLOUDS_Y = base_ - 101;
|
||||||
|
|
||||||
top_clouds_sprite_a_ = std::make_unique<MovingSprite>(top_clouds_texture_, (SDL_FRect){.x = 0, .y = TOP_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(top_clouds_texture_->getHeight())});
|
top_clouds_sprite_a_ = std::make_unique<MovingSprite>(top_clouds_texture_, SDL_FRect{.x = 0, .y = TOP_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(top_clouds_texture_->getHeight())});
|
||||||
top_clouds_sprite_b_ = std::make_unique<MovingSprite>(top_clouds_texture_, (SDL_FRect){.x = rect_.w, .y = TOP_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(top_clouds_texture_->getHeight())});
|
top_clouds_sprite_b_ = std::make_unique<MovingSprite>(top_clouds_texture_, SDL_FRect{.x = rect_.w, .y = TOP_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(top_clouds_texture_->getHeight())});
|
||||||
|
|
||||||
bottom_clouds_sprite_a_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, (SDL_FRect){.x = 0, .y = BOTTOM_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(bottom_clouds_texture_->getHeight())});
|
bottom_clouds_sprite_a_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, SDL_FRect{.x = 0, .y = BOTTOM_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(bottom_clouds_texture_->getHeight())});
|
||||||
bottom_clouds_sprite_b_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, (SDL_FRect){.x = rect_.w, .y = BOTTOM_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(bottom_clouds_texture_->getHeight())});
|
bottom_clouds_sprite_b_ = std::make_unique<MovingSprite>(bottom_clouds_texture_, SDL_FRect{.x = rect_.w, .y = BOTTOM_CLOUDS_Y, .w = rect_.w, .h = static_cast<float>(bottom_clouds_texture_->getHeight())});
|
||||||
|
|
||||||
buildings_sprite_ = std::make_unique<Sprite>(buildings_texture_);
|
buildings_sprite_ = std::make_unique<Sprite>(buildings_texture_);
|
||||||
gradient_sprite_ = std::make_unique<Sprite>(gradients_texture_, 0, 0, rect_.w, rect_.h);
|
gradient_sprite_ = std::make_unique<Sprite>(gradients_texture_, 0, 0, rect_.w, rect_.h);
|
||||||
@@ -167,7 +168,7 @@ void Background::incrementProgress(float amount) {
|
|||||||
if (state_ == State::NORMAL) {
|
if (state_ == State::NORMAL) {
|
||||||
float old_progress = progress_;
|
float old_progress = progress_;
|
||||||
progress_ += amount;
|
progress_ += amount;
|
||||||
progress_ = std::min(progress_, total_progress_to_complete_);
|
progress_ = std::min(progress_, TOTAL_PROGRESS_TO_COMPLETE);
|
||||||
|
|
||||||
// Notifica el cambio si hay callback y el progreso cambió
|
// Notifica el cambio si hay callback y el progreso cambió
|
||||||
if (progress_callback_ && progress_ != old_progress) {
|
if (progress_callback_ && progress_ != old_progress) {
|
||||||
@@ -179,7 +180,7 @@ void Background::incrementProgress(float amount) {
|
|||||||
// Establece la progresión absoluta
|
// Establece la progresión absoluta
|
||||||
void Background::setProgress(float absolute_progress) {
|
void Background::setProgress(float absolute_progress) {
|
||||||
float old_progress = progress_;
|
float old_progress = progress_;
|
||||||
progress_ = std::clamp(absolute_progress, 0.0F, total_progress_to_complete_);
|
progress_ = std::clamp(absolute_progress, 0.0F, TOTAL_PROGRESS_TO_COMPLETE);
|
||||||
|
|
||||||
// Notifica el cambio si hay callback y el progreso cambió
|
// Notifica el cambio si hay callback y el progreso cambió
|
||||||
if (progress_callback_ && progress_ != old_progress) {
|
if (progress_callback_ && progress_ != old_progress) {
|
||||||
@@ -282,27 +283,27 @@ void Background::updateProgression(float delta_time) {
|
|||||||
float eased_t = easeOutCubic(static_cast<double>(t));
|
float eased_t = easeOutCubic(static_cast<double>(t));
|
||||||
|
|
||||||
// Interpolación desde progreso inicial hasta mínimo
|
// Interpolación desde progreso inicial hasta mínimo
|
||||||
float progress_range = completion_initial_progress_ - minimum_completed_progress_;
|
float progress_range = completion_initial_progress_ - MINIMUM_COMPLETED_PROGRESS;
|
||||||
progress_ = completion_initial_progress_ - (progress_range * eased_t);
|
progress_ = completion_initial_progress_ - (progress_range * eased_t);
|
||||||
} else {
|
} else {
|
||||||
// Transición completada, fijar al valor mínimo
|
// Transición completada, fijar al valor mínimo
|
||||||
progress_ = minimum_completed_progress_;
|
progress_ = MINIMUM_COMPLETED_PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula la transición de los diferentes fondos
|
// Calcula la transición de los diferentes fondos
|
||||||
const float GRADIENT_NUMBER_FLOAT = std::min(progress_ / progress_per_stage_, 3.0F);
|
const float GRADIENT_NUMBER_FLOAT = std::min(progress_ / PROGRESS_PER_STAGE, 3.0F);
|
||||||
const float PERCENT = GRADIENT_NUMBER_FLOAT - static_cast<int>(GRADIENT_NUMBER_FLOAT);
|
const float PERCENT = GRADIENT_NUMBER_FLOAT - static_cast<int>(GRADIENT_NUMBER_FLOAT);
|
||||||
|
|
||||||
gradient_number_ = static_cast<size_t>(GRADIENT_NUMBER_FLOAT);
|
gradient_number_ = static_cast<size_t>(GRADIENT_NUMBER_FLOAT);
|
||||||
transition_ = PERCENT;
|
transition_ = PERCENT;
|
||||||
|
|
||||||
// Calcula la posición del sol
|
// Calcula la posición del sol
|
||||||
const float SUN_PROGRESSION = std::min(progress_ / sun_completion_progress_, 1.0F);
|
const float SUN_PROGRESSION = std::min(progress_ / SUM_COMPLETION_PROGRESS, 1.0F);
|
||||||
sun_index_ = static_cast<size_t>(SUN_PROGRESSION * (sun_path_.size() - 1));
|
sun_index_ = static_cast<size_t>(SUN_PROGRESSION * (sun_path_.size() - 1));
|
||||||
|
|
||||||
// Calcula la posición de la luna
|
// Calcula la posición de la luna
|
||||||
const float MOON_PROGRESSION = std::min(progress_ / total_progress_to_complete_, 1.0F);
|
const float MOON_PROGRESSION = std::min(progress_ / TOTAL_PROGRESS_TO_COMPLETE, 1.0F);
|
||||||
moon_index_ = static_cast<size_t>(MOON_PROGRESSION * (moon_path_.size() - 1));
|
moon_index_ = static_cast<size_t>(MOON_PROGRESSION * (moon_path_.size() - 1));
|
||||||
|
|
||||||
// Actualiza la velocidad de las nubes
|
// Actualiza la velocidad de las nubes
|
||||||
@@ -318,12 +319,12 @@ void Background::updateCloudsSpeed() {
|
|||||||
|
|
||||||
// Velocidad base según progreso (de -3.0 a -120.0 píxeles/segundo, igual que la versión original)
|
// Velocidad base según progreso (de -3.0 a -120.0 píxeles/segundo, igual que la versión original)
|
||||||
float base_clouds_speed = (-CLOUDS_INITIAL_SPEED_PX_PER_S) +
|
float base_clouds_speed = (-CLOUDS_INITIAL_SPEED_PX_PER_S) +
|
||||||
(-CLOUDS_FINAL_SPEED_RANGE_PX_PER_S * (progress_ / total_progress_to_complete_));
|
(-CLOUDS_FINAL_SPEED_RANGE_PX_PER_S * (progress_ / TOTAL_PROGRESS_TO_COMPLETE));
|
||||||
|
|
||||||
// En estado completado, las nubes se ralentizan gradualmente
|
// En estado completado, las nubes se ralentizan gradualmente
|
||||||
if (state_ == State::COMPLETED) {
|
if (state_ == State::COMPLETED) {
|
||||||
float completion_factor = (progress_ - minimum_completed_progress_) /
|
float completion_factor = (progress_ - MINIMUM_COMPLETED_PROGRESS) /
|
||||||
(total_progress_to_complete_ - minimum_completed_progress_);
|
(TOTAL_PROGRESS_TO_COMPLETE - MINIMUM_COMPLETED_PROGRESS);
|
||||||
completion_factor = std::max(0.1F, completion_factor);
|
completion_factor = std::max(0.1F, completion_factor);
|
||||||
base_clouds_speed *= completion_factor;
|
base_clouds_speed *= completion_factor;
|
||||||
}
|
}
|
||||||
@@ -562,14 +563,13 @@ void Background::createMoonPath() {
|
|||||||
const int FREEZE_START_INDEX = static_cast<int>(NUM_STEPS * (1.0F - FREEZE_PERCENTAGE));
|
const int FREEZE_START_INDEX = static_cast<int>(NUM_STEPS * (1.0F - FREEZE_PERCENTAGE));
|
||||||
|
|
||||||
for (int i = 0; i < NUM_STEPS; ++i) {
|
for (int i = 0; i < NUM_STEPS; ++i) {
|
||||||
double theta = i * STEP;
|
|
||||||
float x = CENTER_X + (RADIUS * cos(theta));
|
|
||||||
float y = CENTER_Y - (RADIUS * sin(theta));
|
|
||||||
|
|
||||||
if (i >= FREEZE_START_INDEX && !moon_path_.empty()) {
|
if (i >= FREEZE_START_INDEX && !moon_path_.empty()) {
|
||||||
moon_path_.push_back(moon_path_.back()); // Repite el último punto válido
|
moon_path_.push_back(moon_path_.back()); // Repite el último punto válido
|
||||||
} else {
|
} else {
|
||||||
moon_path_.push_back({.x = x, .y = y});
|
const double THETA = i * STEP;
|
||||||
|
const float X = CENTER_X + (RADIUS * cos(THETA));
|
||||||
|
const float Y = CENTER_Y - (RADIUS * sin(THETA));
|
||||||
|
moon_path_.push_back({.x = X, .y = Y});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
#include <array> // Para array
|
#include <array> // Para array
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
|
#include <cstdint> // Para std::uint8_t
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
#include <memory> // Para unique_ptr, shared_ptr
|
#include <memory> // Para unique_ptr, shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "color.hpp" // Para Color
|
#include "utils/color.hpp" // Para Color
|
||||||
|
|
||||||
class MovingSprite;
|
class MovingSprite;
|
||||||
class Sprite;
|
class Sprite;
|
||||||
@@ -19,7 +20,7 @@ class AnimatedSprite;
|
|||||||
class Background {
|
class Background {
|
||||||
public:
|
public:
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class State {
|
enum class State : std::uint8_t {
|
||||||
NORMAL, // Progresión normal del día
|
NORMAL, // Progresión normal del día
|
||||||
COMPLETED // Reducción gradual de la actividad
|
COMPLETED // Reducción gradual de la actividad
|
||||||
};
|
};
|
||||||
@@ -28,8 +29,8 @@ class Background {
|
|||||||
using ProgressCallback = std::function<void(float)>; // Callback para sincronización
|
using ProgressCallback = std::function<void(float)>; // Callback para sincronización
|
||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
Background(float total_progress_to_complete = 6100.0F); // Constructor principal
|
explicit Background(float total_progress_to_complete = 6100.0F); // Constructor principal
|
||||||
~Background(); // Destructor
|
~Background(); // Destructor
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void update(float delta_time); // Actualiza la lógica del objeto
|
void update(float delta_time); // Actualiza la lógica del objeto
|
||||||
@@ -87,10 +88,10 @@ class Background {
|
|||||||
std::unique_ptr<AnimatedSprite> grass_sprite_; // Sprite con la hierba
|
std::unique_ptr<AnimatedSprite> grass_sprite_; // Sprite con la hierba
|
||||||
|
|
||||||
// --- Variables de configuración ---
|
// --- Variables de configuración ---
|
||||||
const float total_progress_to_complete_; // Progreso total para completar
|
const float TOTAL_PROGRESS_TO_COMPLETE; // Progreso total para completar
|
||||||
const float progress_per_stage_; // Progreso por etapa
|
const float PROGRESS_PER_STAGE; // Progreso por etapa
|
||||||
const float sun_completion_progress_; // Progreso de completado del sol
|
const float SUM_COMPLETION_PROGRESS; // Progreso de completado del sol
|
||||||
const float minimum_completed_progress_; // Progreso mínimo calculado dinámicamente
|
const float MINIMUM_COMPLETED_PROGRESS; // Progreso mínimo calculado dinámicamente
|
||||||
ProgressCallback progress_callback_; // Callback para notificar cambios de progreso
|
ProgressCallback progress_callback_; // Callback para notificar cambios de progreso
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "fade.hpp"
|
#include "core/rendering/fade.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "color.hpp"
|
#include "core/rendering/screen.hpp"
|
||||||
#include "param.hpp"
|
#include "utils/color.hpp"
|
||||||
#include "screen.hpp"
|
#include "utils/param.hpp"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Fade::Fade()
|
Fade::Fade()
|
||||||
@@ -68,7 +68,7 @@ void Fade::render() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables internas
|
// Actualiza las variables internas
|
||||||
void Fade::update(float delta_time) {
|
void Fade::update(float /*delta_time*/) {
|
||||||
switch (state_) {
|
switch (state_) {
|
||||||
case State::PRE:
|
case State::PRE:
|
||||||
updatePreState();
|
updatePreState();
|
||||||
@@ -481,7 +481,7 @@ void Fade::activate() {
|
|||||||
case Type::DIAGONAL: {
|
case Type::DIAGONAL: {
|
||||||
rect1_ = {.x = 0, .y = 0, .w = static_cast<float>(param.game.width / num_squares_width_), .h = static_cast<float>(param.game.height / num_squares_height_)};
|
rect1_ = {.x = 0, .y = 0, .w = static_cast<float>(param.game.width / num_squares_width_), .h = static_cast<float>(param.game.height / num_squares_height_)};
|
||||||
square_.clear();
|
square_.clear();
|
||||||
square_age_.assign(num_squares_width_ * num_squares_height_, -1);
|
square_age_.assign(static_cast<size_t>(num_squares_width_) * num_squares_height_, -1);
|
||||||
for (int i = 0; i < num_squares_width_ * num_squares_height_; ++i) {
|
for (int i = 0; i < num_squares_width_ * num_squares_height_; ++i) {
|
||||||
rect1_.x = (i % num_squares_width_) * rect1_.w;
|
rect1_.x = (i % num_squares_width_) * rect1_.w;
|
||||||
rect1_.y = (i / num_squares_width_) * rect1_.h;
|
rect1_.y = (i / num_squares_width_) * rect1_.h;
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
#include "core/rendering/gif.hpp"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h> // Para SDL_LogError, SDL_LogCategory, SDL_LogInfo
|
||||||
|
|
||||||
|
#include <cstring> // Para memcpy, size_t
|
||||||
|
#include <iostream> // Para std::cout
|
||||||
|
#include <stdexcept> // Para runtime_error
|
||||||
|
#include <string> // Para char_traits, operator==, basic_string, string
|
||||||
|
|
||||||
|
namespace GIF {
|
||||||
|
namespace {
|
||||||
|
inline void readBytes(const uint8_t *&buffer, void *dst, size_t size) {
|
||||||
|
std::memcpy(dst, buffer, size);
|
||||||
|
buffer += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Llavor del diccionari LZW: 0..N-1 com a entrades base, i salta 2 (clear_code + stop_code).
|
||||||
|
void resetDictionary(std::vector<DictionaryEntry> &dict, int code_length, int &dictionary_ind) {
|
||||||
|
dict.resize(1 << (code_length + 1));
|
||||||
|
for (dictionary_ind = 0; dictionary_ind < (1 << code_length); dictionary_ind++) {
|
||||||
|
dict[dictionary_ind].byte = static_cast<uint8_t>(dictionary_ind);
|
||||||
|
dict[dictionary_ind].prev = -1;
|
||||||
|
dict[dictionary_ind].len = 1;
|
||||||
|
}
|
||||||
|
dictionary_ind += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Llig `code_length + 1` bits LSB-first del flux d'entrada. Llança si s'acaba el buffer.
|
||||||
|
auto readNextCode(const uint8_t *&input, int &input_length, int code_length, unsigned int &mask) -> int {
|
||||||
|
int code = 0;
|
||||||
|
for (int i = 0; i < code_length + 1; i++) {
|
||||||
|
if (input_length <= 0) {
|
||||||
|
std::cout << "Unexpected end of input in decompress" << '\n';
|
||||||
|
throw std::runtime_error("Unexpected end of input in decompress");
|
||||||
|
}
|
||||||
|
const int BIT = ((*input & mask) != 0) ? 1 : 0;
|
||||||
|
mask <<= 1;
|
||||||
|
if (mask == 0x100) {
|
||||||
|
mask = 0x01;
|
||||||
|
input++;
|
||||||
|
input_length--;
|
||||||
|
}
|
||||||
|
code |= (BIT << i);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Afig una nova entrada al diccionari. Resol el cas especial KwKwK (code == dictionary_ind)
|
||||||
|
// començant la cadena des de `prev` en lloc de des de `code`.
|
||||||
|
void addDictionaryEntry(std::vector<DictionaryEntry> &dict, int dictionary_ind, int code, int prev) {
|
||||||
|
int ptr = (code == dictionary_ind) ? prev : code;
|
||||||
|
while (dict[ptr].prev != -1) {
|
||||||
|
ptr = dict[ptr].prev;
|
||||||
|
}
|
||||||
|
dict[dictionary_ind].byte = dict[ptr].byte;
|
||||||
|
dict[dictionary_ind].prev = prev;
|
||||||
|
dict[dictionary_ind].len = dict[prev].len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escriu la cadena de bytes associada a `code` en `out` (en ordre invers seguint .prev).
|
||||||
|
// Retorna la longitud del match per avançar el cursor de l'eixida.
|
||||||
|
auto emitMatch(const std::vector<DictionaryEntry> &dict, int code, uint8_t *out) -> int {
|
||||||
|
const int MATCH_LEN = dict[code].len;
|
||||||
|
int cur_code = code;
|
||||||
|
while (cur_code != -1) {
|
||||||
|
out[dict[cur_code].len - 1] = dict[cur_code].byte;
|
||||||
|
if (dict[cur_code].prev == cur_code) {
|
||||||
|
std::cout << "Internal error; self-reference detected." << '\n';
|
||||||
|
throw std::runtime_error("Internal error in decompress: self-reference");
|
||||||
|
}
|
||||||
|
cur_code = dict[cur_code].prev;
|
||||||
|
}
|
||||||
|
return MATCH_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Descompone (uncompress) el bloque comprimido usando LZW.
|
||||||
|
void decompress(int code_length, const uint8_t *input, int input_length, uint8_t *out) {
|
||||||
|
if (code_length < 2 || code_length > 12) {
|
||||||
|
std::cout << "Invalid LZW code length: " << code_length << '\n';
|
||||||
|
throw std::runtime_error("Invalid LZW code length");
|
||||||
|
}
|
||||||
|
|
||||||
|
int prev = -1;
|
||||||
|
std::vector<DictionaryEntry> dictionary;
|
||||||
|
int dictionary_ind = 0;
|
||||||
|
unsigned int mask = 0x01;
|
||||||
|
const int RESET_CODE_LENGTH = code_length;
|
||||||
|
const int CLEAR_CODE = 1 << code_length;
|
||||||
|
const int STOP_CODE = CLEAR_CODE + 1;
|
||||||
|
|
||||||
|
resetDictionary(dictionary, code_length, dictionary_ind);
|
||||||
|
|
||||||
|
while (input_length > 0) {
|
||||||
|
const int CODE = readNextCode(input, input_length, code_length, mask);
|
||||||
|
|
||||||
|
if (CODE == CLEAR_CODE) {
|
||||||
|
code_length = RESET_CODE_LENGTH;
|
||||||
|
resetDictionary(dictionary, code_length, dictionary_ind);
|
||||||
|
prev = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (CODE == STOP_CODE) { break; }
|
||||||
|
|
||||||
|
if (prev > -1 && code_length < 12) {
|
||||||
|
if (CODE > dictionary_ind) {
|
||||||
|
std::cout << "LZW error: code (" << CODE << ") exceeds dictionary_ind (" << dictionary_ind << ")" << '\n';
|
||||||
|
throw std::runtime_error("LZW error: code exceeds dictionary_ind.");
|
||||||
|
}
|
||||||
|
addDictionaryEntry(dictionary, dictionary_ind, CODE, prev);
|
||||||
|
dictionary_ind++;
|
||||||
|
|
||||||
|
if ((dictionary_ind == (1 << (code_length + 1))) && (code_length < 11)) {
|
||||||
|
code_length++;
|
||||||
|
dictionary.resize(1 << (code_length + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = CODE;
|
||||||
|
|
||||||
|
if (CODE < 0 || static_cast<size_t>(CODE) >= dictionary.size()) {
|
||||||
|
std::cout << "Invalid LZW code " << CODE << ", dictionary size " << static_cast<unsigned long>(dictionary.size()) << '\n';
|
||||||
|
throw std::runtime_error("LZW error: invalid code encountered");
|
||||||
|
}
|
||||||
|
|
||||||
|
out += emitMatch(dictionary, CODE, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lee los sub-bloques de datos y los acumula en un std::vector<uint8_t>.
|
||||||
|
auto readSubBlocks(const uint8_t *&buffer) -> std::vector<uint8_t> {
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
uint8_t block_size = *buffer;
|
||||||
|
buffer++;
|
||||||
|
while (block_size != 0) {
|
||||||
|
data.insert(data.end(), buffer, buffer + block_size);
|
||||||
|
buffer += block_size;
|
||||||
|
block_size = *buffer;
|
||||||
|
buffer++;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Procesa el Image Descriptor y retorna el vector de datos sin comprimir.
|
||||||
|
auto processImageDescriptor(const uint8_t *&buffer, const std::vector<RGB> & /*gct*/, int /*resolution_bits*/) -> std::vector<uint8_t> {
|
||||||
|
ImageDescriptor image_descriptor;
|
||||||
|
readBytes(buffer, &image_descriptor, sizeof(ImageDescriptor));
|
||||||
|
|
||||||
|
uint8_t lzw_code_size;
|
||||||
|
readBytes(buffer, &lzw_code_size, sizeof(uint8_t));
|
||||||
|
|
||||||
|
std::vector<uint8_t> compressed_data = readSubBlocks(buffer);
|
||||||
|
int uncompressed_data_length = image_descriptor.image_width * image_descriptor.image_height;
|
||||||
|
std::vector<uint8_t> uncompressed_data(uncompressed_data_length);
|
||||||
|
|
||||||
|
decompress(lzw_code_size, compressed_data.data(), static_cast<int>(compressed_data.size()), uncompressed_data.data());
|
||||||
|
return uncompressed_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Procesa el stream completo del GIF y devuelve los datos sin comprimir.
|
||||||
|
auto processGifStream(const uint8_t *buffer, uint16_t &w, uint16_t &h) -> std::vector<uint8_t> {
|
||||||
|
uint8_t header[6];
|
||||||
|
std::memcpy(header, buffer, 6);
|
||||||
|
buffer += 6;
|
||||||
|
|
||||||
|
std::string header_str(reinterpret_cast<char *>(header), 6);
|
||||||
|
if (header_str != "GIF87a" && header_str != "GIF89a") {
|
||||||
|
std::cout << "Formato de archivo GIF inválido: " << header_str << '\n';
|
||||||
|
throw std::runtime_error("Formato de archivo GIF inválido.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenDescriptor screen_descriptor;
|
||||||
|
readBytes(buffer, &screen_descriptor, sizeof(ScreenDescriptor));
|
||||||
|
|
||||||
|
w = screen_descriptor.width;
|
||||||
|
h = screen_descriptor.height;
|
||||||
|
|
||||||
|
int color_resolution_bits = ((screen_descriptor.fields & 0x70) >> 4) + 1;
|
||||||
|
std::vector<RGB> global_color_table;
|
||||||
|
if ((screen_descriptor.fields & 0x80) != 0) {
|
||||||
|
const size_t GLOBAL_COLOR_TABLE_SIZE = 1U << (((screen_descriptor.fields & 0x07) + 1));
|
||||||
|
global_color_table.resize(GLOBAL_COLOR_TABLE_SIZE);
|
||||||
|
std::memcpy(global_color_table.data(), buffer, 3 * GLOBAL_COLOR_TABLE_SIZE);
|
||||||
|
buffer += 3 * GLOBAL_COLOR_TABLE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t block_type = *buffer++;
|
||||||
|
while (block_type != TRAILER) {
|
||||||
|
if (block_type == EXTENSION_INTRODUCER) {
|
||||||
|
uint8_t extension_label = *buffer++;
|
||||||
|
switch (extension_label) {
|
||||||
|
case GRAPHIC_CONTROL: {
|
||||||
|
uint8_t block_size = *buffer++;
|
||||||
|
buffer += block_size;
|
||||||
|
uint8_t sub_block_size = *buffer++;
|
||||||
|
while (sub_block_size != 0) {
|
||||||
|
buffer += sub_block_size;
|
||||||
|
sub_block_size = *buffer++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case APPLICATION_EXTENSION:
|
||||||
|
case COMMENT_EXTENSION:
|
||||||
|
case PLAINTEXT_EXTENSION: {
|
||||||
|
uint8_t block_size = *buffer++;
|
||||||
|
buffer += block_size;
|
||||||
|
uint8_t sub_block_size = *buffer++;
|
||||||
|
while (sub_block_size != 0) {
|
||||||
|
buffer += sub_block_size;
|
||||||
|
sub_block_size = *buffer++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
uint8_t block_size = *buffer++;
|
||||||
|
buffer += block_size;
|
||||||
|
uint8_t sub_block_size = *buffer++;
|
||||||
|
while (sub_block_size != 0) {
|
||||||
|
buffer += sub_block_size;
|
||||||
|
sub_block_size = *buffer++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (block_type == IMAGE_DESCRIPTOR) {
|
||||||
|
return processImageDescriptor(buffer, global_color_table, color_resolution_bits);
|
||||||
|
} else {
|
||||||
|
std::cout << "Unrecognized block type: 0x" << std::hex << static_cast<int>(block_type) << std::dec << '\n';
|
||||||
|
return std::vector<uint8_t>{};
|
||||||
|
}
|
||||||
|
block_type = *buffer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::vector<uint8_t>{};
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
auto loadPalette(const uint8_t *buffer) -> std::vector<uint32_t> {
|
||||||
|
uint8_t header[6];
|
||||||
|
std::memcpy(header, buffer, 6);
|
||||||
|
buffer += 6;
|
||||||
|
|
||||||
|
ScreenDescriptor screen_descriptor;
|
||||||
|
std::memcpy(&screen_descriptor, buffer, sizeof(ScreenDescriptor));
|
||||||
|
buffer += sizeof(ScreenDescriptor);
|
||||||
|
|
||||||
|
std::vector<uint32_t> global_color_table;
|
||||||
|
if ((screen_descriptor.fields & 0x80) != 0) {
|
||||||
|
int global_color_table_size = 1 << (((screen_descriptor.fields & 0x07) + 1));
|
||||||
|
global_color_table.resize(global_color_table_size);
|
||||||
|
for (int i = 0; i < global_color_table_size; ++i) {
|
||||||
|
uint8_t r = buffer[0];
|
||||||
|
uint8_t g = buffer[1];
|
||||||
|
uint8_t b = buffer[2];
|
||||||
|
global_color_table[i] = (r << 16) | (g << 8) | b;
|
||||||
|
buffer += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return global_color_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto loadGif(const uint8_t *buffer, uint16_t &w, uint16_t &h) -> std::vector<uint8_t> {
|
||||||
|
return processGifStream(buffer, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace GIF
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t, uint16_t, uint32_t
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
|
namespace GIF {
|
||||||
|
|
||||||
|
// Constantes definidas con constexpr, en lugar de macros
|
||||||
|
constexpr uint8_t EXTENSION_INTRODUCER = 0x21;
|
||||||
|
constexpr uint8_t IMAGE_DESCRIPTOR = 0x2C;
|
||||||
|
constexpr uint8_t TRAILER = 0x3B;
|
||||||
|
constexpr uint8_t GRAPHIC_CONTROL = 0xF9;
|
||||||
|
constexpr uint8_t APPLICATION_EXTENSION = 0xFF;
|
||||||
|
constexpr uint8_t COMMENT_EXTENSION = 0xFE;
|
||||||
|
constexpr uint8_t PLAINTEXT_EXTENSION = 0x01;
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct ScreenDescriptor {
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
uint8_t fields;
|
||||||
|
uint8_t background_color_index;
|
||||||
|
uint8_t pixel_aspect_ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RGB {
|
||||||
|
uint8_t r, g, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImageDescriptor {
|
||||||
|
uint16_t image_left_position;
|
||||||
|
uint16_t image_top_position;
|
||||||
|
uint16_t image_width;
|
||||||
|
uint16_t image_height;
|
||||||
|
uint8_t fields;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct DictionaryEntry {
|
||||||
|
uint8_t byte;
|
||||||
|
int prev;
|
||||||
|
int len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Extension {
|
||||||
|
uint8_t extension_code;
|
||||||
|
uint8_t block_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GraphicControlExtension {
|
||||||
|
uint8_t fields;
|
||||||
|
uint16_t delay_time;
|
||||||
|
uint8_t transparent_color_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ApplicationExtension {
|
||||||
|
uint8_t application_id[8];
|
||||||
|
uint8_t version[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlaintextExtension {
|
||||||
|
uint16_t left, top, width, height;
|
||||||
|
uint8_t cell_width, cell_height;
|
||||||
|
uint8_t foreground_color, background_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Carga la paleta (global color table) a partir de un buffer,
|
||||||
|
// retornándola en un vector de uint32_t (cada color se compone de R, G, B).
|
||||||
|
auto loadPalette(const uint8_t *buffer) -> std::vector<uint32_t>;
|
||||||
|
|
||||||
|
// Carga el stream GIF; devuelve un vector con los datos de imagen sin comprimir y
|
||||||
|
// asigna el ancho y alto mediante referencias.
|
||||||
|
auto loadGif(const uint8_t *buffer, uint16_t &w, uint16_t &h) -> std::vector<uint8_t>;
|
||||||
|
|
||||||
|
} // namespace GIF
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
#include "screen.hpp"
|
#include "core/rendering/screen.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_RenderTexture, SDL_SetRenderDrawColor, SDL_SetRenderVSync, SDL_LogCategory, SDL_GetError, SDL_LogError, SDL_LogInfo, SDL_RendererLogicalPresentation, SDL_SetRenderLogicalPresentation, SDL_CreateTexture, SDL_DestroyTexture, SDL_DestroyWindow, SDL_GetDisplayName, SDL_GetTicks, SDL_Quit, SDL_RENDERER_VSYNC_DISABLED, SDL_RenderClear, SDL_CreateRenderer, SDL_CreateWindow, SDL_DestroyRenderer, SDL_DisplayID, SDL_FRect, SDL_GetCurrentDisplayMode, SDL_GetDisplays, SDL_GetRenderTarget, SDL_GetWindowPosition, SDL_GetWindowSize, SDL_Init, SDL_LogWarn, SDL_PixelFormat, SDL_RenderFillRect, SDL_RenderPresent, SDL_SetHint, SDL_SetRenderDrawBlendMode, SDL_SetTextureScaleMode, SDL_SetWindowFullscreen, SDL_SetWindowPosition, SDL_SetWindowSize, SDL_TextureAccess, SDL_free, SDL_BLENDMODE_BLEND, SDL_HINT_RENDER_DRIVER, SDL_INIT_VIDEO, SDL_ScaleMode, SDL_WINDOW_FULLSCREEN, SDL_WindowFlags
|
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_RenderTexture, SDL_SetRenderDrawColor, SDL_SetRenderVSync, SDL_LogCategory, SDL_GetError, SDL_LogError, SDL_LogInfo, SDL_RendererLogicalPresentation, SDL_SetRenderLogicalPresentation, SDL_CreateTexture, SDL_DestroyTexture, SDL_DestroyWindow, SDL_GetDisplayName, SDL_GetTicks, SDL_Quit, SDL_RENDERER_VSYNC_DISABLED, SDL_RenderClear, SDL_CreateRenderer, SDL_CreateWindow, SDL_DestroyRenderer, SDL_DisplayID, SDL_FRect, SDL_GetCurrentDisplayMode, SDL_GetDisplays, SDL_GetRenderTarget, SDL_GetWindowPosition, SDL_GetWindowSize, SDL_Init, SDL_LogWarn, SDL_PixelFormat, SDL_RenderFillRect, SDL_RenderPresent, SDL_SetHint, SDL_SetRenderDrawBlendMode, SDL_SetTextureScaleMode, SDL_SetWindowFullscreen, SDL_SetWindowPosition, SDL_SetWindowSize, SDL_SyncWindow, SDL_TextureAccess, SDL_free, SDL_BLENDMODE_BLEND, SDL_HINT_RENDER_DRIVER, SDL_INIT_VIDEO, SDL_ScaleMode, SDL_WINDOW_FULLSCREEN, SDL_WindowFlags
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#include <emscripten.h>
|
||||||
|
#include <emscripten/html5.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <algorithm> // Para min, max
|
#include <algorithm> // Para min, max
|
||||||
#include <cstring> // Para memcpy
|
#include <cstring> // Para memcpy
|
||||||
@@ -9,22 +13,62 @@
|
|||||||
#include <string> // Para basic_string, operator+, char_traits, to_string, string
|
#include <string> // Para basic_string, operator+, char_traits, to_string, string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "asset.hpp" // Para Asset
|
#include "core/input/mouse.hpp" // Para updateCursorVisibility
|
||||||
#include "director.hpp" // Para Director::debug_config
|
#ifndef NO_SHADERS
|
||||||
#include "mouse.hpp" // Para updateCursorVisibility
|
#include "core/rendering/sdl3gpu/sdl3gpu_shader.hpp" // Para SDL3GPUShader
|
||||||
#include "options.hpp" // Para Video, video, Window, window
|
#endif
|
||||||
#include "param.hpp" // Para Param, param, ParamGame, ParamDebug
|
#include "core/rendering/text.hpp" // Para Text
|
||||||
#include "rendering/sdl3gpu/sdl3gpu_shader.hpp" // Para SDL3GPUShader
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
#include "resource.hpp" // Para Resource
|
#include "core/resources/asset.hpp" // Para Asset
|
||||||
#include "text.hpp" // Para Text
|
#ifdef _DEBUG
|
||||||
#include "texture.hpp" // Para Texture
|
#include "core/resources/resource.hpp" // Para Resource (només a debug, font 8bithud)
|
||||||
#include "ui/notifier.hpp" // Para Notifier
|
#include "core/system/director.hpp" // Para Director::debug_config (només a debug)
|
||||||
#include "ui/service_menu.hpp" // Para ServiceMenu
|
#endif
|
||||||
#include "utils.hpp" // Para toLower
|
#include "game/options.hpp" // Para Video, video, Window, window
|
||||||
|
#include "game/ui/notifier.hpp" // Para Notifier
|
||||||
|
#include "game/ui/service_menu.hpp" // Para ServiceMenu
|
||||||
|
#include "utils/param.hpp" // Para Param, param, ParamGame, ParamDebug
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
Screen* Screen::instance = nullptr;
|
Screen* Screen::instance = nullptr;
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
// ============================================================================
|
||||||
|
// Restauración del canvas en wasm/Emscripten
|
||||||
|
// ============================================================================
|
||||||
|
// SDL3 + Emscripten no notifica de forma fiable los cambios de estado del
|
||||||
|
// canvas HTML (fullscreen exit vía Esc, rotación del dispositivo, etc.).
|
||||||
|
// Registramos callbacks nativos de Emscripten que delegan en
|
||||||
|
// Screen::handleCanvasResized(), el cual re-aplica el modo de fullscreen y
|
||||||
|
// reajusta la ventana para que SDL salga de su estado interno de fullscreen.
|
||||||
|
//
|
||||||
|
// Los callbacks difieren el trabajo con emscripten_async_call(0ms) porque el
|
||||||
|
// navegador todavía no ha acabado de redimensionar el canvas cuando el evento
|
||||||
|
// se dispara; posponer al siguiente tick garantiza valores estables.
|
||||||
|
//
|
||||||
|
// Referencias: libsdl-org/SDL#13300, libsdl-org/SDL#11389.
|
||||||
|
// ============================================================================
|
||||||
|
namespace {
|
||||||
|
void deferredCanvasResize(void* /*user_data*/) {
|
||||||
|
if (Screen::get() != nullptr) { Screen::get()->handleCanvasResized(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
auto onEmFullscreenChange(int /*event_type*/, const EmscriptenFullscreenChangeEvent* event, void* /*user_data*/) -> EM_BOOL {
|
||||||
|
// Sincronizamos Options::video.fullscreen con el estado real del navegador
|
||||||
|
// antes de diferir la restauración: cuando el usuario sale con Esc no pasa
|
||||||
|
// por toggleFullscreen() y el estado interno quedaría desincronizado.
|
||||||
|
Options::video.fullscreen = (event != nullptr && event->isFullscreen != 0);
|
||||||
|
emscripten_async_call(deferredCanvasResize, nullptr, 0);
|
||||||
|
return EM_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto onEmOrientationChange(int /*event_type*/, const EmscriptenOrientationChangeEvent* /*event*/, void* /*user_data*/) -> EM_BOOL {
|
||||||
|
emscripten_async_call(deferredCanvasResize, nullptr, 0);
|
||||||
|
return EM_FALSE;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
// Inicializa la instancia única del singleton
|
// Inicializa la instancia única del singleton
|
||||||
void Screen::init() {
|
void Screen::init() {
|
||||||
Screen::instance = new Screen();
|
Screen::instance = new Screen();
|
||||||
@@ -39,19 +83,14 @@ auto Screen::get() -> Screen* { return Screen::instance; }
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Screen::Screen()
|
Screen::Screen()
|
||||||
: window_(nullptr),
|
: src_rect_(SDL_FRect{.x = 0, .y = 0, .w = param.game.width, .h = param.game.height}),
|
||||||
renderer_(nullptr),
|
|
||||||
game_canvas_(nullptr),
|
|
||||||
service_menu_(nullptr),
|
|
||||||
notifier_(nullptr),
|
|
||||||
src_rect_(SDL_FRect{.x = 0, .y = 0, .w = param.game.width, .h = param.game.height}),
|
|
||||||
dst_rect_(SDL_FRect{.x = 0, .y = 0, .w = param.game.width, .h = param.game.height}) {
|
dst_rect_(SDL_FRect{.x = 0, .y = 0, .w = param.game.width, .h = param.game.height}) {
|
||||||
// Arranca SDL VIDEO, crea la ventana y el renderizador
|
// Arranca SDL VIDEO, crea la ventana y el renderizador
|
||||||
initSDLVideo();
|
initSDLVideo();
|
||||||
|
|
||||||
// Crea la textura de destino
|
// Crea la textura de destino
|
||||||
game_canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
|
game_canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
|
||||||
SDL_SetTextureScaleMode(game_canvas_, SDL_SCALEMODE_NEAREST);
|
SDL_SetTextureScaleMode(game_canvas_, Options::video.scale_mode);
|
||||||
|
|
||||||
// Inicializar buffer de píxeles para SDL3GPU
|
// Inicializar buffer de píxeles para SDL3GPU
|
||||||
pixel_buffer_.resize(static_cast<size_t>(param.game.width) * static_cast<size_t>(param.game.height));
|
pixel_buffer_.resize(static_cast<size_t>(param.game.width) * static_cast<size_t>(param.game.height));
|
||||||
@@ -67,6 +106,14 @@ Screen::Screen()
|
|||||||
// Renderizar una vez la textura vacía para que tenga contenido válido antes de inicializar los shaders (evita pantalla negra)
|
// Renderizar una vez la textura vacía para que tenga contenido válido antes de inicializar los shaders (evita pantalla negra)
|
||||||
SDL_RenderTexture(renderer_, game_canvas_, nullptr, nullptr);
|
SDL_RenderTexture(renderer_, game_canvas_, nullptr, nullptr);
|
||||||
|
|
||||||
|
// Aplicar la configuración inicial completa (vsync + logical presentation +
|
||||||
|
// fullscreen + tamaño de ventana). En Emscripten es necesario porque el
|
||||||
|
// canvas HTML tiene un tamaño propio y SDL_CreateWindow solo no basta para
|
||||||
|
// que SDL sincronice su viewport interno con el canvas real: sin este
|
||||||
|
// applySettings el canvas inicial sale descolocado con barras negras a los
|
||||||
|
// lados y el juego pequeño en el centro hasta el primer toggle de fullscreen.
|
||||||
|
applySettings();
|
||||||
|
|
||||||
// Limpiar renderer
|
// Limpiar renderer
|
||||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
@@ -143,10 +190,39 @@ void Screen::setFullscreenMode() {
|
|||||||
SDL_SetWindowFullscreen(window_, Options::video.fullscreen);
|
SDL_SetWindowFullscreen(window_, Options::video.fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Camibia entre pantalla completa y ventana
|
// Cambia entre pantalla completa y ventana. Usamos applySettings en vez de
|
||||||
|
// setFullscreenMode porque applySettings también re-aplica la logical
|
||||||
|
// presentation — sin eso, al entrar en fullscreen SDL no recalcula el viewport
|
||||||
|
// y el juego se ve pequeño (especialmente en Android).
|
||||||
void Screen::toggleFullscreen() {
|
void Screen::toggleFullscreen() {
|
||||||
Options::video.fullscreen = !Options::video.fullscreen;
|
Options::video.fullscreen = !Options::video.fullscreen;
|
||||||
setFullscreenMode();
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-sincroniza SDL con el estado real del canvas del navegador. Lo invocan los
|
||||||
|
// callbacks nativos de Emscripten (vegeu el bloc al principi del fitxer) cuando
|
||||||
|
// se detecta un fullscreenchange o un orientationchange. Re-aplica fullscreen y
|
||||||
|
// reajusta la ventana porque SDL no emite SDL_EVENT_WINDOW_LEAVE_FULLSCREEN en
|
||||||
|
// Emscripten y su estado interno queda desincronizado al salir con Esc.
|
||||||
|
// Fuera de Emscripten es un no-op (desktop sí emite los events correctamente).
|
||||||
|
void Screen::handleCanvasResized() {
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
// SDL_SetWindowFullscreen es imprescindible para sacar a SDL de su estado
|
||||||
|
// interno de fullscreen cuando el usuario ha salido sin pasar por
|
||||||
|
// toggleFullscreen (onEmFullscreenChange ya ha actualizado Options).
|
||||||
|
SDL_SetWindowFullscreen(window_, Options::video.fullscreen);
|
||||||
|
SDL_SyncWindow(window_);
|
||||||
|
adjustWindowSize();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registra los callbacks nativos de Emscripten que restauran el canvas cuando
|
||||||
|
// SDL3 no emite los events equivalentes. Fuera de Emscripten es un no-op.
|
||||||
|
void Screen::registerEmscriptenEventCallbacks() {
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, EM_TRUE, onEmFullscreenChange);
|
||||||
|
emscripten_set_orientationchange_callback(nullptr, EM_TRUE, onEmOrientationChange);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cambia el tamaño de la ventana
|
// Cambia el tamaño de la ventana
|
||||||
@@ -240,49 +316,49 @@ void Screen::renderShake() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
// Compone la línia d'informació de debug: "fps - driver - shader preset"
|
||||||
|
auto Screen::buildDebugInfoText() const -> std::string {
|
||||||
|
std::string info_text = std::to_string(fps_.last_value) + " fps";
|
||||||
|
|
||||||
|
// Driver GPU
|
||||||
|
if (shader_backend_ && shader_backend_->isHardwareAccelerated()) {
|
||||||
|
const std::string DRIVER = shader_backend_->getDriverName();
|
||||||
|
info_text += DRIVER.empty() ? "" : " - " + toLower(DRIVER);
|
||||||
|
} else {
|
||||||
|
info_text += " - sdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader + preset (només si està activat)
|
||||||
|
if (!Options::video.shader.enabled) { return info_text; }
|
||||||
|
|
||||||
|
if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
|
||||||
|
const std::string PRESET_NAME = Options::crtpi_presets.empty() ? "" : Options::crtpi_presets.at(static_cast<size_t>(Options::video.shader.current_crtpi_preset)).name;
|
||||||
|
info_text += " - crtpi " + toLower(PRESET_NAME);
|
||||||
|
} else {
|
||||||
|
const std::string PRESET_NAME = Options::postfx_presets.empty() ? "" : Options::postfx_presets.at(static_cast<size_t>(Options::video.shader.current_postfx_preset)).name;
|
||||||
|
info_text += " - postfx " + toLower(PRESET_NAME);
|
||||||
|
}
|
||||||
|
return info_text;
|
||||||
|
}
|
||||||
|
|
||||||
// Muestra información por pantalla
|
// Muestra información por pantalla
|
||||||
void Screen::renderInfo() const {
|
void Screen::renderInfo() const {
|
||||||
if (debug_info_.show) {
|
if (!debug_info_.show) { return; }
|
||||||
const Color GOLD(0xFF, 0xD7, 0x00);
|
|
||||||
const Color GOLD_SHADOW = GOLD.DARKEN(150);
|
|
||||||
|
|
||||||
// Construir texto: fps - driver - preset
|
const Color GOLD(0xFF, 0xD7, 0x00);
|
||||||
std::string info_text = std::to_string(fps_.last_value) + " fps";
|
const Color GOLD_SHADOW = GOLD.darken(150);
|
||||||
|
|
||||||
// Driver GPU
|
const std::string INFO_TEXT = buildDebugInfoText();
|
||||||
if (shader_backend_ && shader_backend_->isHardwareAccelerated()) {
|
const int TEXT_WIDTH = debug_info_.text->length(INFO_TEXT);
|
||||||
const std::string DRIVER = shader_backend_->getDriverName();
|
const int X_POS = (static_cast<int>(param.game.width) - TEXT_WIDTH) / 2;
|
||||||
if (!DRIVER.empty()) {
|
debug_info_.text->writeDX(Text::COLOR | Text::STROKE, X_POS, 1, INFO_TEXT, 1, GOLD, 1, GOLD_SHADOW);
|
||||||
info_text += " - " + toLower(DRIVER);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info_text += " - sdl";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shader + preset
|
|
||||||
if (Options::video.shader.enabled) {
|
|
||||||
if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
|
|
||||||
const std::string PRESET_NAME = Options::crtpi_presets.empty() ? "" : Options::crtpi_presets.at(static_cast<size_t>(Options::video.shader.current_crtpi_preset)).name;
|
|
||||||
info_text += " - crtpi " + toLower(PRESET_NAME);
|
|
||||||
} else {
|
|
||||||
const std::string PRESET_NAME = Options::postfx_presets.empty() ? "" : Options::postfx_presets.at(static_cast<size_t>(Options::video.shader.current_postfx_preset)).name;
|
|
||||||
info_text += " - postfx " + toLower(PRESET_NAME);
|
|
||||||
if (Options::video.supersampling.enabled) { info_text += " (ss)"; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Centrado arriba
|
|
||||||
const int TEXT_WIDTH = debug_info_.text->length(info_text);
|
|
||||||
const int X_POS = (static_cast<int>(param.game.width) - TEXT_WIDTH) / 2;
|
|
||||||
debug_info_.text->writeDX(Text::COLOR | Text::STROKE, X_POS, 1, info_text, 1, GOLD, 1, GOLD_SHADOW);
|
|
||||||
|
|
||||||
#ifdef RECORDING
|
#ifdef RECORDING
|
||||||
const std::string REC_TEXT = "recording";
|
const std::string REC_TEXT = "recording";
|
||||||
const int REC_WIDTH = debug_info_.text->length(REC_TEXT);
|
const int REC_WIDTH = debug_info_.text->length(REC_TEXT);
|
||||||
const int REC_X = (static_cast<int>(param.game.width) - REC_WIDTH) / 2;
|
const int REC_X = (static_cast<int>(param.game.width) - REC_WIDTH) / 2;
|
||||||
debug_info_.text->writeDX(Text::COLOR | Text::STROKE, REC_X, 1 + debug_info_.text->getCharacterSize(), REC_TEXT, 1, GOLD, 1, GOLD_SHADOW);
|
debug_info_.text->writeDX(Text::COLOR | Text::STROKE, REC_X, 1 + debug_info_.text->getCharacterSize(), REC_TEXT, 1, GOLD, 1, GOLD_SHADOW);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Inicializa shaders (SDL3GPU)
|
// Inicializa shaders (SDL3GPU)
|
||||||
@@ -300,14 +376,10 @@ void Screen::initShaders() {
|
|||||||
Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : FALLBACK_DRIVER);
|
Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : FALLBACK_DRIVER);
|
||||||
}
|
}
|
||||||
if (!self->shader_backend_->isHardwareAccelerated()) {
|
if (!self->shader_backend_->isHardwareAccelerated()) {
|
||||||
const bool ok = self->shader_backend_->init(self->window_, self->game_canvas_, "", "");
|
const bool OK = self->shader_backend_->init(self->window_, self->game_canvas_, "", "");
|
||||||
std::cout << "Screen::initShaders: SDL3GPUShader::init() = " << (ok ? "OK" : "FAILED") << '\n';
|
std::cout << "Screen::initShaders: SDL3GPUShader::init() = " << (OK ? "OK" : "FAILED") << '\n';
|
||||||
}
|
}
|
||||||
if (self->shader_backend_ && self->shader_backend_->isHardwareAccelerated()) {
|
if (self->shader_backend_ && self->shader_backend_->isHardwareAccelerated()) {
|
||||||
self->shader_backend_->setLinearUpscale(Options::video.supersampling.linear_upscale);
|
|
||||||
self->shader_backend_->setDownscaleAlgo(Options::video.supersampling.downscale_algo);
|
|
||||||
self->shader_backend_->setOversample(Options::video.supersampling.enabled ? 3 : 1);
|
|
||||||
|
|
||||||
if (!Options::video.shader.enabled) {
|
if (!Options::video.shader.enabled) {
|
||||||
// Passthrough: POSTFX con parámetros a cero
|
// Passthrough: POSTFX con parámetros a cero
|
||||||
self->shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX);
|
self->shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX);
|
||||||
@@ -422,6 +494,8 @@ auto Screen::initSDLVideo() -> bool {
|
|||||||
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
|
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
|
||||||
SDL_SetRenderVSync(renderer_, Options::video.vsync ? 1 : SDL_RENDERER_VSYNC_DISABLED);
|
SDL_SetRenderVSync(renderer_, Options::video.vsync ? 1 : SDL_RENDERER_VSYNC_DISABLED);
|
||||||
|
|
||||||
|
registerEmscriptenEventCallbacks();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,36 +584,25 @@ void Screen::nextCrtPiPreset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alterna supersampling
|
|
||||||
void Screen::toggleSupersampling() {
|
|
||||||
Options::video.supersampling.enabled = !Options::video.supersampling.enabled;
|
|
||||||
auto* self = Screen::get();
|
|
||||||
if (self != nullptr && self->shader_backend_ && self->shader_backend_->isHardwareAccelerated()) {
|
|
||||||
self->shader_backend_->setOversample(Options::video.supersampling.enabled ? 3 : 1);
|
|
||||||
if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
|
|
||||||
self->applyCurrentCrtPiPreset();
|
|
||||||
} else {
|
|
||||||
self->applyCurrentPostFXPreset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aplica el preset PostFX activo al backend
|
// Aplica el preset PostFX activo al backend
|
||||||
void Screen::applyCurrentPostFXPreset() {
|
void Screen::applyCurrentPostFXPreset() {
|
||||||
if (!shader_backend_) { return; }
|
if (!shader_backend_) { return; }
|
||||||
shader_backend_->setOversample(Options::video.supersampling.enabled ? 3 : 1);
|
|
||||||
Rendering::PostFXParams p{};
|
Rendering::PostFXParams p{};
|
||||||
if (Options::video.shader.enabled && !Options::postfx_presets.empty()) {
|
if (Options::video.shader.enabled && !Options::postfx_presets.empty()) {
|
||||||
const auto& preset = Options::postfx_presets.at(static_cast<size_t>(Options::video.shader.current_postfx_preset));
|
const auto& preset = Options::postfx_presets.at(static_cast<size_t>(Options::video.shader.current_postfx_preset));
|
||||||
p.vignette = preset.vignette;
|
p.vignette = preset.vignette;
|
||||||
p.scanlines = preset.scanlines;
|
p.scanlines = preset.scanlines;
|
||||||
p.chroma = preset.chroma;
|
p.chroma_min = preset.chroma_min;
|
||||||
|
p.chroma_max = preset.chroma_max;
|
||||||
p.mask = preset.mask;
|
p.mask = preset.mask;
|
||||||
p.gamma = preset.gamma;
|
p.gamma = preset.gamma;
|
||||||
p.curvature = preset.curvature;
|
p.curvature = preset.curvature;
|
||||||
p.bleeding = preset.bleeding;
|
p.bleeding = preset.bleeding;
|
||||||
p.flicker = preset.flicker;
|
p.flicker = preset.flicker;
|
||||||
std::cout << "Screen::applyCurrentPostFXPreset: preset='" << preset.name << "' scan=" << p.scanlines << " vign=" << p.vignette << " chroma=" << p.chroma << '\n';
|
p.scan_dark_ratio = preset.scan_dark_ratio;
|
||||||
|
p.scan_dark_floor = preset.scan_dark_floor;
|
||||||
|
p.scan_edge_soft = preset.scan_edge_soft;
|
||||||
|
std::cout << "Screen::applyCurrentPostFXPreset: preset='" << preset.name << "' scan=" << p.scanlines << " vign=" << p.vignette << " chroma=[" << p.chroma_min << ".." << p.chroma_max << "]\n";
|
||||||
}
|
}
|
||||||
shader_backend_->setPostFXParams(p);
|
shader_backend_->setPostFXParams(p);
|
||||||
}
|
}
|
||||||
@@ -579,19 +642,43 @@ void Screen::toggleIntegerScale() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alterna entre activar y desactivar el V-Sync
|
// Alterna entre activar y desactivar el V-Sync. ÚNICA via "user-facing" que
|
||||||
|
// modifica la preferencia persistent (Options::video.vsync); la resta de
|
||||||
|
// crides a setVSync apliquen l'estat al hardware sense escriure preferència.
|
||||||
void Screen::toggleVSync() {
|
void Screen::toggleVSync() {
|
||||||
Options::video.vsync = !Options::video.vsync;
|
Options::video.vsync = !Options::video.vsync;
|
||||||
SDL_SetRenderVSync(renderer_, Options::video.vsync ? 1 : SDL_RENDERER_VSYNC_DISABLED);
|
setVSync(Options::video.vsync);
|
||||||
if (shader_backend_) {
|
|
||||||
shader_backend_->setVSync(Options::video.vsync);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el estado del V-Sync
|
// Aplica Options::video.scale_mode a la textura del canvas de juego
|
||||||
|
void Screen::applyFilter() {
|
||||||
|
SDL_SetTextureScaleMode(game_canvas_, Options::video.scale_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alterna el modo de filtrado entre nearest y linear
|
||||||
|
void Screen::toggleFilter() {
|
||||||
|
Options::video.scale_mode = (Options::video.scale_mode == SDL_SCALEMODE_NEAREST)
|
||||||
|
? SDL_SCALEMODE_LINEAR
|
||||||
|
: SDL_SCALEMODE_NEAREST;
|
||||||
|
applyFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Devuelve true si el backend SDL3GPU está activo y con aceleración hardware
|
||||||
|
auto Screen::isHardwareAccelerated() -> bool {
|
||||||
|
auto* self = Screen::get();
|
||||||
|
return self != nullptr && self->shader_backend_ && self->shader_backend_->isHardwareAccelerated();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplica V-Sync al renderer SDL i al backend GPU. NO toca la preferència
|
||||||
|
// persistent (Options::video.vsync) — és responsabilitat del caller (menú
|
||||||
|
// servei, toggleVSync). Així Resource::beginLoad/finishBoot poden canviar
|
||||||
|
// el vsync efectiu durant el preload sense clobberar la preferència de
|
||||||
|
// l'usuari (bug històric: el seu vsync=true es perdia entre llançaments).
|
||||||
void Screen::setVSync(bool enabled) {
|
void Screen::setVSync(bool enabled) {
|
||||||
Options::video.vsync = enabled;
|
|
||||||
SDL_SetRenderVSync(renderer_, enabled ? 1 : SDL_RENDERER_VSYNC_DISABLED);
|
SDL_SetRenderVSync(renderer_, enabled ? 1 : SDL_RENDERER_VSYNC_DISABLED);
|
||||||
|
if (shader_backend_) {
|
||||||
|
shader_backend_->setVSync(enabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene los punteros a los singletones
|
// Obtiene los punteros a los singletones
|
||||||
@@ -609,12 +696,17 @@ void Screen::getSingletons() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aplica los valores de las opciones
|
// Aplica los valores de las opciones.
|
||||||
|
// IMPORTANTE: el orden importa. SDL_SetRenderLogicalPresentation calcula el
|
||||||
|
// viewport en función del tamaño actual de la ventana SDL, así que DEBE llamarse
|
||||||
|
// DESPUÉS de setFullscreenMode/adjustWindowSize — si no, al entrar en fullscreen
|
||||||
|
// el viewport queda cacheado al tamaño de la ventana pequeña previa y el juego
|
||||||
|
// se ve pequeño y centrado con barras negras alrededor.
|
||||||
void Screen::applySettings() {
|
void Screen::applySettings() {
|
||||||
SDL_SetRenderVSync(renderer_, Options::video.vsync ? 1 : SDL_RENDERER_VSYNC_DISABLED);
|
setVSync(Options::video.vsync);
|
||||||
SDL_SetRenderLogicalPresentation(Screen::get()->getRenderer(), param.game.width, param.game.height, Options::video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
|
||||||
setFullscreenMode();
|
setFullscreenMode();
|
||||||
adjustWindowSize();
|
adjustWindowSize();
|
||||||
|
SDL_SetRenderLogicalPresentation(renderer_, param.game.width, param.game.height, Options::video.integer_scale ? SDL_LOGICAL_PRESENTATION_INTEGER_SCALE : SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea el objeto de texto
|
// Crea el objeto de texto
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "color.hpp" // Para Color
|
#include "core/rendering/shader_backend.hpp" // Para Rendering::ShaderType
|
||||||
#include "options.hpp" // Para VideoOptions, video
|
#include "game/options.hpp" // Para VideoOptions, video
|
||||||
#include "rendering/shader_backend.hpp" // Para Rendering::ShaderType
|
#include "utils/color.hpp" // Para Color
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class Notifier;
|
class Notifier;
|
||||||
@@ -34,6 +34,7 @@ class Screen {
|
|||||||
// --- Configuración de ventana y render ---
|
// --- Configuración de ventana y render ---
|
||||||
void setFullscreenMode(); // Establece el modo de pantalla completa
|
void setFullscreenMode(); // Establece el modo de pantalla completa
|
||||||
void toggleFullscreen(); // Cambia entre pantalla completa y ventana
|
void toggleFullscreen(); // Cambia entre pantalla completa y ventana
|
||||||
|
void handleCanvasResized(); // Restaura el canvas cuando SDL3 no reporta el cambio (emscripten only: salida de fullscreen con Esc, rotación); no-op fuera de emscripten
|
||||||
void setWindowZoom(int zoom); // Cambia el tamaño de la ventana
|
void setWindowZoom(int zoom); // Cambia el tamaño de la ventana
|
||||||
auto decWindowSize() -> bool; // Reduce el tamaño de la ventana
|
auto decWindowSize() -> bool; // Reduce el tamaño de la ventana
|
||||||
auto incWindowSize() -> bool; // Aumenta el tamaño de la ventana
|
auto incWindowSize() -> bool; // Aumenta el tamaño de la ventana
|
||||||
@@ -43,11 +44,12 @@ class Screen {
|
|||||||
// --- Efectos visuales ---
|
// --- Efectos visuales ---
|
||||||
void shake(int desp = 2, float delay_s = 0.05F, float duration_s = 0.133F) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay_s, duration_s); }
|
void shake(int desp = 2, float delay_s = 0.05F, float duration_s = 0.133F) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay_s, duration_s); }
|
||||||
void flash(Color color, float duration_s = 0.167F, float delay_s = 0.0F) { flash_effect_ = FlashEffect(true, duration_s, delay_s, color); }
|
void flash(Color color, float duration_s = 0.167F, float delay_s = 0.0F) { flash_effect_ = FlashEffect(true, duration_s, delay_s, color); }
|
||||||
static void toggleShaders(); // Alterna activar/desactivar shaders
|
static void toggleShaders(); // Alterna activar/desactivar shaders
|
||||||
static void nextShader(); // Cambia entre PostFX y CrtPi
|
static void nextShader(); // Cambia entre PostFX y CrtPi
|
||||||
static void nextPostFXPreset(); // Avanza al siguiente preset PostFX
|
static void nextPostFXPreset(); // Avanza al siguiente preset PostFX
|
||||||
static void nextCrtPiPreset(); // Avanza al siguiente preset CrtPi
|
static void nextCrtPiPreset(); // Avanza al siguiente preset CrtPi
|
||||||
static void toggleSupersampling(); // Alterna supersampling
|
void toggleFilter(); // Alterna SDL_SCALEMODE_NEAREST ↔ SDL_SCALEMODE_LINEAR
|
||||||
|
void applyFilter(); // Aplica Options::video.scale_mode a game_canvas_
|
||||||
void toggleIntegerScale();
|
void toggleIntegerScale();
|
||||||
void toggleVSync(); // Alterna entre activar y desactivar el V-Sync
|
void toggleVSync(); // Alterna entre activar y desactivar el V-Sync
|
||||||
void setVSync(bool enabled); // Establece el estado del V-Sync
|
void setVSync(bool enabled); // Establece el estado del V-Sync
|
||||||
@@ -59,10 +61,11 @@ class Screen {
|
|||||||
void hide() { SDL_HideWindow(window_); } // Oculta la ventana
|
void hide() { SDL_HideWindow(window_); } // Oculta la ventana
|
||||||
void getSingletons(); // Obtiene los punteros a los singletones
|
void getSingletons(); // Obtiene los punteros a los singletones
|
||||||
[[nodiscard]] static auto getVSync() -> bool { return Options::video.vsync; } // Obtiene el valor de V-Sync
|
[[nodiscard]] static auto getVSync() -> bool { return Options::video.vsync; } // Obtiene el valor de V-Sync
|
||||||
|
[[nodiscard]] static auto isHardwareAccelerated() -> bool; // True si SDL3GPU está activo
|
||||||
[[nodiscard]] auto getText() const -> std::shared_ptr<Text> { return text_; } // Obtiene el puntero al texto de Screen
|
[[nodiscard]] auto getText() const -> std::shared_ptr<Text> { return text_; } // Obtiene el puntero al texto de Screen
|
||||||
|
|
||||||
// --- Display Monitor getters ---
|
// --- Display Monitor getters ---
|
||||||
[[nodiscard]] auto getDisplayMonitorName() const -> std::string { return display_monitor_.name; }
|
[[nodiscard]] auto getDisplayMonitorName() const -> const std::string& { return display_monitor_.name; }
|
||||||
[[nodiscard]] auto getDisplayMonitorWidth() const -> int { return display_monitor_.width; }
|
[[nodiscard]] auto getDisplayMonitorWidth() const -> int { return display_monitor_.width; }
|
||||||
[[nodiscard]] auto getDisplayMonitorHeight() const -> int { return display_monitor_.height; }
|
[[nodiscard]] auto getDisplayMonitorHeight() const -> int { return display_monitor_.height; }
|
||||||
[[nodiscard]] auto getDisplayMonitorRefreshRate() const -> int { return display_monitor_.refresh_rate; }
|
[[nodiscard]] auto getDisplayMonitorRefreshRate() const -> int { return display_monitor_.refresh_rate; }
|
||||||
@@ -210,11 +213,11 @@ class Screen {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
SDL_Window* window_; // Ventana de la aplicación
|
SDL_Window* window_ = nullptr; // Ventana de la aplicación
|
||||||
SDL_Renderer* renderer_; // El renderizador de la ventana
|
SDL_Renderer* renderer_ = nullptr; // El renderizador de la ventana
|
||||||
SDL_Texture* game_canvas_; // Textura donde se dibuja todo antes de volcarse al renderizador
|
SDL_Texture* game_canvas_ = nullptr; // Textura donde se dibuja todo antes de volcarse al renderizador
|
||||||
ServiceMenu* service_menu_; // Objeto para mostrar el menú de servicio
|
ServiceMenu* service_menu_ = nullptr; // Objeto para mostrar el menú de servicio
|
||||||
Notifier* notifier_; // Objeto para mostrar las notificaciones por pantalla
|
Notifier* notifier_ = nullptr; // Objeto para mostrar las notificaciones por pantalla
|
||||||
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
|
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
|
||||||
std::unique_ptr<Rendering::ShaderBackend> shader_backend_; // Backend de shaders (SDL3GPU)
|
std::unique_ptr<Rendering::ShaderBackend> shader_backend_; // Backend de shaders (SDL3GPU)
|
||||||
|
|
||||||
@@ -232,18 +235,20 @@ class Screen {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
auto initSDLVideo() -> bool; // Arranca SDL VIDEO y crea la ventana
|
auto initSDLVideo() -> bool; // Arranca SDL VIDEO y crea la ventana
|
||||||
void renderFlash(); // Dibuja el efecto de flash en la pantalla
|
void registerEmscriptenEventCallbacks(); // Registra callbacks nativos para restaurar el canvas en wasm (no-op fuera de emscripten)
|
||||||
void renderShake(); // Aplica el efecto de agitar la pantalla
|
void renderFlash(); // Dibuja el efecto de flash en la pantalla
|
||||||
void renderInfo() const; // Muestra información por pantalla
|
void renderShake(); // Aplica el efecto de agitar la pantalla
|
||||||
void renderPresent(); // Selecciona y ejecuta el método de renderizado adecuado
|
void renderInfo() const; // Muestra información por pantalla
|
||||||
void applyCurrentPostFXPreset(); // Aplica el preset PostFX activo al backend
|
[[nodiscard]] auto buildDebugInfoText() const -> std::string; // Compone fps + driver + shader/preset para renderInfo
|
||||||
void applyCurrentCrtPiPreset(); // Aplica el preset CrtPi activo al backend
|
void renderPresent(); // Selecciona y ejecuta el método de renderizado adecuado
|
||||||
void adjustWindowSize(); // Calcula el tamaño de la ventana
|
void applyCurrentPostFXPreset(); // Aplica el preset PostFX activo al backend
|
||||||
void getDisplayInfo(); // Obtiene información sobre la pantalla
|
void applyCurrentCrtPiPreset(); // Aplica el preset CrtPi activo al backend
|
||||||
void renderOverlays(); // Renderiza todos los overlays y efectos
|
void adjustWindowSize(); // Calcula el tamaño de la ventana
|
||||||
void renderAttenuate(); // Atenúa la pantalla
|
void getDisplayInfo(); // Obtiene información sobre la pantalla
|
||||||
void createText(); // Crea el objeto de texto
|
void renderOverlays(); // Renderiza todos los overlays y efectos
|
||||||
|
void renderAttenuate(); // Atenúa la pantalla
|
||||||
|
void createText(); // Crea el objeto de texto
|
||||||
|
|
||||||
// --- Constructores y destructor privados (singleton) ---
|
// --- Constructores y destructor privados (singleton) ---
|
||||||
Screen(); // Constructor privado
|
Screen(); // Constructor privado
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
// Fragment shader del shader "crtpi" (algoritme CRT-Pi): scanlines amb
|
||||||
|
// pesos gaussians, multisample opcional, gamma i màscara de subpíxels.
|
||||||
|
namespace Rendering::Msl {
|
||||||
|
|
||||||
|
inline constexpr const char* kCrtpiFrag = R"(
|
||||||
|
#include <metal_stdlib>
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct PostVOut {
|
||||||
|
float4 pos [[position]];
|
||||||
|
float2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CrtPiUniforms {
|
||||||
|
float scanline_weight;
|
||||||
|
float scanline_gap_brightness;
|
||||||
|
float bloom_factor;
|
||||||
|
float input_gamma;
|
||||||
|
float output_gamma;
|
||||||
|
float mask_brightness;
|
||||||
|
float curvature_x;
|
||||||
|
float curvature_y;
|
||||||
|
int mask_type;
|
||||||
|
int enable_scanlines;
|
||||||
|
int enable_multisample;
|
||||||
|
int enable_gamma;
|
||||||
|
int enable_curvature;
|
||||||
|
int enable_sharper;
|
||||||
|
float texture_width;
|
||||||
|
float texture_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
static float2 crtpi_distort(float2 coord, float2 screen_scale, float cx, float cy) {
|
||||||
|
float2 curvature = float2(cx, cy);
|
||||||
|
float2 barrel_scale = 1.0f - (0.23f * curvature);
|
||||||
|
coord *= screen_scale;
|
||||||
|
coord -= 0.5f;
|
||||||
|
float rsq = coord.x * coord.x + coord.y * coord.y;
|
||||||
|
coord += coord * (curvature * rsq);
|
||||||
|
coord *= barrel_scale;
|
||||||
|
if (abs(coord.x) >= 0.5f || abs(coord.y) >= 0.5f) { return float2(-1.0f); }
|
||||||
|
coord += 0.5f;
|
||||||
|
coord /= screen_scale;
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float crtpi_scan_weight(float dist, float sw, float gap) {
|
||||||
|
return max(1.0f - dist * dist * sw, gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float crtpi_scan_line(float dy, float filter_w, float sw, float gap, bool ms) {
|
||||||
|
float w = crtpi_scan_weight(dy, sw, gap);
|
||||||
|
if (ms) {
|
||||||
|
w += crtpi_scan_weight(dy - filter_w, sw, gap);
|
||||||
|
w += crtpi_scan_weight(dy + filter_w, sw, gap);
|
||||||
|
w *= 0.3333333f;
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment float4 crtpi_fs(PostVOut in [[stage_in]],
|
||||||
|
texture2d<float> tex [[texture(0)]],
|
||||||
|
sampler samp [[sampler(0)]],
|
||||||
|
constant CrtPiUniforms& u [[buffer(0)]]) {
|
||||||
|
float2 tex_size = float2(u.texture_width, u.texture_height);
|
||||||
|
// Amplada del filtre de scanline analític. 768 = alçada de referència
|
||||||
|
// CRT a la qual es va tarar l'algoritme original; 3 = divisió per
|
||||||
|
// subpíxel (R/G/B) del multisample. El resultat escala amb la textura
|
||||||
|
// d'entrada, de manera que més alçada → filtre més fi.
|
||||||
|
const float CRT_REFERENCE_HEIGHT = 768.0f;
|
||||||
|
const float SUBPIXEL_DIV = 3.0f;
|
||||||
|
float filter_width = (CRT_REFERENCE_HEIGHT / u.texture_height) / SUBPIXEL_DIV;
|
||||||
|
float2 texcoord = in.uv;
|
||||||
|
|
||||||
|
if (u.enable_curvature != 0) {
|
||||||
|
texcoord = crtpi_distort(texcoord, float2(1.0f, 1.0f), u.curvature_x, u.curvature_y);
|
||||||
|
if (texcoord.x < 0.0f) { return float4(0.0f, 0.0f, 0.0f, 1.0f); }
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 coord_in_pixels = texcoord * tex_size;
|
||||||
|
float2 tc;
|
||||||
|
float scan_weight;
|
||||||
|
|
||||||
|
if (u.enable_sharper != 0) {
|
||||||
|
float2 temp = floor(coord_in_pixels) + 0.5f;
|
||||||
|
tc = temp / tex_size;
|
||||||
|
float2 deltas = coord_in_pixels - temp;
|
||||||
|
scan_weight = crtpi_scan_line(deltas.y, filter_width, u.scanline_weight, u.scanline_gap_brightness, u.enable_multisample != 0);
|
||||||
|
float2 signs = sign(deltas);
|
||||||
|
deltas.x *= 2.0f;
|
||||||
|
deltas = deltas * deltas;
|
||||||
|
deltas.y = deltas.y * deltas.y;
|
||||||
|
deltas.x *= 0.5f;
|
||||||
|
deltas.y *= 8.0f;
|
||||||
|
deltas /= tex_size;
|
||||||
|
deltas *= signs;
|
||||||
|
tc = tc + deltas;
|
||||||
|
} else {
|
||||||
|
float temp_y = floor(coord_in_pixels.y) + 0.5f;
|
||||||
|
float y_coord = temp_y / tex_size.y;
|
||||||
|
float dy = coord_in_pixels.y - temp_y;
|
||||||
|
scan_weight = crtpi_scan_line(dy, filter_width, u.scanline_weight, u.scanline_gap_brightness, u.enable_multisample != 0);
|
||||||
|
float sign_y = sign(dy);
|
||||||
|
dy = dy * dy;
|
||||||
|
dy = dy * dy;
|
||||||
|
dy *= 8.0f;
|
||||||
|
dy /= tex_size.y;
|
||||||
|
dy *= sign_y;
|
||||||
|
tc = float2(texcoord.x, y_coord + dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 colour = tex.sample(samp, tc).rgb;
|
||||||
|
|
||||||
|
if (u.enable_scanlines != 0) {
|
||||||
|
if (u.enable_gamma != 0) { colour = pow(colour, float3(u.input_gamma)); }
|
||||||
|
colour *= scan_weight * u.bloom_factor;
|
||||||
|
if (u.enable_gamma != 0) { colour = pow(colour, float3(1.0f / u.output_gamma)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u.mask_type == 1) {
|
||||||
|
float wm = fract(in.pos.x * 0.5f);
|
||||||
|
float3 mask = (wm < 0.5f) ? float3(u.mask_brightness, 1.0f, u.mask_brightness)
|
||||||
|
: float3(1.0f, u.mask_brightness, 1.0f);
|
||||||
|
colour *= mask;
|
||||||
|
} else if (u.mask_type == 2) {
|
||||||
|
float wm = fract(in.pos.x * 0.3333333f);
|
||||||
|
float3 mask = float3(u.mask_brightness);
|
||||||
|
if (wm < 0.3333333f) mask.x = 1.0f;
|
||||||
|
else if (wm < 0.6666666f) mask.y = 1.0f;
|
||||||
|
else mask.z = 1.0f;
|
||||||
|
colour *= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
return float4(colour, 1.0f);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
} // namespace Rendering::Msl
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
// Fragment shader del shader "postfx": vignette, chroma, scanlines, mask,
|
||||||
|
// gamma, curvature, bleeding i flicker. Els paràmetres venen via uniforms.
|
||||||
|
//
|
||||||
|
// IMPORTANT: mantenir sincronitzat a mà amb data/shaders/postfx.frag. SDL3 GPU
|
||||||
|
// compila aquest string MSL en runtime; no hi ha generador automàtic. Qualsevol
|
||||||
|
// canvi a la struct d'uniforms o a la lògica del GLSL cal replicar-lo ací al
|
||||||
|
// mateix commit. Mida total = 64 bytes (4 × vec4).
|
||||||
|
namespace Rendering::Msl {
|
||||||
|
|
||||||
|
inline constexpr const char* kPostfxFrag = R"(
|
||||||
|
#include <metal_stdlib>
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct PostVOut {
|
||||||
|
float4 pos [[position]];
|
||||||
|
float2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PostFXUniforms {
|
||||||
|
float vignette_strength;
|
||||||
|
float chroma_min;
|
||||||
|
float scanline_strength;
|
||||||
|
float screen_height;
|
||||||
|
float mask_strength;
|
||||||
|
float gamma_strength;
|
||||||
|
float curvature;
|
||||||
|
float bleeding;
|
||||||
|
float pixel_scale;
|
||||||
|
float time;
|
||||||
|
float flicker;
|
||||||
|
float chroma_max;
|
||||||
|
// vec4 #3 — paràmetres de scanlines (exposats per preset YAML)
|
||||||
|
float scan_dark_ratio;
|
||||||
|
float scan_dark_floor;
|
||||||
|
float scan_edge_soft;
|
||||||
|
float pad3;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mostreig bilinear horitzontal d'un canal RGB. Evita el "tic-tac" del sampler
|
||||||
|
// NEAREST quan l'offset de chroma és subpíxel.
|
||||||
|
static float sampleBilinearX(float2 uv_target, int channel, texture2d<float> scene, sampler samp) {
|
||||||
|
float2 tex_size = float2(scene.get_width(), scene.get_height());
|
||||||
|
float px = uv_target.x * tex_size.x - 0.5f;
|
||||||
|
float p_floor = floor(px);
|
||||||
|
float f = px - p_floor;
|
||||||
|
float4 c0 = scene.sample(samp, float2((p_floor + 0.5f) / tex_size.x, uv_target.y));
|
||||||
|
float4 c1 = scene.sample(samp, float2((p_floor + 1.5f) / tex_size.x, uv_target.y));
|
||||||
|
return mix(c0[channel], c1[channel], f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float3 rgb_to_ycc(float3 rgb) {
|
||||||
|
return float3(
|
||||||
|
0.299f*rgb.r + 0.587f*rgb.g + 0.114f*rgb.b,
|
||||||
|
-0.169f*rgb.r - 0.331f*rgb.g + 0.500f*rgb.b + 0.5f,
|
||||||
|
0.500f*rgb.r - 0.419f*rgb.g - 0.081f*rgb.b + 0.5f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
static float3 ycc_to_rgb(float3 ycc) {
|
||||||
|
float y = ycc.x;
|
||||||
|
float cb = ycc.y - 0.5f;
|
||||||
|
float cr = ycc.z - 0.5f;
|
||||||
|
return clamp(float3(
|
||||||
|
y + 1.402f*cr,
|
||||||
|
y - 0.344f*cb - 0.714f*cr,
|
||||||
|
y + 1.772f*cb
|
||||||
|
), 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment float4 postfx_fs(PostVOut in [[stage_in]],
|
||||||
|
texture2d<float> scene [[texture(0)]],
|
||||||
|
sampler samp [[sampler(0)]],
|
||||||
|
constant PostFXUniforms& u [[buffer(0)]]) {
|
||||||
|
float2 uv = in.uv;
|
||||||
|
|
||||||
|
if (u.curvature > 0.0f) {
|
||||||
|
float2 c = uv - 0.5f;
|
||||||
|
float rsq = dot(c, c);
|
||||||
|
float2 dist = float2(0.05f, 0.1f) * u.curvature;
|
||||||
|
float2 barrelScale = 1.0f - 0.23f * dist;
|
||||||
|
c += c * (dist * rsq);
|
||||||
|
c *= barrelScale;
|
||||||
|
if (abs(c.x) >= 0.5f || abs(c.y) >= 0.5f) {
|
||||||
|
return float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
uv = c + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 base = scene.sample(samp, uv).rgb;
|
||||||
|
|
||||||
|
float3 colour;
|
||||||
|
if (u.bleeding > 0.0f) {
|
||||||
|
float tw = float(scene.get_width());
|
||||||
|
float step = 1.0f / tw;
|
||||||
|
float3 ycc = rgb_to_ycc(base);
|
||||||
|
float3 ycc_l2 = rgb_to_ycc(scene.sample(samp, uv - float2(2.0f*step, 0.0f)).rgb);
|
||||||
|
float3 ycc_l1 = rgb_to_ycc(scene.sample(samp, uv - float2(1.0f*step, 0.0f)).rgb);
|
||||||
|
float3 ycc_r1 = rgb_to_ycc(scene.sample(samp, uv + float2(1.0f*step, 0.0f)).rgb);
|
||||||
|
float3 ycc_r2 = rgb_to_ycc(scene.sample(samp, uv + float2(2.0f*step, 0.0f)).rgb);
|
||||||
|
ycc.yz = (ycc_l2.yz + ycc_l1.yz*2.0f + ycc.yz*2.0f + ycc_r1.yz*2.0f + ycc_r2.yz) / 8.0f;
|
||||||
|
colour = mix(base, ycc_to_rgb(ycc), u.bleeding);
|
||||||
|
} else {
|
||||||
|
colour = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chroma — varia entre chroma_min i chroma_max via sinusoidal; si min == max
|
||||||
|
// queda estàtic. Mostreig bilinear horitzontal per evitar el "tic-tac" del
|
||||||
|
// NEAREST sampler amb offsets subpíxel.
|
||||||
|
if (u.chroma_min > 0.0f || u.chroma_max > 0.0f) {
|
||||||
|
float ca = mix(u.chroma_min, u.chroma_max, 0.5f + 0.5f * sin(u.time * 7.3f)) * 0.005f;
|
||||||
|
colour.r = sampleBilinearX(uv + float2(ca, 0.0f), 0, scene, samp);
|
||||||
|
colour.b = sampleBilinearX(uv - float2(ca, 0.0f), 2, scene, samp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u.gamma_strength > 0.0f) {
|
||||||
|
float3 lin = pow(colour, float3(2.4f));
|
||||||
|
colour = mix(colour, lin, u.gamma_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scanlines — 3 subpíxels per fila lògica (2 brillants + 1 fosca). Transició
|
||||||
|
// suavitzada amb smoothstep d'ample ≈ 1 píxel físic (estil crtpi: filtratge
|
||||||
|
// analític continu). scan_edge_soft = 0 recupera el step dur de l'original.
|
||||||
|
if (u.scanline_strength > 0.0f) {
|
||||||
|
float ps = max(u.pixel_scale, 1.0f);
|
||||||
|
float sub = fract(uv.y * u.screen_height);
|
||||||
|
float dark_center = 1.0f - u.scan_dark_ratio * 0.5f;
|
||||||
|
float d = abs(sub - dark_center);
|
||||||
|
d = min(d, 1.0f - d);
|
||||||
|
float half_width = u.scan_dark_ratio * 0.5f;
|
||||||
|
float softness = u.scan_edge_soft * 0.5f / ps;
|
||||||
|
float band = 1.0f - smoothstep(half_width - softness, half_width + softness, d);
|
||||||
|
float scan = mix(1.0f, u.scan_dark_floor, band);
|
||||||
|
colour *= mix(1.0f, scan, u.scanline_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u.gamma_strength > 0.0f) {
|
||||||
|
float3 enc = pow(colour, float3(1.0f/2.2f));
|
||||||
|
colour = mix(colour, enc, u.gamma_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 d = uv - 0.5f;
|
||||||
|
float vignette = 1.0f - dot(d, d) * u.vignette_strength;
|
||||||
|
colour *= clamp(vignette, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
if (u.mask_strength > 0.0f) {
|
||||||
|
float whichMask = fract(in.pos.x * 0.3333333f);
|
||||||
|
float3 mask = float3(0.80f);
|
||||||
|
if (whichMask < 0.3333333f) mask.x = 1.0f;
|
||||||
|
else if (whichMask < 0.6666667f) mask.y = 1.0f;
|
||||||
|
else mask.z = 1.0f;
|
||||||
|
colour = mix(colour, colour * mask, u.mask_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u.flicker > 0.0f) {
|
||||||
|
float flicker_wave = sin(u.time * 100.0f) * 0.5f + 0.5f;
|
||||||
|
colour *= 1.0f - u.flicker * 0.04f * flicker_wave;
|
||||||
|
}
|
||||||
|
|
||||||
|
return float4(colour, 1.0f);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
} // namespace Rendering::Msl
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
// Vertex shader compartit per tots els pipelines de post-procés:
|
||||||
|
// fullscreen-triangle que cobreix tota l'àrea del swapchain amb UVs a [0,1].
|
||||||
|
namespace Rendering::Msl {
|
||||||
|
|
||||||
|
inline constexpr const char* kPostfxVert = R"(
|
||||||
|
#include <metal_stdlib>
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct PostVOut {
|
||||||
|
float4 pos [[position]];
|
||||||
|
float2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex PostVOut postfx_vs(uint vid [[vertex_id]]) {
|
||||||
|
const float2 positions[3] = { {-1.0, -1.0}, {3.0, -1.0}, {-1.0, 3.0} };
|
||||||
|
const float2 uvs[3] = { { 0.0, 1.0}, {2.0, 1.0}, { 0.0,-1.0} };
|
||||||
|
PostVOut out;
|
||||||
|
out.pos = float4(positions[vid], 0.0, 1.0);
|
||||||
|
out.uv = uvs[vid];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
} // namespace Rendering::Msl
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
@@ -0,0 +1,559 @@
|
|||||||
|
#include "core/rendering/sdl3gpu/sdl3gpu_shader.hpp"
|
||||||
|
|
||||||
|
#include <SDL3/SDL_log.h>
|
||||||
|
|
||||||
|
#include <algorithm> // std::min, std::max
|
||||||
|
#include <cmath> // std::floor
|
||||||
|
#include <cstring> // memcpy, strlen
|
||||||
|
#include <iostream> // Para std::cout
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
#include "core/rendering/sdl3gpu/spv/crtpi_frag_spv.h"
|
||||||
|
#include "core/rendering/sdl3gpu/spv/postfx_frag_spv.h"
|
||||||
|
#include "core/rendering/sdl3gpu/spv/postfx_vert_spv.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "core/rendering/sdl3gpu/msl/crtpi_frag.msl.h"
|
||||||
|
#include "core/rendering/sdl3gpu/msl/postfx_frag.msl.h"
|
||||||
|
#include "core/rendering/sdl3gpu/msl/postfx_vert.msl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Rendering {
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Destructor
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
SDL3GPUShader::~SDL3GPUShader() {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// init
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
auto SDL3GPUShader::init(SDL_Window* window,
|
||||||
|
SDL_Texture* texture,
|
||||||
|
const std::string& /*vertex_source*/,
|
||||||
|
const std::string& /*fragment_source*/) -> bool {
|
||||||
|
if (is_initialized_) {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
window_ = window;
|
||||||
|
|
||||||
|
float fw = 0.0F;
|
||||||
|
float fh = 0.0F;
|
||||||
|
SDL_GetTextureSize(texture, &fw, &fh);
|
||||||
|
game_width_ = static_cast<int>(fw);
|
||||||
|
game_height_ = static_cast<int>(fh);
|
||||||
|
uniforms_.screen_height = static_cast<float>(game_height_);
|
||||||
|
|
||||||
|
// 1. GPU disabled by config
|
||||||
|
if (preferred_driver_ == "none") {
|
||||||
|
std::cout << "SDL3GPUShader: GPU disabled by config, using SDL_Renderer fallback" << '\n';
|
||||||
|
driver_name_ = "";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Create GPU device (solo si no existe ya)
|
||||||
|
if (device_ == nullptr) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const SDL_GPUShaderFormat PREFERRED = SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_METALLIB;
|
||||||
|
#else
|
||||||
|
const SDL_GPUShaderFormat PREFERRED = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||||
|
#endif
|
||||||
|
const char* preferred = preferred_driver_.empty() ? nullptr : preferred_driver_.c_str();
|
||||||
|
device_ = SDL_CreateGPUDevice(PREFERRED, false, preferred);
|
||||||
|
if (device_ == nullptr && preferred != nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: driver '" << preferred << "' not available, falling back to auto" << '\n';
|
||||||
|
device_ = SDL_CreateGPUDevice(PREFERRED, false, nullptr);
|
||||||
|
}
|
||||||
|
if (device_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: SDL_CreateGPUDevice failed: " << SDL_GetError() << '\n';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
driver_name_ = SDL_GetGPUDeviceDriver(device_);
|
||||||
|
std::cout << "SDL3GPUShader: driver = " << driver_name_ << '\n';
|
||||||
|
|
||||||
|
if (!SDL_ClaimWindowForGPUDevice(device_, window_)) {
|
||||||
|
std::cout << "SDL3GPUShader: SDL_ClaimWindowForGPUDevice failed: " << SDL_GetError() << '\n';
|
||||||
|
SDL_DestroyGPUDevice(device_);
|
||||||
|
device_ = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SDL_SetGPUSwapchainParameters(device_, window_, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, bestPresentMode(vsync_));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Create scene texture (game resolution)
|
||||||
|
SDL_GPUTextureCreateInfo tex_info = {};
|
||||||
|
tex_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||||
|
tex_info.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
|
||||||
|
tex_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
||||||
|
tex_info.width = static_cast<Uint32>(game_width_);
|
||||||
|
tex_info.height = static_cast<Uint32>(game_height_);
|
||||||
|
tex_info.layer_count_or_depth = 1;
|
||||||
|
tex_info.num_levels = 1;
|
||||||
|
scene_texture_ = SDL_CreateGPUTexture(device_, &tex_info);
|
||||||
|
if (scene_texture_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: failed to create scene texture: " << SDL_GetError() << '\n';
|
||||||
|
cleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Create upload transfer buffer (game resolution)
|
||||||
|
SDL_GPUTransferBufferCreateInfo tb_info = {};
|
||||||
|
tb_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||||
|
tb_info.size = static_cast<Uint32>(game_width_ * game_height_ * 4);
|
||||||
|
upload_buffer_ = SDL_CreateGPUTransferBuffer(device_, &tb_info);
|
||||||
|
if (upload_buffer_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: failed to create upload buffer: " << SDL_GetError() << '\n';
|
||||||
|
cleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Create nearest sampler
|
||||||
|
SDL_GPUSamplerCreateInfo samp_info = {};
|
||||||
|
samp_info.min_filter = SDL_GPU_FILTER_NEAREST;
|
||||||
|
samp_info.mag_filter = SDL_GPU_FILTER_NEAREST;
|
||||||
|
samp_info.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST;
|
||||||
|
samp_info.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
samp_info.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
samp_info.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
sampler_ = SDL_CreateGPUSampler(device_, &samp_info);
|
||||||
|
if (sampler_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: failed to create sampler: " << SDL_GetError() << '\n';
|
||||||
|
cleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Create pipelines
|
||||||
|
if (!createPipeline()) {
|
||||||
|
cleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!createCrtPiPipeline()) {
|
||||||
|
cleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_initialized_ = true;
|
||||||
|
std::cout << "SDL3GPUShader: initialized OK (" << game_width_ << "x" << game_height_ << ")" << '\n';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// createPipeline — PostFX → swapchain
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
auto SDL3GPUShader::createPipeline() -> bool {
|
||||||
|
const SDL_GPUTextureFormat SWAPCHAIN_FMT = SDL_GetGPUSwapchainTextureFormat(device_, window_);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
SDL_GPUShader* vert = createShaderMSL(device_, Msl::kPostfxVert, "postfx_vs", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0);
|
||||||
|
SDL_GPUShader* frag = createShaderMSL(device_, Msl::kPostfxFrag, "postfx_fs", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1);
|
||||||
|
#else
|
||||||
|
SDL_GPUShader* vert = createShaderSPIRV(device_, kpostfx_vert_spv, kpostfx_vert_spv_size, "main", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0);
|
||||||
|
SDL_GPUShader* frag = createShaderSPIRV(device_, kpostfx_frag_spv, kpostfx_frag_spv_size, "main", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((vert == nullptr) || (frag == nullptr)) {
|
||||||
|
std::cout << "SDL3GPUShader: failed to compile PostFX shaders" << '\n';
|
||||||
|
if (vert != nullptr) { SDL_ReleaseGPUShader(device_, vert); }
|
||||||
|
if (frag != nullptr) { SDL_ReleaseGPUShader(device_, frag); }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GPUColorTargetBlendState no_blend = {};
|
||||||
|
no_blend.enable_blend = false;
|
||||||
|
no_blend.enable_color_write_mask = false;
|
||||||
|
|
||||||
|
SDL_GPUColorTargetDescription color_target = {};
|
||||||
|
color_target.format = SWAPCHAIN_FMT;
|
||||||
|
color_target.blend_state = no_blend;
|
||||||
|
|
||||||
|
SDL_GPUVertexInputState no_input = {};
|
||||||
|
|
||||||
|
SDL_GPUGraphicsPipelineCreateInfo pipe_info = {};
|
||||||
|
pipe_info.vertex_shader = vert;
|
||||||
|
pipe_info.fragment_shader = frag;
|
||||||
|
pipe_info.vertex_input_state = no_input;
|
||||||
|
pipe_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST;
|
||||||
|
pipe_info.target_info.num_color_targets = 1;
|
||||||
|
pipe_info.target_info.color_target_descriptions = &color_target;
|
||||||
|
|
||||||
|
pipeline_ = SDL_CreateGPUGraphicsPipeline(device_, &pipe_info);
|
||||||
|
SDL_ReleaseGPUShader(device_, vert);
|
||||||
|
SDL_ReleaseGPUShader(device_, frag);
|
||||||
|
|
||||||
|
if (pipeline_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: PostFX pipeline creation failed: " << SDL_GetError() << '\n';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// createCrtPiPipeline
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
auto SDL3GPUShader::createCrtPiPipeline() -> bool {
|
||||||
|
const SDL_GPUTextureFormat SWAPCHAIN_FMT = SDL_GetGPUSwapchainTextureFormat(device_, window_);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
SDL_GPUShader* vert = createShaderMSL(device_, Msl::kPostfxVert, "postfx_vs", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0);
|
||||||
|
SDL_GPUShader* frag = createShaderMSL(device_, Msl::kCrtpiFrag, "crtpi_fs", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1);
|
||||||
|
#else
|
||||||
|
SDL_GPUShader* vert = createShaderSPIRV(device_, kpostfx_vert_spv, kpostfx_vert_spv_size, "main", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0);
|
||||||
|
SDL_GPUShader* frag = createShaderSPIRV(device_, kcrtpi_frag_spv, kcrtpi_frag_spv_size, "main", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((vert == nullptr) || (frag == nullptr)) {
|
||||||
|
if (vert != nullptr) { SDL_ReleaseGPUShader(device_, vert); }
|
||||||
|
if (frag != nullptr) { SDL_ReleaseGPUShader(device_, frag); }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GPUColorTargetBlendState no_blend = {};
|
||||||
|
SDL_GPUColorTargetDescription ct = {};
|
||||||
|
ct.format = SWAPCHAIN_FMT;
|
||||||
|
ct.blend_state = no_blend;
|
||||||
|
|
||||||
|
SDL_GPUVertexInputState no_input = {};
|
||||||
|
SDL_GPUGraphicsPipelineCreateInfo pi = {};
|
||||||
|
pi.vertex_shader = vert;
|
||||||
|
pi.fragment_shader = frag;
|
||||||
|
pi.vertex_input_state = no_input;
|
||||||
|
pi.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST;
|
||||||
|
pi.target_info.num_color_targets = 1;
|
||||||
|
pi.target_info.color_target_descriptions = &ct;
|
||||||
|
|
||||||
|
crtpi_pipeline_ = SDL_CreateGPUGraphicsPipeline(device_, &pi);
|
||||||
|
SDL_ReleaseGPUShader(device_, vert);
|
||||||
|
SDL_ReleaseGPUShader(device_, frag);
|
||||||
|
|
||||||
|
if (crtpi_pipeline_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: CrtPi pipeline creation failed: " << SDL_GetError() << '\n';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// uploadPixels — direct memcpy
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
void SDL3GPUShader::uploadPixels(const Uint32* pixels, int width, int height) {
|
||||||
|
if (!is_initialized_ || (upload_buffer_ == nullptr)) { return; }
|
||||||
|
|
||||||
|
void* mapped = SDL_MapGPUTransferBuffer(device_, upload_buffer_, false);
|
||||||
|
if (mapped == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: SDL_MapGPUTransferBuffer failed: " << SDL_GetError() << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(mapped, pixels, static_cast<size_t>(width) * height * 4);
|
||||||
|
SDL_UnmapGPUTransferBuffer(device_, upload_buffer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// render — CrtPi direct OR PostFX direct → swapchain
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
void SDL3GPUShader::render() {
|
||||||
|
if (!is_initialized_) { return; }
|
||||||
|
|
||||||
|
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(device_);
|
||||||
|
if (cmd == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: SDL_AcquireGPUCommandBuffer failed: " << SDL_GetError() << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Copy pass: transfer buffer → scene texture ----
|
||||||
|
SDL_GPUCopyPass* copy = SDL_BeginGPUCopyPass(cmd);
|
||||||
|
if (copy != nullptr) {
|
||||||
|
SDL_GPUTextureTransferInfo src = {};
|
||||||
|
src.transfer_buffer = upload_buffer_;
|
||||||
|
src.offset = 0;
|
||||||
|
src.pixels_per_row = static_cast<Uint32>(game_width_);
|
||||||
|
src.rows_per_layer = static_cast<Uint32>(game_height_);
|
||||||
|
|
||||||
|
SDL_GPUTextureRegion dst = {};
|
||||||
|
dst.texture = scene_texture_;
|
||||||
|
dst.w = static_cast<Uint32>(game_width_);
|
||||||
|
dst.h = static_cast<Uint32>(game_height_);
|
||||||
|
dst.d = 1;
|
||||||
|
|
||||||
|
SDL_UploadToGPUTexture(copy, &src, &dst, false);
|
||||||
|
SDL_EndGPUCopyPass(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Acquire swapchain texture ----
|
||||||
|
SDL_GPUTexture* swapchain = nullptr;
|
||||||
|
Uint32 sw = 0;
|
||||||
|
Uint32 sh = 0;
|
||||||
|
if (!SDL_AcquireGPUSwapchainTexture(cmd, window_, &swapchain, &sw, &sh)) {
|
||||||
|
std::cout << "SDL3GPUShader: SDL_AcquireGPUSwapchainTexture failed: " << SDL_GetError() << '\n';
|
||||||
|
SDL_SubmitGPUCommandBuffer(cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (swapchain == nullptr) {
|
||||||
|
SDL_SubmitGPUCommandBuffer(cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Viewport calculation ----
|
||||||
|
float vx = 0.0F;
|
||||||
|
float vy = 0.0F;
|
||||||
|
float vw = 0.0F;
|
||||||
|
float vh = 0.0F;
|
||||||
|
if (integer_scale_) {
|
||||||
|
const int SCALE = std::max(1, std::min(static_cast<int>(sw) / game_width_, static_cast<int>(sh) / game_height_));
|
||||||
|
vw = static_cast<float>(game_width_ * SCALE);
|
||||||
|
vh = static_cast<float>(game_height_ * SCALE);
|
||||||
|
} else {
|
||||||
|
const float SCALE = std::min(
|
||||||
|
static_cast<float>(sw) / static_cast<float>(game_width_),
|
||||||
|
static_cast<float>(sh) / static_cast<float>(game_height_));
|
||||||
|
vw = static_cast<float>(game_width_) * SCALE;
|
||||||
|
vh = static_cast<float>(game_height_) * SCALE;
|
||||||
|
}
|
||||||
|
vx = std::floor((static_cast<float>(sw) - vw) * 0.5F);
|
||||||
|
vy = std::floor((static_cast<float>(sh) - vh) * 0.5F);
|
||||||
|
|
||||||
|
uniforms_.pixel_scale = (game_height_ > 0) ? (vh / static_cast<float>(game_height_)) : 1.0F;
|
||||||
|
uniforms_.time = static_cast<float>(SDL_GetTicks()) / 1000.0F;
|
||||||
|
|
||||||
|
SDL_GPUColorTargetInfo ct = {};
|
||||||
|
ct.texture = swapchain;
|
||||||
|
ct.load_op = SDL_GPU_LOADOP_CLEAR;
|
||||||
|
ct.store_op = SDL_GPU_STOREOP_STORE;
|
||||||
|
ct.clear_color = {.r = 0.0F, .g = 0.0F, .b = 0.0F, .a = 1.0F};
|
||||||
|
|
||||||
|
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &ct, 1, nullptr);
|
||||||
|
if (pass != nullptr) {
|
||||||
|
SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F};
|
||||||
|
SDL_SetGPUViewport(pass, &vp);
|
||||||
|
|
||||||
|
SDL_GPUTextureSamplerBinding binding = {};
|
||||||
|
binding.texture = scene_texture_;
|
||||||
|
binding.sampler = sampler_;
|
||||||
|
SDL_BindGPUFragmentSamplers(pass, 0, &binding, 1);
|
||||||
|
|
||||||
|
if (active_shader_ == ShaderType::CRTPI && crtpi_pipeline_ != nullptr) {
|
||||||
|
SDL_BindGPUGraphicsPipeline(pass, crtpi_pipeline_);
|
||||||
|
crtpi_uniforms_.texture_width = static_cast<float>(game_width_);
|
||||||
|
crtpi_uniforms_.texture_height = static_cast<float>(game_height_);
|
||||||
|
SDL_PushGPUFragmentUniformData(cmd, 0, &crtpi_uniforms_, sizeof(CrtPiUniforms));
|
||||||
|
} else {
|
||||||
|
SDL_BindGPUGraphicsPipeline(pass, pipeline_);
|
||||||
|
SDL_PushGPUFragmentUniformData(cmd, 0, &uniforms_, sizeof(PostFXUniforms));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0);
|
||||||
|
SDL_EndGPURenderPass(pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SubmitGPUCommandBuffer(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// cleanup
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
void SDL3GPUShader::cleanup() {
|
||||||
|
is_initialized_ = false;
|
||||||
|
|
||||||
|
if (device_ != nullptr) {
|
||||||
|
SDL_WaitForGPUIdle(device_);
|
||||||
|
|
||||||
|
auto release_pipeline = [this](SDL_GPUGraphicsPipeline*& p) {
|
||||||
|
if (p != nullptr) {
|
||||||
|
SDL_ReleaseGPUGraphicsPipeline(device_, p);
|
||||||
|
p = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto release_texture = [this](SDL_GPUTexture*& t) {
|
||||||
|
if (t != nullptr) {
|
||||||
|
SDL_ReleaseGPUTexture(device_, t);
|
||||||
|
t = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
release_pipeline(pipeline_);
|
||||||
|
release_pipeline(crtpi_pipeline_);
|
||||||
|
release_texture(scene_texture_);
|
||||||
|
if (upload_buffer_ != nullptr) {
|
||||||
|
SDL_ReleaseGPUTransferBuffer(device_, upload_buffer_);
|
||||||
|
upload_buffer_ = nullptr;
|
||||||
|
}
|
||||||
|
if (sampler_ != nullptr) {
|
||||||
|
SDL_ReleaseGPUSampler(device_, sampler_);
|
||||||
|
sampler_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// destroy
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
void SDL3GPUShader::destroy() {
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
if (device_ != nullptr) {
|
||||||
|
if (window_ != nullptr) {
|
||||||
|
SDL_ReleaseWindowFromGPUDevice(device_, window_);
|
||||||
|
}
|
||||||
|
SDL_DestroyGPUDevice(device_);
|
||||||
|
device_ = nullptr;
|
||||||
|
}
|
||||||
|
window_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Shader creation helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
auto SDL3GPUShader::createShaderMSL(SDL_GPUDevice* device,
|
||||||
|
const char* msl_source,
|
||||||
|
const char* entrypoint,
|
||||||
|
SDL_GPUShaderStage stage,
|
||||||
|
Uint32 num_samplers,
|
||||||
|
Uint32 num_uniform_buffers) -> SDL_GPUShader* {
|
||||||
|
SDL_GPUShaderCreateInfo info = {};
|
||||||
|
info.code = reinterpret_cast<const Uint8*>(msl_source);
|
||||||
|
info.code_size = std::strlen(msl_source) + 1;
|
||||||
|
info.entrypoint = entrypoint;
|
||||||
|
info.format = SDL_GPU_SHADERFORMAT_MSL;
|
||||||
|
info.stage = stage;
|
||||||
|
info.num_samplers = num_samplers;
|
||||||
|
info.num_uniform_buffers = num_uniform_buffers;
|
||||||
|
SDL_GPUShader* shader = SDL_CreateGPUShader(device, &info);
|
||||||
|
if (shader == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: MSL shader '" << entrypoint << "' failed: " << SDL_GetError() << '\n';
|
||||||
|
}
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SDL3GPUShader::createShaderSPIRV(SDL_GPUDevice* device,
|
||||||
|
const uint8_t* spv_code,
|
||||||
|
size_t spv_size,
|
||||||
|
const char* entrypoint,
|
||||||
|
SDL_GPUShaderStage stage,
|
||||||
|
Uint32 num_samplers,
|
||||||
|
Uint32 num_uniform_buffers) -> SDL_GPUShader* {
|
||||||
|
SDL_GPUShaderCreateInfo info = {};
|
||||||
|
info.code = spv_code;
|
||||||
|
info.code_size = spv_size;
|
||||||
|
info.entrypoint = entrypoint;
|
||||||
|
info.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||||
|
info.stage = stage;
|
||||||
|
info.num_samplers = num_samplers;
|
||||||
|
info.num_uniform_buffers = num_uniform_buffers;
|
||||||
|
SDL_GPUShader* shader = SDL_CreateGPUShader(device, &info);
|
||||||
|
if (shader == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: SPIRV shader '" << entrypoint << "' failed: " << SDL_GetError() << '\n';
|
||||||
|
}
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL3GPUShader::setPostFXParams(const PostFXParams& p) {
|
||||||
|
uniforms_.vignette_strength = p.vignette;
|
||||||
|
uniforms_.chroma_min = p.chroma_min;
|
||||||
|
uniforms_.chroma_max = p.chroma_max;
|
||||||
|
uniforms_.scanline_strength = p.scanlines;
|
||||||
|
uniforms_.mask_strength = p.mask;
|
||||||
|
uniforms_.gamma_strength = p.gamma;
|
||||||
|
uniforms_.curvature = p.curvature;
|
||||||
|
uniforms_.bleeding = p.bleeding;
|
||||||
|
uniforms_.flicker = p.flicker;
|
||||||
|
uniforms_.scan_dark_ratio = p.scan_dark_ratio;
|
||||||
|
uniforms_.scan_dark_floor = p.scan_dark_floor;
|
||||||
|
uniforms_.scan_edge_soft = p.scan_edge_soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL3GPUShader::setCrtPiParams(const CrtPiParams& p) {
|
||||||
|
crtpi_uniforms_.scanline_weight = p.scanline_weight;
|
||||||
|
crtpi_uniforms_.scanline_gap_brightness = p.scanline_gap_brightness;
|
||||||
|
crtpi_uniforms_.bloom_factor = p.bloom_factor;
|
||||||
|
crtpi_uniforms_.input_gamma = p.input_gamma;
|
||||||
|
crtpi_uniforms_.output_gamma = p.output_gamma;
|
||||||
|
crtpi_uniforms_.mask_brightness = p.mask_brightness;
|
||||||
|
crtpi_uniforms_.curvature_x = p.curvature_x;
|
||||||
|
crtpi_uniforms_.curvature_y = p.curvature_y;
|
||||||
|
crtpi_uniforms_.mask_type = p.mask_type;
|
||||||
|
crtpi_uniforms_.enable_scanlines = p.enable_scanlines ? 1 : 0;
|
||||||
|
crtpi_uniforms_.enable_multisample = p.enable_multisample ? 1 : 0;
|
||||||
|
crtpi_uniforms_.enable_gamma = p.enable_gamma ? 1 : 0;
|
||||||
|
crtpi_uniforms_.enable_curvature = p.enable_curvature ? 1 : 0;
|
||||||
|
crtpi_uniforms_.enable_sharper = p.enable_sharper ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL3GPUShader::setActiveShader(ShaderType type) {
|
||||||
|
active_shader_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SDL3GPUShader::bestPresentMode(bool vsync) const -> SDL_GPUPresentMode {
|
||||||
|
if (vsync) { return SDL_GPU_PRESENTMODE_VSYNC; }
|
||||||
|
if (SDL_WindowSupportsGPUPresentMode(device_, window_, SDL_GPU_PRESENTMODE_IMMEDIATE)) {
|
||||||
|
return SDL_GPU_PRESENTMODE_IMMEDIATE;
|
||||||
|
}
|
||||||
|
if (SDL_WindowSupportsGPUPresentMode(device_, window_, SDL_GPU_PRESENTMODE_MAILBOX)) {
|
||||||
|
return SDL_GPU_PRESENTMODE_MAILBOX;
|
||||||
|
}
|
||||||
|
return SDL_GPU_PRESENTMODE_VSYNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL3GPUShader::setVSync(bool vsync) {
|
||||||
|
vsync_ = vsync;
|
||||||
|
if (device_ != nullptr && window_ != nullptr) {
|
||||||
|
SDL_SetGPUSwapchainParameters(device_, window_, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, bestPresentMode(vsync_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL3GPUShader::setScaleMode(bool integer_scale) {
|
||||||
|
integer_scale_ = integer_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// reinitTexturesAndBuffer
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
auto SDL3GPUShader::reinitTexturesAndBuffer() -> bool {
|
||||||
|
if (device_ == nullptr) { return false; }
|
||||||
|
SDL_WaitForGPUIdle(device_);
|
||||||
|
|
||||||
|
if (scene_texture_ != nullptr) {
|
||||||
|
SDL_ReleaseGPUTexture(device_, scene_texture_);
|
||||||
|
scene_texture_ = nullptr;
|
||||||
|
}
|
||||||
|
if (upload_buffer_ != nullptr) {
|
||||||
|
SDL_ReleaseGPUTransferBuffer(device_, upload_buffer_);
|
||||||
|
upload_buffer_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uniforms_.screen_height = static_cast<float>(game_height_);
|
||||||
|
|
||||||
|
SDL_GPUTextureCreateInfo tex_info = {};
|
||||||
|
tex_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||||
|
tex_info.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
|
||||||
|
tex_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
||||||
|
tex_info.width = static_cast<Uint32>(game_width_);
|
||||||
|
tex_info.height = static_cast<Uint32>(game_height_);
|
||||||
|
tex_info.layer_count_or_depth = 1;
|
||||||
|
tex_info.num_levels = 1;
|
||||||
|
scene_texture_ = SDL_CreateGPUTexture(device_, &tex_info);
|
||||||
|
if (scene_texture_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: reinit — failed to create scene texture: " << SDL_GetError() << '\n';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GPUTransferBufferCreateInfo tb_info = {};
|
||||||
|
tb_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||||
|
tb_info.size = static_cast<Uint32>(game_width_ * game_height_ * 4);
|
||||||
|
upload_buffer_ = SDL_CreateGPUTransferBuffer(device_, &tb_info);
|
||||||
|
if (upload_buffer_ == nullptr) {
|
||||||
|
std::cout << "SDL3GPUShader: reinit — failed to create upload buffer: " << SDL_GetError() << '\n';
|
||||||
|
SDL_ReleaseGPUTexture(device_, scene_texture_);
|
||||||
|
scene_texture_ = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "SDL3GPUShader: reinit — scene " << game_width_ << "x" << game_height_ << '\n';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Rendering
|
||||||
+48
-37
@@ -4,25 +4,32 @@
|
|||||||
#include <SDL3/SDL_gpu.h>
|
#include <SDL3/SDL_gpu.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "rendering/shader_backend.hpp"
|
#include "core/rendering/shader_backend.hpp"
|
||||||
|
|
||||||
// PostFX uniforms pushed to fragment stage each frame.
|
// PostFX uniforms pushed to fragment stage each frame.
|
||||||
// 12 floats = 48 bytes — meets Metal/Vulkan 16-byte alignment requirement.
|
// 16 floats = 64 bytes (4 × vec4) — std140/scalar layout for Vulkan + Metal.
|
||||||
struct PostFXUniforms {
|
struct PostFXUniforms {
|
||||||
|
// vec4 #0
|
||||||
float vignette_strength;
|
float vignette_strength;
|
||||||
float chroma_strength;
|
float chroma_min;
|
||||||
float scanline_strength;
|
float scanline_strength;
|
||||||
float screen_height;
|
float screen_height;
|
||||||
|
// vec4 #1
|
||||||
float mask_strength;
|
float mask_strength;
|
||||||
float gamma_strength;
|
float gamma_strength;
|
||||||
float curvature;
|
float curvature;
|
||||||
float bleeding;
|
float bleeding;
|
||||||
|
// vec4 #2
|
||||||
float pixel_scale;
|
float pixel_scale;
|
||||||
float time;
|
float time;
|
||||||
float oversample;
|
|
||||||
float flicker;
|
float flicker;
|
||||||
|
float chroma_max;
|
||||||
|
// vec4 #3 — paràmetres de scanlines exposats al preset YAML
|
||||||
|
float scan_dark_ratio;
|
||||||
|
float scan_dark_floor;
|
||||||
|
float scan_edge_soft;
|
||||||
|
float pad3;
|
||||||
};
|
};
|
||||||
|
|
||||||
// CrtPi uniforms pushed to fragment stage each frame.
|
// CrtPi uniforms pushed to fragment stage each frame.
|
||||||
@@ -46,22 +53,13 @@ struct CrtPiUniforms {
|
|||||||
float texture_height;
|
float texture_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Downscale uniforms for Lanczos downscale fragment stage.
|
|
||||||
// 1 int + 3 floats = 16 bytes.
|
|
||||||
struct DownscaleUniforms {
|
|
||||||
int algorithm;
|
|
||||||
float pad0;
|
|
||||||
float pad1;
|
|
||||||
float pad2;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Rendering {
|
namespace Rendering {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Backend de shaders usando SDL3 GPU API (Metal en macOS, Vulkan/SPIR-V en Win/Linux)
|
* @brief Backend de shaders usando SDL3 GPU API (Metal en macOS, Vulkan/SPIR-V en Win/Linux)
|
||||||
*
|
*
|
||||||
* Pipeline: Surface pixels (CPU) → SDL_GPUTransferBuffer → SDL_GPUTexture (scene)
|
* Pipeline: Surface pixels (CPU) → SDL_GPUTransferBuffer → SDL_GPUTexture (scene)
|
||||||
* → [Upscale →] PostFX/CrtPi render pass → [Lanczos downscale →] swapchain → present
|
* → PostFX/CrtPi render pass → swapchain → present
|
||||||
*/
|
*/
|
||||||
class SDL3GPUShader : public ShaderBackend {
|
class SDL3GPUShader : public ShaderBackend {
|
||||||
public:
|
public:
|
||||||
@@ -74,7 +72,7 @@ namespace Rendering {
|
|||||||
const std::string& fragment_source) -> bool override;
|
const std::string& fragment_source) -> bool override;
|
||||||
|
|
||||||
void render() override;
|
void render() override;
|
||||||
void setTextureSize(float width, float height) override {}
|
void setTextureSize(float /*width*/, float /*height*/) override {}
|
||||||
void cleanup() final;
|
void cleanup() final;
|
||||||
void destroy();
|
void destroy();
|
||||||
[[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; }
|
[[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; }
|
||||||
@@ -85,13 +83,6 @@ namespace Rendering {
|
|||||||
void setPostFXParams(const PostFXParams& p) override;
|
void setPostFXParams(const PostFXParams& p) override;
|
||||||
void setVSync(bool vsync) override;
|
void setVSync(bool vsync) override;
|
||||||
void setScaleMode(bool integer_scale) override;
|
void setScaleMode(bool integer_scale) override;
|
||||||
void setOversample(int factor) override;
|
|
||||||
|
|
||||||
void setLinearUpscale(bool linear) override;
|
|
||||||
[[nodiscard]] auto isLinearUpscale() const -> bool override { return linear_upscale_; }
|
|
||||||
void setDownscaleAlgo(int algo) override;
|
|
||||||
[[nodiscard]] auto getDownscaleAlgo() const -> int override { return downscale_algo_; }
|
|
||||||
[[nodiscard]] auto getSsTextureSize() const -> std::pair<int, int> override;
|
|
||||||
|
|
||||||
void setActiveShader(ShaderType type) override;
|
void setActiveShader(ShaderType type) override;
|
||||||
void setCrtPiParams(const CrtPiParams& p) override;
|
void setCrtPiParams(const CrtPiParams& p) override;
|
||||||
@@ -116,39 +107,59 @@ namespace Rendering {
|
|||||||
auto createPipeline() -> bool;
|
auto createPipeline() -> bool;
|
||||||
auto createCrtPiPipeline() -> bool;
|
auto createCrtPiPipeline() -> bool;
|
||||||
auto reinitTexturesAndBuffer() -> bool;
|
auto reinitTexturesAndBuffer() -> bool;
|
||||||
auto recreateScaledTexture(int factor) -> bool;
|
|
||||||
static auto calcSsFactor(float zoom) -> int;
|
|
||||||
[[nodiscard]] auto bestPresentMode(bool vsync) const -> SDL_GPUPresentMode;
|
[[nodiscard]] auto bestPresentMode(bool vsync) const -> SDL_GPUPresentMode;
|
||||||
|
|
||||||
SDL_Window* window_ = nullptr;
|
SDL_Window* window_ = nullptr;
|
||||||
SDL_GPUDevice* device_ = nullptr;
|
SDL_GPUDevice* device_ = nullptr;
|
||||||
SDL_GPUGraphicsPipeline* pipeline_ = nullptr;
|
SDL_GPUGraphicsPipeline* pipeline_ = nullptr;
|
||||||
SDL_GPUGraphicsPipeline* crtpi_pipeline_ = nullptr;
|
SDL_GPUGraphicsPipeline* crtpi_pipeline_ = nullptr;
|
||||||
SDL_GPUGraphicsPipeline* postfx_offscreen_pipeline_ = nullptr;
|
|
||||||
SDL_GPUGraphicsPipeline* upscale_pipeline_ = nullptr;
|
|
||||||
SDL_GPUGraphicsPipeline* downscale_pipeline_ = nullptr;
|
|
||||||
SDL_GPUTexture* scene_texture_ = nullptr;
|
SDL_GPUTexture* scene_texture_ = nullptr;
|
||||||
SDL_GPUTexture* scaled_texture_ = nullptr;
|
|
||||||
SDL_GPUTexture* postfx_texture_ = nullptr;
|
|
||||||
SDL_GPUTransferBuffer* upload_buffer_ = nullptr;
|
SDL_GPUTransferBuffer* upload_buffer_ = nullptr;
|
||||||
SDL_GPUSampler* sampler_ = nullptr;
|
SDL_GPUSampler* sampler_ = nullptr;
|
||||||
SDL_GPUSampler* linear_sampler_ = nullptr;
|
|
||||||
|
|
||||||
PostFXUniforms uniforms_{.vignette_strength = 0.6F, .chroma_strength = 0.15F, .scanline_strength = 0.7F, .screen_height = 192.0F, .pixel_scale = 1.0F, .oversample = 1.0F};
|
PostFXUniforms uniforms_{
|
||||||
CrtPiUniforms crtpi_uniforms_{.scanline_weight = 6.0F, .scanline_gap_brightness = 0.12F, .bloom_factor = 3.5F, .input_gamma = 2.4F, .output_gamma = 2.2F, .mask_brightness = 0.80F, .curvature_x = 0.05F, .curvature_y = 0.10F, .mask_type = 2, .enable_scanlines = 1, .enable_multisample = 1, .enable_gamma = 1};
|
.vignette_strength = 0.6F,
|
||||||
|
.chroma_min = 0.15F,
|
||||||
|
.scanline_strength = 0.7F,
|
||||||
|
.screen_height = 192.0F,
|
||||||
|
.mask_strength = 0.0F,
|
||||||
|
.gamma_strength = 0.0F,
|
||||||
|
.curvature = 0.0F,
|
||||||
|
.bleeding = 0.0F,
|
||||||
|
.pixel_scale = 1.0F,
|
||||||
|
.time = 0.0F,
|
||||||
|
.flicker = 0.0F,
|
||||||
|
.chroma_max = 0.15F,
|
||||||
|
.scan_dark_ratio = 0.333F,
|
||||||
|
.scan_dark_floor = 0.42F,
|
||||||
|
.scan_edge_soft = 1.0F,
|
||||||
|
.pad3 = 0.0F};
|
||||||
|
CrtPiUniforms crtpi_uniforms_{
|
||||||
|
.scanline_weight = 6.0F,
|
||||||
|
.scanline_gap_brightness = 0.12F,
|
||||||
|
.bloom_factor = 3.5F,
|
||||||
|
.input_gamma = 2.4F,
|
||||||
|
.output_gamma = 2.2F,
|
||||||
|
.mask_brightness = 0.80F,
|
||||||
|
.curvature_x = 0.05F,
|
||||||
|
.curvature_y = 0.10F,
|
||||||
|
.mask_type = 2,
|
||||||
|
.enable_scanlines = 1,
|
||||||
|
.enable_multisample = 1,
|
||||||
|
.enable_gamma = 1,
|
||||||
|
.enable_curvature = 0,
|
||||||
|
.enable_sharper = 0,
|
||||||
|
.texture_width = 0.0F,
|
||||||
|
.texture_height = 0.0F};
|
||||||
ShaderType active_shader_ = ShaderType::POSTFX;
|
ShaderType active_shader_ = ShaderType::POSTFX;
|
||||||
|
|
||||||
int game_width_ = 0;
|
int game_width_ = 0;
|
||||||
int game_height_ = 0;
|
int game_height_ = 0;
|
||||||
int ss_factor_ = 0;
|
|
||||||
int oversample_ = 1;
|
|
||||||
int downscale_algo_ = 1;
|
|
||||||
std::string driver_name_;
|
std::string driver_name_;
|
||||||
std::string preferred_driver_;
|
std::string preferred_driver_;
|
||||||
bool is_initialized_ = false;
|
bool is_initialized_ = false;
|
||||||
bool vsync_ = true;
|
bool vsync_ = true;
|
||||||
bool integer_scale_ = false;
|
bool integer_scale_ = false;
|
||||||
bool linear_upscale_ = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Rendering
|
} // namespace Rendering
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
DisableFormat: true
|
||||||
|
SortIncludes: Never
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# source/core/rendering/sdl3gpu/spv/.clang-tidy
|
||||||
|
Checks: '-*'
|
||||||
|
WarningsAsErrors: ''
|
||||||
|
HeaderFilterRegex: ''
|
||||||
+2
-1
@@ -10357,5 +10357,6 @@ static const uint8_t kcrtpi_frag_spv[] = {
|
|||||||
0x38,
|
0x38,
|
||||||
0x00,
|
0x00,
|
||||||
0x01,
|
0x01,
|
||||||
0x00};
|
0x00,
|
||||||
|
};
|
||||||
static const size_t kcrtpi_frag_spv_size = 10356;
|
static const size_t kcrtpi_frag_spv_size = 10356;
|
||||||
+9633
-7224
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -1445,5 +1445,6 @@ static const uint8_t kpostfx_vert_spv[] = {
|
|||||||
0x38,
|
0x38,
|
||||||
0x00,
|
0x00,
|
||||||
0x01,
|
0x01,
|
||||||
0x00};
|
0x00,
|
||||||
|
};
|
||||||
static const size_t kpostfx_vert_spv_size = 1444;
|
static const size_t kpostfx_vert_spv_size = 1444;
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace Rendering {
|
namespace Rendering {
|
||||||
|
|
||||||
/** @brief Identificador del shader de post-procesado activo */
|
/** @brief Identificador del shader de post-procesado activo */
|
||||||
enum class ShaderType { POSTFX,
|
enum class ShaderType : std::uint8_t { POSTFX,
|
||||||
CRTPI };
|
CRTPI };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,12 +17,19 @@ namespace Rendering {
|
|||||||
struct PostFXParams {
|
struct PostFXParams {
|
||||||
float vignette = 0.0F;
|
float vignette = 0.0F;
|
||||||
float scanlines = 0.0F;
|
float scanlines = 0.0F;
|
||||||
float chroma = 0.0F;
|
// Aberració cromàtica — varia entre min i max via sinusoidal; si coincideixen
|
||||||
|
// queda estàtica. Permet un "floor" perquè la imatge mai sigui lliure de chroma.
|
||||||
|
float chroma_min = 0.0F;
|
||||||
|
float chroma_max = 0.0F;
|
||||||
float mask = 0.0F;
|
float mask = 0.0F;
|
||||||
float gamma = 0.0F;
|
float gamma = 0.0F;
|
||||||
float curvature = 0.0F;
|
float curvature = 0.0F;
|
||||||
float bleeding = 0.0F;
|
float bleeding = 0.0F;
|
||||||
float flicker = 0.0F;
|
float flicker = 0.0F;
|
||||||
|
// Forma de les scanlines — 3 subpíxels per fila lògica per defecte.
|
||||||
|
float scan_dark_ratio{0.333F};
|
||||||
|
float scan_dark_floor{0.42F};
|
||||||
|
float scan_edge_soft{1.0F};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,15 +72,6 @@ namespace Rendering {
|
|||||||
virtual void setPostFXParams(const PostFXParams& /*p*/) {}
|
virtual void setPostFXParams(const PostFXParams& /*p*/) {}
|
||||||
virtual void setVSync(bool /*vsync*/) {}
|
virtual void setVSync(bool /*vsync*/) {}
|
||||||
virtual void setScaleMode(bool /*integer_scale*/) {}
|
virtual void setScaleMode(bool /*integer_scale*/) {}
|
||||||
virtual void setOversample(int /*factor*/) {}
|
|
||||||
|
|
||||||
virtual void setLinearUpscale(bool /*linear*/) {}
|
|
||||||
[[nodiscard]] virtual auto isLinearUpscale() const -> bool { return false; }
|
|
||||||
|
|
||||||
virtual void setDownscaleAlgo(int /*algo*/) {}
|
|
||||||
[[nodiscard]] virtual auto getDownscaleAlgo() const -> int { return 0; }
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto getSsTextureSize() const -> std::pair<int, int> { return {0, 0}; }
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto isHardwareAccelerated() const -> bool = 0;
|
[[nodiscard]] virtual auto isHardwareAccelerated() const -> bool = 0;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "animated_sprite.hpp"
|
#include "core/rendering/sprite/animated_sprite.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError, SDL_FRect
|
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError, SDL_FRect
|
||||||
|
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <utility> // Para move, pair
|
#include <utility> // Para move, pair
|
||||||
|
|
||||||
#include "resource_helper.hpp" // Para loadFile
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
#include "texture.hpp" // Para Texture
|
#include "core/resources/resource_helper.hpp" // Para loadFile
|
||||||
|
|
||||||
// Carga las animaciones en un vector(Animations) desde un fichero
|
// Carga las animaciones en un vector(Animations) desde un fichero
|
||||||
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer {
|
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer {
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "moving_sprite.hpp" // for MovingSprite
|
#include "core/rendering/sprite/moving_sprite.hpp" // for MovingSprite
|
||||||
|
|
||||||
// Declaración adelantada
|
// Declaración adelantada
|
||||||
class Texture;
|
class Texture;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "card_sprite.hpp"
|
#include "core/rendering/sprite/card_sprite.hpp"
|
||||||
|
|
||||||
#include <algorithm> // Para std::clamp
|
#include <algorithm> // Para std::clamp
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
#include "texture.hpp" // Para Texture
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
#include "utils.hpp" // Para easeOutBounce, easeOutCubic
|
#include "utils/utils.hpp" // Para easeOutBounce, easeOutCubic
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CardSprite::CardSprite(std::shared_ptr<Texture> texture)
|
CardSprite::CardSprite(std::shared_ptr<Texture> texture)
|
||||||
@@ -31,7 +31,7 @@ auto CardSprite::enable() -> bool {
|
|||||||
|
|
||||||
// Ángulo inicial
|
// Ángulo inicial
|
||||||
rotate_.angle = start_angle_;
|
rotate_.angle = start_angle_;
|
||||||
rotate_.center = {pos_.w / 2.0F, pos_.h / 2.0F};
|
rotate_.center = {.x = pos_.w / 2.0F, .y = pos_.h / 2.0F};
|
||||||
|
|
||||||
shadow_visible_ = true;
|
shadow_visible_ = true;
|
||||||
return true;
|
return true;
|
||||||
@@ -55,7 +55,7 @@ void CardSprite::startExit() {
|
|||||||
// Rotación continua
|
// Rotación continua
|
||||||
rotate_.enabled = true;
|
rotate_.enabled = true;
|
||||||
rotate_.amount = exit_rotate_amount_;
|
rotate_.amount = exit_rotate_amount_;
|
||||||
rotate_.center = {pos_.w / 2.0F, pos_.h / 2.0F};
|
rotate_.center = {.x = pos_.w / 2.0F, .y = pos_.h / 2.0F};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza según el estado
|
// Actualiza según el estado
|
||||||
@@ -80,7 +80,7 @@ void CardSprite::updateEntering(float delta_time) {
|
|||||||
double eased = entry_easing_(static_cast<double>(progress));
|
double eased = entry_easing_(static_cast<double>(progress));
|
||||||
|
|
||||||
// Zoom: de start_zoom_ a 1.0 con rebote
|
// Zoom: de start_zoom_ a 1.0 con rebote
|
||||||
auto current_zoom = static_cast<float>(start_zoom_ + (1.0 - start_zoom_) * eased);
|
auto current_zoom = static_cast<float>(start_zoom_ + ((1.0 - start_zoom_) * eased));
|
||||||
horizontal_zoom_ = current_zoom;
|
horizontal_zoom_ = current_zoom;
|
||||||
vertical_zoom_ = current_zoom;
|
vertical_zoom_ = current_zoom;
|
||||||
|
|
||||||
@@ -90,8 +90,8 @@ void CardSprite::updateEntering(float delta_time) {
|
|||||||
// Posición: de entry_start a landing con easing suave (sin rebote)
|
// Posición: de entry_start a landing con easing suave (sin rebote)
|
||||||
// Usamos easeOutCubic para que el desplazamiento sea fluido
|
// Usamos easeOutCubic para que el desplazamiento sea fluido
|
||||||
double pos_eased = easeOutCubic(static_cast<double>(progress));
|
double pos_eased = easeOutCubic(static_cast<double>(progress));
|
||||||
auto current_x = static_cast<float>(entry_start_x_ + (landing_x_ - entry_start_x_) * pos_eased);
|
auto current_x = static_cast<float>(entry_start_x_ + ((landing_x_ - entry_start_x_) * pos_eased));
|
||||||
auto current_y = static_cast<float>(entry_start_y_ + (landing_y_ - entry_start_y_) * pos_eased);
|
auto current_y = static_cast<float>(entry_start_y_ + ((landing_y_ - entry_start_y_) * pos_eased));
|
||||||
setPos(current_x, current_y);
|
setPos(current_x, current_y);
|
||||||
|
|
||||||
// Detecta el primer toque (cuando el easing alcanza ~1.0 por primera vez)
|
// Detecta el primer toque (cuando el easing alcanza ~1.0 por primera vez)
|
||||||
@@ -117,12 +117,9 @@ void CardSprite::updateExiting(float delta_time) {
|
|||||||
|
|
||||||
// Ganar altura gradualmente (zoom hacia el objetivo)
|
// Ganar altura gradualmente (zoom hacia el objetivo)
|
||||||
if (exit_zoom_speed_ > 0.0F && horizontal_zoom_ < exit_target_zoom_) {
|
if (exit_zoom_speed_ > 0.0F && horizontal_zoom_ < exit_target_zoom_) {
|
||||||
float new_zoom = horizontal_zoom_ + exit_zoom_speed_ * delta_time;
|
const float NEW_ZOOM = std::min(horizontal_zoom_ + (exit_zoom_speed_ * delta_time), exit_target_zoom_);
|
||||||
if (new_zoom > exit_target_zoom_) {
|
horizontal_zoom_ = NEW_ZOOM;
|
||||||
new_zoom = exit_target_zoom_;
|
vertical_zoom_ = NEW_ZOOM;
|
||||||
}
|
|
||||||
horizontal_zoom_ = new_zoom;
|
|
||||||
vertical_zoom_ = new_zoom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOffScreen()) {
|
if (isOffScreen()) {
|
||||||
@@ -164,8 +161,8 @@ void CardSprite::renderShadow() {
|
|||||||
|
|
||||||
// Offset respecto a la tarjeta: base + extra proporcional a la altura
|
// Offset respecto a la tarjeta: base + extra proporcional a la altura
|
||||||
// La sombra se aleja en diagonal abajo-derecha (opuesta a la luz en 0,0)
|
// La sombra se aleja en diagonal abajo-derecha (opuesta a la luz en 0,0)
|
||||||
float offset_x = shadow_offset_x_ + height * SHADOW_HEIGHT_MULTIPLIER;
|
float offset_x = shadow_offset_x_ + (height * SHADOW_HEIGHT_MULTIPLIER);
|
||||||
float offset_y = shadow_offset_y_ + height * SHADOW_HEIGHT_MULTIPLIER;
|
float offset_y = shadow_offset_y_ + (height * SHADOW_HEIGHT_MULTIPLIER);
|
||||||
|
|
||||||
shadow_texture_->render(
|
shadow_texture_->render(
|
||||||
pos_.x + offset_x,
|
pos_.x + offset_x,
|
||||||
@@ -2,15 +2,16 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FPoint
|
#include <SDL3/SDL.h> // Para SDL_FPoint
|
||||||
|
|
||||||
|
#include <cstdint> // Para std::uint8_t
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
|
|
||||||
#include "moving_sprite.hpp" // Para MovingSprite
|
#include "core/rendering/sprite/moving_sprite.hpp" // Para MovingSprite
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
// --- Estados de la tarjeta ---
|
// --- Estados de la tarjeta ---
|
||||||
enum class CardState {
|
enum class CardState : std::uint8_t {
|
||||||
IDLE, // No activada todavía
|
IDLE, // No activada todavía
|
||||||
ENTERING, // Animación de entrada (zoom + rotación + desplazamiento con rebote)
|
ENTERING, // Animación de entrada (zoom + rotación + desplazamiento con rebote)
|
||||||
LANDED, // En reposo sobre la mesa
|
LANDED, // En reposo sobre la mesa
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "moving_sprite.hpp"
|
#include "core/rendering/sprite/moving_sprite.hpp"
|
||||||
|
|
||||||
#include <cmath> // Para std::abs
|
#include <cmath> // Para std::abs
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "texture.hpp" // Para Texture
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_FRect pos, Rotate rotate, float horizontal_zoom, float vertical_zoom, SDL_FlipMode flip)
|
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_FRect pos, Rotate rotate, float horizontal_zoom, float vertical_zoom, SDL_FlipMode flip)
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
|
|
||||||
#include "sprite.hpp" // for Sprite
|
#include "core/rendering/sprite/sprite.hpp" // for Sprite
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// IWYU pragma: no_include <bits/std_abs.h>
|
// IWYU pragma: no_include <bits/std_abs.h>
|
||||||
#include "path_sprite.hpp"
|
#include "core/rendering/sprite/path_sprite.hpp"
|
||||||
|
|
||||||
#include <cmath> // Para abs
|
#include <cmath> // Para abs
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
@@ -2,22 +2,23 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FPoint
|
#include <SDL3/SDL.h> // Para SDL_FPoint
|
||||||
|
|
||||||
|
#include <cstdint> // Para std::uint8_t
|
||||||
#include <functional> // Para std::function
|
#include <functional> // Para std::function
|
||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "sprite.hpp" // Para Sprite
|
#include "core/rendering/sprite/sprite.hpp" // Para Sprite
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class PathType { // Tipos de recorrido
|
enum class PathType : std::uint8_t { // Tipos de recorrido
|
||||||
VERTICAL,
|
VERTICAL,
|
||||||
HORIZONTAL,
|
HORIZONTAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PathCentered { // Centrado del recorrido
|
enum class PathCentered : std::uint8_t { // Centrado del recorrido
|
||||||
ON_X,
|
ON_X,
|
||||||
ON_Y,
|
ON_Y,
|
||||||
NONE,
|
NONE,
|
||||||
@@ -25,12 +26,12 @@ enum class PathCentered { // Centrado del recorrido
|
|||||||
|
|
||||||
// --- Estructuras ---
|
// --- Estructuras ---
|
||||||
struct Path { // Define un recorrido para el sprite
|
struct Path { // Define un recorrido para el sprite
|
||||||
float start_pos; // Posición inicial
|
float start_pos = 0.0F; // Posición inicial
|
||||||
float end_pos; // Posición final
|
float end_pos = 0.0F; // Posición final
|
||||||
PathType type; // Tipo de movimiento (horizontal/vertical)
|
PathType type = PathType::HORIZONTAL; // Tipo de movimiento (horizontal/vertical)
|
||||||
float fixed_pos; // Posición fija en el eje contrario
|
float fixed_pos = 0.0F; // Posición fija en el eje contrario
|
||||||
float duration_s; // Duración de la animación en segundos
|
float duration_s = 0.0F; // Duración de la animación en segundos
|
||||||
float waiting_time_s; // Tiempo de espera una vez en el destino
|
float waiting_time_s = 0.0F; // Tiempo de espera una vez en el destino
|
||||||
std::function<double(double)> easing_function; // Función de easing
|
std::function<double(double)> easing_function; // Función de easing
|
||||||
float elapsed_time = 0.0F; // Tiempo transcurrido
|
float elapsed_time = 0.0F; // Tiempo transcurrido
|
||||||
float waiting_elapsed = 0.0F; // Tiempo de espera transcurrido
|
float waiting_elapsed = 0.0F; // Tiempo de espera transcurrido
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
#include "smart_sprite.hpp"
|
#include "core/rendering/sprite/smart_sprite.hpp"
|
||||||
|
|
||||||
#include "moving_sprite.hpp" // Para MovingSprite
|
|
||||||
|
|
||||||
// Actualiza la posición y comprueba si ha llegado a su destino (time-based)
|
// Actualiza la posición y comprueba si ha llegado a su destino (time-based)
|
||||||
void SmartSprite::update(float delta_time) {
|
void SmartSprite::update(float delta_time) {
|
||||||
@@ -3,16 +3,16 @@
|
|||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "animated_sprite.hpp" // Para AnimatedSprite
|
#include "core/rendering/sprite/moving_sprite.hpp" // Para MovingSprite
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
// --- Clase SmartSprite: sprite animado que se mueve hacia un destino y puede deshabilitarse automáticamente ---
|
// --- Clase SmartSprite: sprite que se mueve hacia un destino y puede deshabilitarse automáticamente ---
|
||||||
class SmartSprite : public AnimatedSprite {
|
class SmartSprite : public MovingSprite {
|
||||||
public:
|
public:
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
explicit SmartSprite(std::shared_ptr<Texture> texture)
|
explicit SmartSprite(std::shared_ptr<Texture> texture)
|
||||||
: AnimatedSprite(std::move(texture)) {}
|
: MovingSprite(std::move(texture)) {}
|
||||||
~SmartSprite() override = default;
|
~SmartSprite() override = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
#include "sprite.hpp"
|
#include "core/rendering/sprite/sprite.hpp"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "texture.hpp" // Para Texture
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Sprite::Sprite(std::shared_ptr<Texture> texture, float pos_x, float pos_y, float width, float height)
|
Sprite::Sprite(std::shared_ptr<Texture> texture, float pos_x, float pos_y, float width, float height)
|
||||||
: textures_{std::move(texture)},
|
: textures_{std::move(texture)},
|
||||||
pos_((SDL_FRect){.x = pos_x, .y = pos_y, .w = width, .h = height}),
|
pos_(SDL_FRect{.x = pos_x, .y = pos_y, .w = width, .h = height}),
|
||||||
sprite_clip_((SDL_FRect){.x = 0, .y = 0, .w = pos_.w, .h = pos_.h}) {}
|
sprite_clip_(SDL_FRect{.x = 0, .y = 0, .w = pos_.w, .h = pos_.h}) {}
|
||||||
|
|
||||||
Sprite::Sprite(std::shared_ptr<Texture> texture, SDL_FRect rect)
|
Sprite::Sprite(std::shared_ptr<Texture> texture, SDL_FRect rect)
|
||||||
: textures_{std::move(texture)},
|
: textures_{std::move(texture)},
|
||||||
pos_(rect),
|
pos_(rect),
|
||||||
sprite_clip_((SDL_FRect){.x = 0, .y = 0, .w = pos_.w, .h = pos_.h}) {}
|
sprite_clip_(SDL_FRect{.x = 0, .y = 0, .w = pos_.w, .h = pos_.h}) {}
|
||||||
|
|
||||||
Sprite::Sprite(std::shared_ptr<Texture> texture)
|
Sprite::Sprite(std::shared_ptr<Texture> texture)
|
||||||
: textures_{std::move(texture)},
|
: textures_{std::move(texture)},
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "text.hpp"
|
#include "core/rendering/text.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FRect, Uint8, SDL_GetRenderTarget, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_TextureAccess, SDL_GetTextureAlphaMod
|
#include <SDL3/SDL.h> // Para SDL_FRect, Uint8, SDL_GetRenderTarget, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_TextureAccess, SDL_GetTextureAlphaMod
|
||||||
|
|
||||||
@@ -10,12 +10,12 @@
|
|||||||
#include <utility> // Para std::cmp_less_equal
|
#include <utility> // Para std::cmp_less_equal
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "color.hpp" // Para Color
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "resource_helper.hpp" // Para loadFile
|
#include "core/rendering/sprite/sprite.hpp" // Para Sprite
|
||||||
#include "screen.hpp" // Para Screen
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
#include "sprite.hpp" // Para Sprite
|
#include "core/resources/resource_helper.hpp" // Para loadFile
|
||||||
#include "texture.hpp" // Para Texture
|
#include "utils/color.hpp" // Para Color
|
||||||
#include "utils.hpp" // Para getFileName
|
#include "utils/utils.hpp" // Para getFileName
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Text::Text(const std::shared_ptr<Texture>& texture, const std::string& text_file) {
|
Text::Text(const std::shared_ptr<Texture>& texture, const std::string& text_file) {
|
||||||
@@ -32,7 +32,7 @@ Text::Text(const std::shared_ptr<Texture>& texture, const std::string& text_file
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crea los objetos
|
// Crea los objetos
|
||||||
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
sprite_ = std::make_unique<Sprite>(texture, SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
fixed_width_ = false;
|
fixed_width_ = false;
|
||||||
@@ -50,7 +50,7 @@ Text::Text(const std::shared_ptr<Texture>& texture, const std::shared_ptr<Text::
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crea los objetos
|
// Crea los objetos
|
||||||
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
sprite_ = std::make_unique<Sprite>(texture, SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
fixed_width_ = false;
|
fixed_width_ = false;
|
||||||
@@ -71,8 +71,8 @@ Text::Text(const std::shared_ptr<Texture>& texture, const std::shared_ptr<Textur
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crea los objetos
|
// Crea los objetos
|
||||||
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
sprite_ = std::make_unique<Sprite>(texture, SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
||||||
white_sprite_ = std::make_unique<Sprite>(white_texture, (SDL_FRect){.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
white_sprite_ = std::make_unique<Sprite>(white_texture, SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
fixed_width_ = false;
|
fixed_width_ = false;
|
||||||
@@ -90,8 +90,8 @@ Text::Text(const std::shared_ptr<Texture>& texture, const std::shared_ptr<Textur
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crea los objetos
|
// Crea los objetos
|
||||||
sprite_ = std::make_unique<Sprite>(texture, (SDL_FRect){.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
sprite_ = std::make_unique<Sprite>(texture, SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
||||||
white_sprite_ = std::make_unique<Sprite>(white_texture, (SDL_FRect){.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
white_sprite_ = std::make_unique<Sprite>(white_texture, SDL_FRect{.x = 0, .y = 0, .w = static_cast<float>(box_width_), .h = static_cast<float>(box_height_)});
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
fixed_width_ = false;
|
fixed_width_ = false;
|
||||||
@@ -137,7 +137,7 @@ void Text::write2X(int x, int y, const std::string& text, int kerning, int lengt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Escribe el texto en una textura
|
// Escribe el texto en una textura
|
||||||
auto Text::writeToTexture(const std::string& text, int zoom, int kerning, int length) -> std::shared_ptr<Texture> {
|
auto Text::writeToTexture(const std::string& text, int zoom, int kerning, int /*length*/) -> std::shared_ptr<Texture> {
|
||||||
auto* renderer = Screen::get()->getRenderer();
|
auto* renderer = Screen::get()->getRenderer();
|
||||||
auto texture = std::make_shared<Texture>(renderer);
|
auto texture = std::make_shared<Texture>(renderer);
|
||||||
auto width = Text::length(text, kerning) * zoom;
|
auto width = Text::length(text, kerning) * zoom;
|
||||||
@@ -342,7 +342,7 @@ void Text::writeDX(Uint8 flags, int x, int y, const std::string& text, int kerni
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Escribe texto a partir de un TextStyle
|
// Escribe texto a partir de un TextStyle
|
||||||
void Text::writeStyle(int x, int y, const std::string& text, const Style& style, int length) {
|
void Text::writeStyle(int x, int y, const std::string& text, const Style& style, int /*length*/) {
|
||||||
writeDX(style.flags, x, y, text, style.kerning, style.text_color, style.shadow_distance, style.shadow_color);
|
writeDX(style.flags, x, y, text, style.kerning, style.text_color, style.shadow_distance, style.shadow_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,9 +403,8 @@ auto Text::loadFile(const std::string& file_path) -> std::shared_ptr<Text::File>
|
|||||||
file.open(file_path);
|
file.open(file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream& input_stream = using_resource_data ? stream : static_cast<std::istream&>(file);
|
|
||||||
|
|
||||||
if ((using_resource_data && stream.good()) || (!using_resource_data && file.is_open() && file.good())) {
|
if ((using_resource_data && stream.good()) || (!using_resource_data && file.is_open() && file.good())) {
|
||||||
|
std::istream& input_stream = using_resource_data ? stream : static_cast<std::istream&>(file);
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|
||||||
// Lee los dos primeros valores del fichero
|
// Lee los dos primeros valores del fichero
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
#include <memory> // Para shared_ptr, unique_ptr
|
#include <memory> // Para shared_ptr, unique_ptr
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
|
|
||||||
#include "color.hpp" // Para Color
|
#include "core/rendering/sprite/sprite.hpp" // Para Sprite
|
||||||
#include "sprite.hpp" // Para Sprite
|
#include "utils/color.hpp" // Para Color
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ class Text {
|
|||||||
int kerning;
|
int kerning;
|
||||||
|
|
||||||
// Constructor con argumentos por defecto
|
// Constructor con argumentos por defecto
|
||||||
Style(Uint8 flags = 0,
|
explicit Style(Uint8 flags = 0,
|
||||||
Color text = Color(),
|
Color text = Color(),
|
||||||
Color shadow = Color(),
|
Color shadow = Color(),
|
||||||
Uint8 distance = 1,
|
Uint8 distance = 1,
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "texture.hpp"
|
#include "core/rendering/texture.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogError, SDL_LogCategory, Uint8, SDL_...
|
#include <SDL3/SDL.h> // Para SDL_LogError, SDL_LogCategory, Uint8, SDL_...
|
||||||
|
|
||||||
#include <cstdint> // Para uint32_t
|
#include <cstdint> // Para uint32_t
|
||||||
#include <cstring> // Para memcpy
|
|
||||||
#include <fstream> // Para basic_ifstream, basic_istream, basic_ios
|
#include <fstream> // Para basic_ifstream, basic_istream, basic_ios
|
||||||
#include <iostream> // Para std::cout
|
#include <iostream> // Para std::cout
|
||||||
#include <sstream> // Para basic_istringstream
|
#include <sstream> // Para basic_istringstream
|
||||||
@@ -13,11 +12,11 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "color.hpp" // Para getFileName, Color
|
#include "core/rendering/gif.hpp" // Para Gif
|
||||||
#include "external/gif.hpp" // Para Gif
|
#include "core/resources/resource_helper.hpp" // Para ResourceHelper
|
||||||
#include "resource_helper.hpp" // Para ResourceHelper
|
#include "external/stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_alpha
|
||||||
#include "stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_alpha
|
#include "utils/color.hpp" // Para getFileName, Color
|
||||||
#include "utils.hpp"
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Texture::Texture(SDL_Renderer* renderer, std::string path)
|
Texture::Texture(SDL_Renderer* renderer, std::string path)
|
||||||
@@ -251,22 +250,15 @@ auto Texture::loadSurface(const std::string& file_path) -> std::shared_ptr<Surfa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crear un objeto Gif y llamar a la función loadGif
|
|
||||||
GIF::Gif gif;
|
|
||||||
Uint16 w = 0;
|
Uint16 w = 0;
|
||||||
Uint16 h = 0;
|
Uint16 h = 0;
|
||||||
std::vector<Uint8> raw_pixels = gif.loadGif(buffer.data(), w, h);
|
std::vector<Uint8> raw_pixels = GIF::loadGif(buffer.data(), w, h);
|
||||||
if (raw_pixels.empty()) {
|
if (raw_pixels.empty()) {
|
||||||
std::cout << "Error: No se pudo cargar el GIF " << file_path << '\n';
|
std::cout << "Error: No se pudo cargar el GIF " << file_path << '\n';
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si el constructor de Surface espera un std::shared_ptr<Uint8[]>:
|
auto surface = std::make_shared<Surface>(w, h, std::move(raw_pixels));
|
||||||
size_t pixel_count = raw_pixels.size();
|
|
||||||
auto pixels = std::shared_ptr<Uint8[]>(new Uint8[pixel_count], std::default_delete<Uint8[]>()); // NOLINT(modernize-avoid-c-arrays)
|
|
||||||
std::memcpy(pixels.get(), raw_pixels.data(), pixel_count);
|
|
||||||
|
|
||||||
auto surface = std::make_shared<Surface>(w, h, pixels);
|
|
||||||
|
|
||||||
// Actualizar las dimensiones
|
// Actualizar las dimensiones
|
||||||
width_ = w;
|
width_ = w;
|
||||||
@@ -329,8 +321,7 @@ auto Texture::loadPaletteFromFile(const std::string& file_path) -> Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Usar la nueva función loadPalette, que devuelve un vector<uint32_t>
|
// Usar la nueva función loadPalette, que devuelve un vector<uint32_t>
|
||||||
GIF::Gif gif;
|
std::vector<uint32_t> pal = GIF::loadPalette(buffer.data());
|
||||||
std::vector<uint32_t> pal = gif.loadPalette(buffer.data());
|
|
||||||
if (pal.empty()) {
|
if (pal.empty()) {
|
||||||
std::cout << "Advertencia: No se encontró paleta en el archivo " << file_path << '\n';
|
std::cout << "Advertencia: No se encontró paleta en el archivo " << file_path << '\n';
|
||||||
return palette; // Devuelve un vector vacío si no hay paleta
|
return palette; // Devuelve un vector vacío si no hay paleta
|
||||||
@@ -16,11 +16,11 @@ using Palette = std::array<Uint32, 256>;
|
|||||||
|
|
||||||
// Definición de Surface para imágenes con paleta
|
// Definición de Surface para imágenes con paleta
|
||||||
struct Surface {
|
struct Surface {
|
||||||
std::shared_ptr<Uint8[]> data; // NOLINT(modernize-avoid-c-arrays)
|
std::vector<Uint8> data;
|
||||||
Uint16 w, h;
|
Uint16 w, h;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels) // NOLINT(modernize-avoid-c-arrays)
|
Surface(Uint16 width, Uint16 height, std::vector<Uint8> pixels)
|
||||||
: data(std::move(pixels)),
|
: data(std::move(pixels)),
|
||||||
w(width),
|
w(width),
|
||||||
h(height) {}
|
h(height) {}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "tiled_bg.hpp"
|
#include "core/rendering/tiled_bg.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_FRect, SDL_GetRenderTarget, SDL_RenderTexture, SDL_PixelFormat, SDL_TextureAccess
|
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_FRect, SDL_GetRenderTarget, SDL_RenderTexture, SDL_PixelFormat, SDL_TextureAccess
|
||||||
|
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
#include <numbers> // Para pi
|
#include <numbers> // Para pi
|
||||||
#include <string> // Para basic_string
|
#include <string> // Para basic_string
|
||||||
|
|
||||||
#include "resource.hpp" // Para Resource
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "screen.hpp" // Para Screen
|
#include "core/rendering/sprite/sprite.hpp" // Para Sprite
|
||||||
#include "sprite.hpp" // Para Sprite
|
#include "core/resources/resource.hpp" // Para Resource
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
TiledBG::TiledBG(SDL_FRect pos, TiledBGMode mode)
|
TiledBG::TiledBG(SDL_FRect pos, TiledBGMode mode)
|
||||||
@@ -50,7 +50,7 @@ TiledBG::~TiledBG() {
|
|||||||
// Rellena la textura con el contenido
|
// Rellena la textura con el contenido
|
||||||
void TiledBG::fillTexture() {
|
void TiledBG::fillTexture() {
|
||||||
// Crea los objetos para pintar en la textura de fondo
|
// Crea los objetos para pintar en la textura de fondo
|
||||||
auto tile = std::make_unique<Sprite>(Resource::get()->getTexture("title_bg_tile.png"), (SDL_FRect){.x = 0, .y = 0, .w = TILE_WIDTH, .h = TILE_HEIGHT});
|
auto tile = std::make_unique<Sprite>(Resource::get()->getTexture("title_bg_tile.png"), SDL_FRect{.x = 0, .y = 0, .w = TILE_WIDTH, .h = TILE_HEIGHT});
|
||||||
|
|
||||||
// Prepara para dibujar sobre la textura
|
// Prepara para dibujar sobre la textura
|
||||||
auto* temp = SDL_GetRenderTarget(renderer_);
|
auto* temp = SDL_GetRenderTarget(renderer_);
|
||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetTextureColorMod, SDL_Renderer, SDL_Texture
|
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetTextureColorMod, SDL_Renderer, SDL_Texture
|
||||||
|
|
||||||
#include "color.hpp" // Para Color
|
#include <cstdint> // Para std::uint8_t
|
||||||
|
|
||||||
|
#include "utils/color.hpp" // Para Color
|
||||||
|
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class TiledBGMode : int { // Modos de funcionamiento para el tileado de fondo
|
enum class TiledBGMode : std::uint8_t { // Modos de funcionamiento para el tileado de fondo
|
||||||
CIRCLE = 0,
|
CIRCLE = 0,
|
||||||
DIAGONAL = 1,
|
DIAGONAL = 1,
|
||||||
RANDOM = 2,
|
RANDOM = 2,
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "writer.hpp"
|
#include "core/rendering/writer.hpp"
|
||||||
|
|
||||||
#include "text.hpp" // Para Text
|
// Text es completat ací per `text_->write/length` via shared_ptr; include-cleaner no detecta l'ús indirecte.
|
||||||
|
#include "core/rendering/text.hpp" // IWYU pragma: keep
|
||||||
|
|
||||||
// Actualiza el objeto (delta_time en ms)
|
// Actualiza el objeto (delta_time en ms)
|
||||||
void Writer::update(float delta_time) {
|
void Writer::update(float delta_time) {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "asset.hpp"
|
#include "core/resources/asset.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError
|
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError
|
||||||
|
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
#include <sstream> // Para basic_istringstream
|
#include <sstream> // Para basic_istringstream
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
|
|
||||||
#include "resource_helper.hpp" // Para loadFile
|
#include "core/resources/resource_helper.hpp" // Para loadFile
|
||||||
#include "utils.hpp" // Para getFileName
|
#include "utils/utils.hpp" // Para getFileName
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
Asset* Asset::instance = nullptr;
|
Asset* Asset::instance = nullptr;
|
||||||
@@ -47,27 +47,39 @@ void Asset::add(const std::string& file_path, Type type, bool required, bool abs
|
|||||||
addToMap(file_path, type, required, absolute);
|
addToMap(file_path, type, required, absolute);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga recursos desde un archivo de configuración con soporte para variables
|
// Carga recursos desde un archivo de configuración en el filesystem
|
||||||
void Asset::loadFromFile(const std::string& config_file_path, const std::string& prefix, const std::string& system_folder) {
|
void Asset::loadFromFile(const std::string& config_file_path, const std::string& prefix, const std::string& system_folder) {
|
||||||
std::ifstream file(config_file_path);
|
std::ifstream file(config_file_path);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
std::cout << "Error: Cannot open config file: " << config_file_path << '\n';
|
std::cout << "Error: Cannot open config file: " << config_file_path << '\n';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
parseConfigStream(file, prefix, system_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carga recursos desde un buffer en memoria (p.ex. obtenido del pack)
|
||||||
|
void Asset::loadFromBuffer(const std::vector<uint8_t>& buffer, const std::string& prefix, const std::string& system_folder) {
|
||||||
|
if (buffer.empty()) {
|
||||||
|
std::cout << "Error: Asset index buffer is empty" << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string content(buffer.begin(), buffer.end());
|
||||||
|
std::istringstream stream(content);
|
||||||
|
parseConfigStream(stream, prefix, system_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parsea el contenido del índice (formato común a loadFromFile y loadFromBuffer)
|
||||||
|
void Asset::parseConfigStream(std::istream& stream, const std::string& prefix, const std::string& system_folder) {
|
||||||
std::string line;
|
std::string line;
|
||||||
int line_number = 0;
|
int line_number = 0;
|
||||||
|
|
||||||
while (std::getline(file, line)) {
|
while (std::getline(stream, line)) {
|
||||||
++line_number;
|
++line_number;
|
||||||
|
|
||||||
// Limpiar espacios en blanco al principio y final
|
// Limpiar espacios en blanco al principio y final
|
||||||
line.erase(0, line.find_first_not_of(" \t\r"));
|
line.erase(0, line.find_first_not_of(" \t\r"));
|
||||||
line.erase(line.find_last_not_of(" \t\r") + 1);
|
line.erase(line.find_last_not_of(" \t\r") + 1);
|
||||||
|
|
||||||
// DEBUG: mostrar línea leída (opcional, puedes comentar esta línea)
|
|
||||||
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Line %d: '%s'", line_number, line.c_str());
|
|
||||||
|
|
||||||
// Ignorar líneas vacías y comentarios
|
// Ignorar líneas vacías y comentarios
|
||||||
if (line.empty() || line[0] == '#' || line[0] == ';') {
|
if (line.empty() || line[0] == '#' || line[0] == ';') {
|
||||||
continue;
|
continue;
|
||||||
@@ -114,8 +126,6 @@ void Asset::loadFromFile(const std::string& config_file_path, const std::string&
|
|||||||
std::cout << "Error parsing line " << line_number << " in config file: " << e.what() << '\n';
|
std::cout << "Error parsing line " << line_number << " in config file: " << e.what() << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Devuelve la ruta completa a un fichero (búsqueda O(1))
|
// Devuelve la ruta completa a un fichero (búsqueda O(1))
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint> // Para uint8_t
|
#include <cstdint> // Para uint8_t
|
||||||
|
#include <iosfwd> // Para istream (forward decl)
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <unordered_map> // Para unordered_map
|
#include <unordered_map> // Para unordered_map
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
class Asset {
|
class Asset {
|
||||||
public:
|
public:
|
||||||
// --- Enums ---
|
// --- Enums ---
|
||||||
enum class Type : int {
|
enum class Type : std::uint8_t {
|
||||||
BITMAP, // Imágenes
|
BITMAP, // Imágenes
|
||||||
MUSIC, // Música
|
MUSIC, // Música
|
||||||
SOUND, // Sonidos
|
SOUND, // Sonidos
|
||||||
@@ -32,7 +33,8 @@ class Asset {
|
|||||||
|
|
||||||
// --- Métodos para la gestión de recursos ---
|
// --- Métodos para la gestión de recursos ---
|
||||||
void add(const std::string& file_path, Type type, bool required = true, bool absolute = false);
|
void add(const std::string& file_path, Type type, bool required = true, bool absolute = false);
|
||||||
void loadFromFile(const std::string& config_file_path, const std::string& prefix = "", const std::string& system_folder = ""); // Con soporte para variables
|
void loadFromFile(const std::string& config_file_path, const std::string& prefix = "", const std::string& system_folder = ""); // Carga el índice desde el filesystem
|
||||||
|
void loadFromBuffer(const std::vector<uint8_t>& buffer, const std::string& prefix = "", const std::string& system_folder = ""); // Carga el índice desde memoria (p.ex. desde el pack)
|
||||||
[[nodiscard]] auto getPath(const std::string& filename) const -> std::string;
|
[[nodiscard]] auto getPath(const std::string& filename) const -> std::string;
|
||||||
[[nodiscard]] auto loadData(const std::string& filename) const -> std::vector<uint8_t>; // Carga datos del archivo
|
[[nodiscard]] auto loadData(const std::string& filename) const -> std::vector<uint8_t>; // Carga datos del archivo
|
||||||
[[nodiscard]] auto check() const -> bool;
|
[[nodiscard]] auto check() const -> bool;
|
||||||
@@ -63,6 +65,7 @@ class Asset {
|
|||||||
void addToMap(const std::string& file_path, Type type, bool required, bool absolute); // Añade archivo al mapa
|
void addToMap(const std::string& file_path, Type type, bool required, bool absolute); // Añade archivo al mapa
|
||||||
[[nodiscard]] static auto replaceVariables(const std::string& path, const std::string& prefix, const std::string& system_folder) -> std::string; // Reemplaza variables en la ruta
|
[[nodiscard]] static auto replaceVariables(const std::string& path, const std::string& prefix, const std::string& system_folder) -> std::string; // Reemplaza variables en la ruta
|
||||||
static auto parseOptions(const std::string& options, bool& required, bool& absolute) -> void; // Parsea opciones
|
static auto parseOptions(const std::string& options, bool& required, bool& absolute) -> void; // Parsea opciones
|
||||||
|
void parseConfigStream(std::istream& stream, const std::string& prefix, const std::string& system_folder); // Lógica común de parseo del índice
|
||||||
|
|
||||||
// --- Constructores y destructor privados (singleton) ---
|
// --- Constructores y destructor privados (singleton) ---
|
||||||
explicit Asset(std::string executable_path) // Constructor privado
|
explicit Asset(std::string executable_path) // Constructor privado
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
#include "asset_integrated.hpp"
|
#include "core/resources/asset_integrated.hpp"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "core/resources/resource_loader.hpp"
|
||||||
|
|
||||||
bool AssetIntegrated::resource_pack_enabled = false;
|
bool AssetIntegrated::resource_pack_enabled = false;
|
||||||
|
|
||||||
void AssetIntegrated::initWithResourcePack(const std::string& executable_path,
|
void AssetIntegrated::initWithResourcePack(const std::string& executable_path,
|
||||||
@@ -86,20 +88,11 @@ auto AssetIntegrated::getSystemPath(const std::string& filename) -> std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto AssetIntegrated::shouldUseResourcePack(const std::string& filepath) -> bool {
|
auto AssetIntegrated::shouldUseResourcePack(const std::string& filepath) -> bool {
|
||||||
// Los archivos que NO van al pack:
|
// Els fitxers que NO van al pack:
|
||||||
// - Archivos de config/ (ahora están fuera de data/)
|
// - Fitxers amb absolute=true a assets.txt
|
||||||
// - Archivos con absolute=true en assets.txt
|
// - Fitxers de sistema (${SYSTEM_FOLDER})
|
||||||
// - Archivos de sistema (${SYSTEM_FOLDER})
|
// - Fitxers al costat del binari (com gamecontrollerdb.txt)
|
||||||
|
|
||||||
if (filepath.find("/config/") != std::string::npos ||
|
return filepath.find("/data/") != std::string::npos ||
|
||||||
filepath.starts_with("config/")) {
|
filepath.starts_with("data/");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filepath.find("/data/") != std::string::npos ||
|
|
||||||
filepath.starts_with("data/")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include "core/resources/asset.hpp"
|
||||||
|
|
||||||
#include "asset.hpp"
|
|
||||||
#include "resource_loader.hpp"
|
|
||||||
|
|
||||||
// Extensión de Asset que integra ResourceLoader
|
// Extensión de Asset que integra ResourceLoader
|
||||||
class AssetIntegrated : public Asset {
|
class AssetIntegrated : public Asset {
|
||||||
@@ -1,30 +1,27 @@
|
|||||||
#include "resource.hpp"
|
#include "core/resources/resource.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event
|
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event
|
||||||
|
|
||||||
|
#include <algorithm> // Para ranges::transform, ranges::find_if
|
||||||
#include <array> // Para array
|
#include <array> // Para array
|
||||||
#include <cstdlib> // Para exit
|
#include <cstdlib> // Para exit
|
||||||
#include <exception> // Para exception
|
|
||||||
#include <filesystem> // Para exists, path, remove
|
|
||||||
#include <fstream> // Para basic_ofstream, basic_ios, basic_ostream::write, ios, ofstream
|
|
||||||
#include <iostream> // Para std::cout
|
#include <iostream> // Para std::cout
|
||||||
#include <ranges> // Para __find_if_fn, find_if, __find_fn, find
|
#include <iterator> // Para back_inserter
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
#include "asset.hpp" // Para Asset
|
#include "core/audio/jail_audio.hpp" // Para Ja::loadMusic, Ja::loadSound, Ja::deleteMusic, Ja::deleteSound
|
||||||
#include "color.hpp" // Para Color, NO_COLOR_MOD
|
#include "core/locale/lang.hpp" // Para getText
|
||||||
#include "external/jail_audio.hpp" // Para JA_LoadMusic, JA_LoadSound, JA_DeleteMusic, JA_DeleteSound
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "lang.hpp" // Para getText
|
#include "core/rendering/text.hpp" // Para Text
|
||||||
#include "param.hpp" // Para Param, param, ParamPlayer, ParamResource, ParamGame
|
#include "core/resources/asset.hpp" // Para Asset
|
||||||
#include "resource_helper.hpp" // Para loadFile
|
#include "core/resources/resource_helper.hpp" // Para loadFile
|
||||||
#include "screen.hpp" // Para Screen
|
#include "game/options.hpp" // Para Options::loading
|
||||||
#include "text.hpp" // Para Text
|
#include "utils/color.hpp" // Para Color, NO_COLOR_MOD
|
||||||
#include "utils.hpp" // Para getFileName
|
#include "utils/defines.hpp" // Para Texts::VERSION
|
||||||
#include "version.h" // Para APP_NAME, GIT_HASH
|
#include "utils/param.hpp" // Para Param, param, ParamPlayer, ParamResource, ParamGame
|
||||||
|
#include "utils/utils.hpp" // Para getFileName
|
||||||
struct JA_Music_t; // lines 11-11
|
#include "version.h" // Para APP_NAME, GIT_HASH
|
||||||
struct JA_Sound_t; // lines 12-12
|
|
||||||
|
|
||||||
// Helper para cargar archivos de audio desde pack o filesystem en memoria
|
// Helper para cargar archivos de audio desde pack o filesystem en memoria
|
||||||
namespace {
|
namespace {
|
||||||
@@ -65,7 +62,8 @@ Resource::Resource(LoadingMode mode)
|
|||||||
Screen::get()->show();
|
Screen::get()->show();
|
||||||
if (loading_mode_ == LoadingMode::PRELOAD) {
|
if (loading_mode_ == LoadingMode::PRELOAD) {
|
||||||
loading_text_ = Screen::get()->getText();
|
loading_text_ = Screen::get()->getText();
|
||||||
load();
|
// Ya NO llamamos load() aquí: Director bombea beginLoad() + loadStep()
|
||||||
|
// desde iterate() para mantener vivo el bucle SDL3 durante la carga.
|
||||||
} else {
|
} else {
|
||||||
// En modo lazy, cargamos lo mínimo indispensable
|
// En modo lazy, cargamos lo mínimo indispensable
|
||||||
initResourceLists();
|
initResourceLists();
|
||||||
@@ -135,40 +133,37 @@ void Resource::loadEssentialTextures() {
|
|||||||
|
|
||||||
// Inicializa las listas de recursos sin cargar el contenido (modo lazy)
|
// Inicializa las listas de recursos sin cargar el contenido (modo lazy)
|
||||||
void Resource::initResourceLists() {
|
void Resource::initResourceLists() {
|
||||||
|
const auto FILE_TO_NAME = [](const auto& file) { return getFileName(file); };
|
||||||
|
|
||||||
// Inicializa lista de sonidos
|
// Inicializa lista de sonidos
|
||||||
auto sound_list = Asset::get()->getListByType(Asset::Type::SOUND);
|
const auto SOUND_LIST = Asset::get()->getListByType(Asset::Type::SOUND);
|
||||||
sounds_.clear();
|
sounds_.clear();
|
||||||
for (const auto& file : sound_list) {
|
sounds_.reserve(SOUND_LIST.size());
|
||||||
sounds_.emplace_back(getFileName(file));
|
std::ranges::transform(SOUND_LIST, std::back_inserter(sounds_), [&](const auto& file) { return ResourceSound(FILE_TO_NAME(file)); });
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa lista de músicas
|
// Inicializa lista de músicas
|
||||||
auto music_list = Asset::get()->getListByType(Asset::Type::MUSIC);
|
const auto MUSIC_LIST = Asset::get()->getListByType(Asset::Type::MUSIC);
|
||||||
musics_.clear();
|
musics_.clear();
|
||||||
for (const auto& file : music_list) {
|
musics_.reserve(MUSIC_LIST.size());
|
||||||
musics_.emplace_back(getFileName(file));
|
std::ranges::transform(MUSIC_LIST, std::back_inserter(musics_), [&](const auto& file) { return ResourceMusic(FILE_TO_NAME(file)); });
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa lista de texturas
|
// Inicializa lista de texturas
|
||||||
auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP);
|
const auto TEXTURE_LIST = Asset::get()->getListByType(Asset::Type::BITMAP);
|
||||||
textures_.clear();
|
textures_.clear();
|
||||||
for (const auto& file : texture_list) {
|
textures_.reserve(TEXTURE_LIST.size());
|
||||||
textures_.emplace_back(getFileName(file));
|
std::ranges::transform(TEXTURE_LIST, std::back_inserter(textures_), [&](const auto& file) { return ResourceTexture(FILE_TO_NAME(file)); });
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa lista de ficheros de texto
|
// Inicializa lista de ficheros de texto
|
||||||
auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT);
|
const auto TEXT_FILE_LIST = Asset::get()->getListByType(Asset::Type::FONT);
|
||||||
text_files_.clear();
|
text_files_.clear();
|
||||||
for (const auto& file : text_file_list) {
|
text_files_.reserve(TEXT_FILE_LIST.size());
|
||||||
text_files_.emplace_back(getFileName(file));
|
std::ranges::transform(TEXT_FILE_LIST, std::back_inserter(text_files_), [&](const auto& file) { return ResourceTextFile(FILE_TO_NAME(file)); });
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializa lista de animaciones
|
// Inicializa lista de animaciones
|
||||||
auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION);
|
const auto ANIMATION_LIST = Asset::get()->getListByType(Asset::Type::ANIMATION);
|
||||||
animations_.clear();
|
animations_.clear();
|
||||||
for (const auto& file : animation_list) {
|
animations_.reserve(ANIMATION_LIST.size());
|
||||||
animations_.emplace_back(getFileName(file));
|
std::ranges::transform(ANIMATION_LIST, std::back_inserter(animations_), [&](const auto& file) { return ResourceAnimation(FILE_TO_NAME(file)); });
|
||||||
}
|
|
||||||
|
|
||||||
// Los demos se cargan directamente sin mostrar progreso (son pocos y pequeños)
|
// Los demos se cargan directamente sin mostrar progreso (son pocos y pequeños)
|
||||||
loadDemoDataQuiet();
|
loadDemoDataQuiet();
|
||||||
@@ -189,13 +184,12 @@ void Resource::initResourceLists() {
|
|||||||
"smb2_grad"};
|
"smb2_grad"};
|
||||||
|
|
||||||
texts_.clear();
|
texts_.clear();
|
||||||
for (const auto& text_name : TEXT_OBJECTS) {
|
texts_.reserve(TEXT_OBJECTS.size());
|
||||||
texts_.emplace_back(text_name); // Constructor con nullptr por defecto
|
std::ranges::transform(TEXT_OBJECTS, std::back_inserter(texts_), [](const auto& text_name) { return ResourceText(text_name); });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el sonido a partir de un nombre (con carga perezosa)
|
// Obtiene el sonido a partir de un nombre (con carga perezosa)
|
||||||
auto Resource::getSound(const std::string& name) -> JA_Sound_t* {
|
auto Resource::getSound(const std::string& name) -> Ja::Sound* {
|
||||||
auto it = std::ranges::find_if(sounds_, [&name](const auto& s) -> auto { return s.name == name; });
|
auto it = std::ranges::find_if(sounds_, [&name](const auto& s) -> auto { return s.name == name; });
|
||||||
|
|
||||||
if (it != sounds_.end()) {
|
if (it != sounds_.end()) {
|
||||||
@@ -211,7 +205,7 @@ auto Resource::getSound(const std::string& name) -> JA_Sound_t* {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene la música a partir de un nombre (con carga perezosa)
|
// Obtiene la música a partir de un nombre (con carga perezosa)
|
||||||
auto Resource::getMusic(const std::string& name) -> JA_Music_t* {
|
auto Resource::getMusic(const std::string& name) -> Ja::Music* {
|
||||||
auto it = std::ranges::find_if(musics_, [&name](const auto& m) -> auto { return m.name == name; });
|
auto it = std::ranges::find_if(musics_, [&name](const auto& m) -> auto { return m.name == name; });
|
||||||
|
|
||||||
if (it != musics_.end()) {
|
if (it != musics_.end()) {
|
||||||
@@ -302,54 +296,48 @@ auto Resource::getDemoData(int index) -> DemoData& {
|
|||||||
|
|
||||||
// --- Métodos de carga perezosa ---
|
// --- Métodos de carga perezosa ---
|
||||||
|
|
||||||
auto Resource::loadSoundLazy(const std::string& name) -> JA_Sound_t* {
|
auto Resource::loadSoundLazy(const std::string& name) -> Ja::Sound* {
|
||||||
auto sound_list = Asset::get()->getListByType(Asset::Type::SOUND);
|
auto sound_list = Asset::get()->getListByType(Asset::Type::SOUND);
|
||||||
for (const auto& file : sound_list) {
|
for (const auto& file : sound_list) {
|
||||||
if (getFileName(file) == name) {
|
if (getFileName(file) == name) {
|
||||||
auto audio_data = loadAudioData(file);
|
auto audio_data = loadAudioData(file);
|
||||||
if (!audio_data.data.empty()) {
|
if (!audio_data.data.empty()) {
|
||||||
return JA_LoadSound(audio_data.data.data(), audio_data.data.size());
|
return Ja::loadSound(audio_data.data.data(), audio_data.data.size());
|
||||||
}
|
}
|
||||||
// Fallback a cargar desde disco si no está en pack
|
// Fallback a cargar desde disco si no está en pack
|
||||||
return JA_LoadSound(file.c_str());
|
return Ja::loadSound(file.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Resource::loadMusicLazy(const std::string& name) -> JA_Music_t* {
|
auto Resource::loadMusicLazy(const std::string& name) -> Ja::Music* {
|
||||||
auto music_list = Asset::get()->getListByType(Asset::Type::MUSIC);
|
auto music_list = Asset::get()->getListByType(Asset::Type::MUSIC);
|
||||||
for (const auto& file : music_list) {
|
for (const auto& file : music_list) {
|
||||||
if (getFileName(file) == name) {
|
if (getFileName(file) == name) {
|
||||||
auto audio_data = loadAudioData(file);
|
auto audio_data = loadAudioData(file);
|
||||||
if (!audio_data.data.empty()) {
|
if (!audio_data.data.empty()) {
|
||||||
return JA_LoadMusic(audio_data.data.data(), audio_data.data.size());
|
return Ja::loadMusic(audio_data.data.data(), audio_data.data.size());
|
||||||
}
|
}
|
||||||
// Fallback a cargar desde disco si no está en pack
|
// Fallback a cargar desde disco si no está en pack
|
||||||
return JA_LoadMusic(file.c_str());
|
return Ja::loadMusic(file.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Resource::loadTextureLazy(const std::string& name) -> std::shared_ptr<Texture> {
|
auto Resource::loadTextureLazy(const std::string& name) -> std::shared_ptr<Texture> {
|
||||||
auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP);
|
const auto TEXTURE_LIST = Asset::get()->getListByType(Asset::Type::BITMAP);
|
||||||
for (const auto& file : texture_list) {
|
const auto IT = std::ranges::find_if(TEXTURE_LIST,
|
||||||
if (getFileName(file) == name) {
|
[&name](const auto& file) { return getFileName(file) == name; });
|
||||||
return std::make_shared<Texture>(Screen::get()->getRenderer(), file);
|
return IT != TEXTURE_LIST.end() ? std::make_shared<Texture>(Screen::get()->getRenderer(), *IT) : nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Resource::loadTextFileLazy(const std::string& name) -> std::shared_ptr<Text::File> {
|
auto Resource::loadTextFileLazy(const std::string& name) -> std::shared_ptr<Text::File> {
|
||||||
auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT);
|
const auto TEXT_FILE_LIST = Asset::get()->getListByType(Asset::Type::FONT);
|
||||||
for (const auto& file : text_file_list) {
|
const auto IT = std::ranges::find_if(TEXT_FILE_LIST,
|
||||||
if (getFileName(file) == name) {
|
[&name](const auto& file) { return getFileName(file) == name; });
|
||||||
return Text::loadFile(file);
|
return IT != TEXT_FILE_LIST.end() ? Text::loadFile(*IT) : nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Resource::loadTextLazy(const std::string& name) -> std::shared_ptr<Text> {
|
auto Resource::loadTextLazy(const std::string& name) -> std::shared_ptr<Text> {
|
||||||
@@ -374,27 +362,22 @@ auto Resource::loadTextLazy(const std::string& name) -> std::shared_ptr<Text> {
|
|||||||
{.key = "smb2", .texture_file = "smb2.png", .text_file = "smb2.txt"},
|
{.key = "smb2", .texture_file = "smb2.png", .text_file = "smb2.txt"},
|
||||||
{.key = "smb2_grad", .texture_file = "smb2_grad.png", .text_file = "smb2.txt"}};
|
{.key = "smb2_grad", .texture_file = "smb2_grad.png", .text_file = "smb2.txt"}};
|
||||||
|
|
||||||
for (const auto& mapping : TEXT_MAPPINGS) {
|
const auto IT = std::ranges::find_if(TEXT_MAPPINGS,
|
||||||
if (mapping.key == name) {
|
[&name](const auto& mapping) { return mapping.key == name; });
|
||||||
// Cargar las dependencias automáticamente
|
if (IT == TEXT_MAPPINGS.end()) {
|
||||||
auto texture = getTexture(mapping.texture_file); // Esto cargará la textura si no está cargada
|
return nullptr;
|
||||||
auto text_file = getTextFile(mapping.text_file); // Esto cargará el archivo de texto si no está cargado
|
|
||||||
|
|
||||||
if (texture && text_file) {
|
|
||||||
return std::make_shared<Text>(texture, text_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
auto texture = getTexture(IT->texture_file); // Esto cargará la textura si no está cargada
|
||||||
return nullptr;
|
auto text_file = getTextFile(IT->text_file); // Esto cargará el archivo de texto si no está cargado
|
||||||
|
return (texture && text_file) ? std::make_shared<Text>(texture, text_file) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Resource::loadAnimationLazy(const std::string& name) -> AnimationsFileBuffer {
|
auto Resource::loadAnimationLazy(const std::string& name) -> AnimationsFileBuffer {
|
||||||
auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION);
|
const auto ANIMATION_LIST = Asset::get()->getListByType(Asset::Type::ANIMATION);
|
||||||
for (const auto& file : animation_list) {
|
const auto IT = std::ranges::find_if(ANIMATION_LIST,
|
||||||
if (getFileName(file) == name) {
|
[&name](const auto& file) { return getFileName(file) == name; });
|
||||||
return loadAnimationsFromFile(file);
|
if (IT != ANIMATION_LIST.end()) {
|
||||||
}
|
return loadAnimationsFromFile(*IT);
|
||||||
}
|
}
|
||||||
// Si no se encuentra, retorna vector vacío
|
// Si no se encuentra, retorna vector vacío
|
||||||
return AnimationsFileBuffer{};
|
return AnimationsFileBuffer{};
|
||||||
@@ -411,31 +394,102 @@ void Resource::clear() {
|
|||||||
demos_.clear();
|
demos_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga todos los recursos del juego y muestra el progreso de carga
|
// Carga síncrona completa: usado por Resource::reload() (hot-reload en debug).
|
||||||
|
// En arranque normal la carga la bombea Director::iterate() vía loadStep().
|
||||||
void Resource::load() {
|
void Resource::load() {
|
||||||
// Prepara la gestión del progreso de carga
|
beginLoad();
|
||||||
|
while (!loadStep(INT_MAX)) {
|
||||||
|
// Presupuesto infinito: una sola pasada carga todo
|
||||||
|
}
|
||||||
|
Screen::get()->setVSync(saved_vsync_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepara el estado del cargador incremental. No carga nada todavía.
|
||||||
|
void Resource::beginLoad() {
|
||||||
calculateTotalResources();
|
calculateTotalResources();
|
||||||
initProgressBar();
|
initProgressBar();
|
||||||
|
|
||||||
// Muerstra la ventana y desactiva el sincronismo vertical
|
saved_vsync_ = Screen::getVSync();
|
||||||
auto* screen = Screen::get();
|
Screen::get()->setVSync(false); // Maximiza FPS durante el preload
|
||||||
auto vsync = Screen::getVSync();
|
|
||||||
screen->setVSync(false);
|
|
||||||
|
|
||||||
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES");
|
stage_ = LoadStage::SOUNDS;
|
||||||
loadSounds(); // Carga sonidos
|
stage_index_ = 0;
|
||||||
loadMusics(); // Carga músicas
|
}
|
||||||
loadTextures(); // Carga texturas
|
|
||||||
loadTextFiles(); // Carga ficheros de texto
|
|
||||||
loadAnimations(); // Carga animaciones
|
|
||||||
loadDemoData(); // Carga datos de demo
|
|
||||||
createText(); // Crea objetos de texto
|
|
||||||
createTextTextures(); // Crea texturas a partir de texto
|
|
||||||
createPlayerTextures(); // Crea las texturas de jugadores con todas sus variantes de paleta
|
|
||||||
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** RESOURCES LOADED");
|
|
||||||
|
|
||||||
// Restablece el sincronismo vertical a su valor original
|
auto Resource::isLoadDone() const -> bool {
|
||||||
screen->setVSync(vsync);
|
return stage_ == LoadStage::DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avança una etapa que descarrega una llista d'assets.
|
||||||
|
void Resource::advanceListLoadStage(const std::vector<std::string>& list, void (Resource::*load_one)(size_t), LoadStage next_stage) {
|
||||||
|
if (stage_index_ >= list.size()) {
|
||||||
|
stage_ = next_stage;
|
||||||
|
stage_index_ = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(this->*load_one)(stage_index_++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bombea la máquina de etapas hasta agotar el presupuesto de tiempo o completar la carga.
|
||||||
|
// Devuelve true cuando ya no queda nada por cargar.
|
||||||
|
auto Resource::loadStep(int budget_ms) -> bool {
|
||||||
|
if (stage_ == LoadStage::DONE) { return true; }
|
||||||
|
|
||||||
|
const Uint64 START_NS = SDL_GetTicksNS();
|
||||||
|
const Uint64 BUDGET_NS = static_cast<Uint64>(budget_ms) * 1'000'000ULL;
|
||||||
|
|
||||||
|
while (stage_ != LoadStage::DONE) {
|
||||||
|
switch (stage_) {
|
||||||
|
case LoadStage::SOUNDS: {
|
||||||
|
if (stage_index_ == 0) { sounds_.clear(); }
|
||||||
|
advanceListLoadStage(Asset::get()->getListByType(Asset::Type::SOUND), &Resource::loadOneSound, LoadStage::MUSICS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LoadStage::MUSICS: {
|
||||||
|
if (stage_index_ == 0) { musics_.clear(); }
|
||||||
|
advanceListLoadStage(Asset::get()->getListByType(Asset::Type::MUSIC), &Resource::loadOneMusic, LoadStage::TEXTURES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LoadStage::TEXTURES: {
|
||||||
|
if (stage_index_ == 0) { textures_.clear(); }
|
||||||
|
advanceListLoadStage(Asset::get()->getListByType(Asset::Type::BITMAP), &Resource::loadOneTexture, LoadStage::TEXT_FILES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LoadStage::TEXT_FILES: {
|
||||||
|
if (stage_index_ == 0) { text_files_.clear(); }
|
||||||
|
advanceListLoadStage(Asset::get()->getListByType(Asset::Type::FONT), &Resource::loadOneTextFile, LoadStage::ANIMATIONS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LoadStage::ANIMATIONS: {
|
||||||
|
if (stage_index_ == 0) { animations_.clear(); }
|
||||||
|
advanceListLoadStage(Asset::get()->getListByType(Asset::Type::ANIMATION), &Resource::loadOneAnimation, LoadStage::DEMO_DATA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LoadStage::DEMO_DATA: {
|
||||||
|
if (stage_index_ == 0) { demos_.clear(); }
|
||||||
|
advanceListLoadStage(Asset::get()->getListByType(Asset::Type::DEMODATA), &Resource::loadOneDemoData, LoadStage::CREATE_TEXT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LoadStage::CREATE_TEXT:
|
||||||
|
createText();
|
||||||
|
stage_ = LoadStage::CREATE_TEXT_TEXTURES;
|
||||||
|
break;
|
||||||
|
case LoadStage::CREATE_TEXT_TEXTURES:
|
||||||
|
createTextTextures();
|
||||||
|
stage_ = LoadStage::CREATE_PLAYER_TEXTURES;
|
||||||
|
break;
|
||||||
|
case LoadStage::CREATE_PLAYER_TEXTURES:
|
||||||
|
createPlayerTextures();
|
||||||
|
stage_ = LoadStage::DONE;
|
||||||
|
break;
|
||||||
|
case LoadStage::DONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((SDL_GetTicksNS() - START_NS) >= BUDGET_NS) { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return stage_ == LoadStage::DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recarga todos los recursos (limpia y vuelve a cargar)
|
// Recarga todos los recursos (limpia y vuelve a cargar)
|
||||||
@@ -448,96 +502,78 @@ void Resource::reload() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga los sonidos del juego
|
// Carga un sonido concreto desde la lista de assets
|
||||||
void Resource::loadSounds() {
|
void Resource::loadOneSound(size_t idx) {
|
||||||
auto list = Asset::get()->getListByType(Asset::Type::SOUND);
|
auto list = Asset::get()->getListByType(Asset::Type::SOUND);
|
||||||
sounds_.clear();
|
const auto& path = list[idx];
|
||||||
|
auto name = getFileName(path);
|
||||||
for (const auto& l : list) {
|
updateLoadingProgress(name);
|
||||||
auto name = getFileName(l);
|
auto audio_data = loadAudioData(path);
|
||||||
updateLoadingProgress(name);
|
Ja::Sound* sound = nullptr;
|
||||||
auto audio_data = loadAudioData(l);
|
if (!audio_data.data.empty()) {
|
||||||
JA_Sound_t* sound = nullptr;
|
sound = Ja::loadSound(audio_data.data.data(), audio_data.data.size());
|
||||||
if (!audio_data.data.empty()) {
|
} else {
|
||||||
sound = JA_LoadSound(audio_data.data.data(), audio_data.data.size());
|
sound = Ja::loadSound(path.c_str());
|
||||||
} else {
|
|
||||||
sound = JA_LoadSound(l.c_str());
|
|
||||||
}
|
|
||||||
if (sound == nullptr) {
|
|
||||||
std::cout << "Sound load failed: " << name << '\n';
|
|
||||||
}
|
|
||||||
sounds_.emplace_back(name, sound);
|
|
||||||
}
|
}
|
||||||
|
if (sound == nullptr) {
|
||||||
|
std::cout << "Sound load failed: " << name << '\n';
|
||||||
|
}
|
||||||
|
sounds_.emplace_back(name, sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga las músicas del juego
|
// Carga una música concreta desde la lista de assets
|
||||||
void Resource::loadMusics() {
|
void Resource::loadOneMusic(size_t idx) {
|
||||||
auto list = Asset::get()->getListByType(Asset::Type::MUSIC);
|
auto list = Asset::get()->getListByType(Asset::Type::MUSIC);
|
||||||
musics_.clear();
|
const auto& path = list[idx];
|
||||||
|
auto name = getFileName(path);
|
||||||
for (const auto& l : list) {
|
updateLoadingProgress(name);
|
||||||
auto name = getFileName(l);
|
auto audio_data = loadAudioData(path);
|
||||||
updateLoadingProgress(name);
|
Ja::Music* music = nullptr;
|
||||||
auto audio_data = loadAudioData(l);
|
if (!audio_data.data.empty()) {
|
||||||
JA_Music_t* music = nullptr;
|
music = Ja::loadMusic(audio_data.data.data(), audio_data.data.size());
|
||||||
if (!audio_data.data.empty()) {
|
} else {
|
||||||
music = JA_LoadMusic(audio_data.data.data(), audio_data.data.size());
|
music = Ja::loadMusic(path.c_str());
|
||||||
} else {
|
|
||||||
music = JA_LoadMusic(l.c_str());
|
|
||||||
}
|
|
||||||
if (music == nullptr) {
|
|
||||||
std::cout << "Music load failed: " << name << '\n';
|
|
||||||
}
|
|
||||||
musics_.emplace_back(name, music);
|
|
||||||
}
|
}
|
||||||
|
if (music == nullptr) {
|
||||||
|
std::cout << "Music load failed: " << name << '\n';
|
||||||
|
}
|
||||||
|
musics_.emplace_back(name, music);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga las texturas del juego
|
// Carga una textura concreta desde la lista de assets
|
||||||
void Resource::loadTextures() {
|
void Resource::loadOneTexture(size_t idx) {
|
||||||
auto list = Asset::get()->getListByType(Asset::Type::BITMAP);
|
auto list = Asset::get()->getListByType(Asset::Type::BITMAP);
|
||||||
textures_.clear();
|
const auto& path = list[idx];
|
||||||
|
auto name = getFileName(path);
|
||||||
for (const auto& l : list) {
|
updateLoadingProgress(name);
|
||||||
auto name = getFileName(l);
|
textures_.emplace_back(name, std::make_shared<Texture>(Screen::get()->getRenderer(), path));
|
||||||
updateLoadingProgress(name);
|
|
||||||
textures_.emplace_back(name, std::make_shared<Texture>(Screen::get()->getRenderer(), l));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga los ficheros de texto del juego
|
// Carga un fichero de texto concreto desde la lista de assets
|
||||||
void Resource::loadTextFiles() {
|
void Resource::loadOneTextFile(size_t idx) {
|
||||||
auto list = Asset::get()->getListByType(Asset::Type::FONT);
|
auto list = Asset::get()->getListByType(Asset::Type::FONT);
|
||||||
text_files_.clear();
|
const auto& path = list[idx];
|
||||||
|
auto name = getFileName(path);
|
||||||
for (const auto& l : list) {
|
updateLoadingProgress(name);
|
||||||
auto name = getFileName(l);
|
text_files_.emplace_back(name, Text::loadFile(path));
|
||||||
updateLoadingProgress(name);
|
|
||||||
text_files_.emplace_back(name, Text::loadFile(l));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga las animaciones del juego
|
// Carga una animación concreta desde la lista de assets
|
||||||
void Resource::loadAnimations() {
|
void Resource::loadOneAnimation(size_t idx) {
|
||||||
auto list = Asset::get()->getListByType(Asset::Type::ANIMATION);
|
auto list = Asset::get()->getListByType(Asset::Type::ANIMATION);
|
||||||
animations_.clear();
|
const auto& path = list[idx];
|
||||||
|
auto name = getFileName(path);
|
||||||
for (const auto& l : list) {
|
updateLoadingProgress(name);
|
||||||
auto name = getFileName(l);
|
animations_.emplace_back(name, loadAnimationsFromFile(path));
|
||||||
updateLoadingProgress(name);
|
|
||||||
animations_.emplace_back(name, loadAnimationsFromFile(l));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga los datos para el modo demostración
|
// Carga un fichero de datos de demo concreto desde la lista de assets
|
||||||
void Resource::loadDemoData() {
|
void Resource::loadOneDemoData(size_t idx) {
|
||||||
auto list = Asset::get()->getListByType(Asset::Type::DEMODATA);
|
auto list = Asset::get()->getListByType(Asset::Type::DEMODATA);
|
||||||
demos_.clear();
|
const auto& path = list[idx];
|
||||||
|
auto name = getFileName(path);
|
||||||
for (const auto& l : list) {
|
updateLoadingProgress(name);
|
||||||
auto name = getFileName(l);
|
demos_.emplace_back(loadDemoDataFromFile(path));
|
||||||
updateLoadingProgress(name);
|
|
||||||
demos_.emplace_back(loadDemoDataFromFile(l));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea las texturas de jugadores con todas sus variantes de paleta
|
// Crea las texturas de jugadores con todas sus variantes de paleta
|
||||||
@@ -558,14 +594,10 @@ void Resource::createPlayerTextures() {
|
|||||||
const auto& player = players[player_idx]; // Obtenemos el jugador actual
|
const auto& player = players[player_idx]; // Obtenemos el jugador actual
|
||||||
|
|
||||||
// Encontrar el archivo original de la textura
|
// Encontrar el archivo original de la textura
|
||||||
std::string texture_file_path;
|
const auto TEXTURE_LIST = Asset::get()->getListByType(Asset::Type::BITMAP);
|
||||||
auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP);
|
const auto IT = std::ranges::find_if(TEXTURE_LIST,
|
||||||
for (const auto& file : texture_list) {
|
[&player](const auto& file) { return getFileName(file) == player.base_texture; });
|
||||||
if (getFileName(file) == player.base_texture) {
|
const std::string TEXTURE_FILE_PATH = (IT != TEXTURE_LIST.end()) ? *IT : std::string{};
|
||||||
texture_file_path = file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crear las 4 texturas con sus respectivas paletas
|
// Crear las 4 texturas con sus respectivas paletas
|
||||||
for (int palette_idx = 0; palette_idx < 4; ++palette_idx) {
|
for (int palette_idx = 0; palette_idx < 4; ++palette_idx) {
|
||||||
@@ -574,14 +606,14 @@ void Resource::createPlayerTextures() {
|
|||||||
if (palette_idx == 0) {
|
if (palette_idx == 0) {
|
||||||
// Textura 0 - usar la ya cargada y modificar solo paleta 0 (default_shirt)
|
// Textura 0 - usar la ya cargada y modificar solo paleta 0 (default_shirt)
|
||||||
texture = getTexture(player.base_texture);
|
texture = getTexture(player.base_texture);
|
||||||
texture->setPaletteColor(0, 16, param.player.default_shirt[player_idx].darkest.TO_UINT32());
|
texture->setPaletteColor(0, 16, param.player.default_shirt[player_idx].darkest.toUint32());
|
||||||
texture->setPaletteColor(0, 17, param.player.default_shirt[player_idx].dark.TO_UINT32());
|
texture->setPaletteColor(0, 17, param.player.default_shirt[player_idx].dark.toUint32());
|
||||||
texture->setPaletteColor(0, 18, param.player.default_shirt[player_idx].base.TO_UINT32());
|
texture->setPaletteColor(0, 18, param.player.default_shirt[player_idx].base.toUint32());
|
||||||
texture->setPaletteColor(0, 19, param.player.default_shirt[player_idx].light.TO_UINT32());
|
texture->setPaletteColor(0, 19, param.player.default_shirt[player_idx].light.toUint32());
|
||||||
texture->setPaletteColor(0, 56, param.player.outline_color[player_idx].TO_UINT32());
|
texture->setPaletteColor(0, 56, param.player.outline_color[player_idx].toUint32());
|
||||||
} else {
|
} else {
|
||||||
// Crear textura nueva desde archivo usando ResourceHelper
|
// Crear textura nueva desde archivo usando ResourceHelper
|
||||||
texture = std::make_shared<Texture>(Screen::get()->getRenderer(), texture_file_path);
|
texture = std::make_shared<Texture>(Screen::get()->getRenderer(), TEXTURE_FILE_PATH);
|
||||||
|
|
||||||
// Añadir todas las paletas
|
// Añadir todas las paletas
|
||||||
texture->addPaletteFromPalFile(Asset::get()->getPath(player.palette_files[0]));
|
texture->addPaletteFromPalFile(Asset::get()->getPath(player.palette_files[0]));
|
||||||
@@ -590,18 +622,18 @@ void Resource::createPlayerTextures() {
|
|||||||
|
|
||||||
if (palette_idx == 1) {
|
if (palette_idx == 1) {
|
||||||
// Textura 1 - modificar solo paleta 1 (one_coffee_shirt)
|
// Textura 1 - modificar solo paleta 1 (one_coffee_shirt)
|
||||||
texture->setPaletteColor(1, 16, param.player.one_coffee_shirt[player_idx].darkest.TO_UINT32());
|
texture->setPaletteColor(1, 16, param.player.one_coffee_shirt[player_idx].darkest.toUint32());
|
||||||
texture->setPaletteColor(1, 17, param.player.one_coffee_shirt[player_idx].dark.TO_UINT32());
|
texture->setPaletteColor(1, 17, param.player.one_coffee_shirt[player_idx].dark.toUint32());
|
||||||
texture->setPaletteColor(1, 18, param.player.one_coffee_shirt[player_idx].base.TO_UINT32());
|
texture->setPaletteColor(1, 18, param.player.one_coffee_shirt[player_idx].base.toUint32());
|
||||||
texture->setPaletteColor(1, 19, param.player.one_coffee_shirt[player_idx].light.TO_UINT32());
|
texture->setPaletteColor(1, 19, param.player.one_coffee_shirt[player_idx].light.toUint32());
|
||||||
texture->setPaletteColor(1, 56, param.player.outline_color[player_idx].TO_UINT32());
|
texture->setPaletteColor(1, 56, param.player.outline_color[player_idx].toUint32());
|
||||||
} else if (palette_idx == 2) {
|
} else if (palette_idx == 2) {
|
||||||
// Textura 2 - modificar solo paleta 2 (two_coffee_shirt)
|
// Textura 2 - modificar solo paleta 2 (two_coffee_shirt)
|
||||||
texture->setPaletteColor(2, 16, param.player.two_coffee_shirt[player_idx].darkest.TO_UINT32());
|
texture->setPaletteColor(2, 16, param.player.two_coffee_shirt[player_idx].darkest.toUint32());
|
||||||
texture->setPaletteColor(2, 17, param.player.two_coffee_shirt[player_idx].dark.TO_UINT32());
|
texture->setPaletteColor(2, 17, param.player.two_coffee_shirt[player_idx].dark.toUint32());
|
||||||
texture->setPaletteColor(2, 18, param.player.two_coffee_shirt[player_idx].base.TO_UINT32());
|
texture->setPaletteColor(2, 18, param.player.two_coffee_shirt[player_idx].base.toUint32());
|
||||||
texture->setPaletteColor(2, 19, param.player.two_coffee_shirt[player_idx].light.TO_UINT32());
|
texture->setPaletteColor(2, 19, param.player.two_coffee_shirt[player_idx].light.toUint32());
|
||||||
texture->setPaletteColor(2, 56, param.player.outline_color[player_idx].TO_UINT32());
|
texture->setPaletteColor(2, 56, param.player.outline_color[player_idx].toUint32());
|
||||||
}
|
}
|
||||||
// Textura 3 (palette_idx == 3) - no modificar nada, usar colores originales
|
// Textura 3 (palette_idx == 3) - no modificar nada, usar colores originales
|
||||||
}
|
}
|
||||||
@@ -638,9 +670,9 @@ void Resource::createTextTextures() {
|
|||||||
{"game_text_1000000_points", Lang::getText("[GAME_TEXT] 8")}};
|
{"game_text_1000000_points", Lang::getText("[GAME_TEXT] 8")}};
|
||||||
|
|
||||||
auto text1 = getText("04b_25_enhanced");
|
auto text1 = getText("04b_25_enhanced");
|
||||||
for (const auto& s : strings1) {
|
std::ranges::transform(strings1, std::back_inserter(textures_), [&](const auto& s) {
|
||||||
textures_.emplace_back(s.name, text1->writeDXToTexture(Text::STROKE, s.text, -2, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
|
return ResourceTexture(s.name, text1->writeDXToTexture(Text::STROKE, s.text, -2, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
|
||||||
}
|
});
|
||||||
|
|
||||||
// Texturas de tamaño doble
|
// Texturas de tamaño doble
|
||||||
std::vector<NameAndText> strings2 = {
|
std::vector<NameAndText> strings2 = {
|
||||||
@@ -652,9 +684,9 @@ void Resource::createTextTextures() {
|
|||||||
{"game_text_game_over", "Game Over"}};
|
{"game_text_game_over", "Game Over"}};
|
||||||
|
|
||||||
auto text2 = getText("04b_25_2x_enhanced");
|
auto text2 = getText("04b_25_2x_enhanced");
|
||||||
for (const auto& s : strings2) {
|
std::ranges::transform(strings2, std::back_inserter(textures_), [&](const auto& s) {
|
||||||
textures_.emplace_back(s.name, text2->writeDXToTexture(Text::STROKE, s.text, -4, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
|
return ResourceTexture(s.name, text2->writeDXToTexture(Text::STROKE, s.text, -4, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea los objetos de texto a partir de los archivos de textura y texto
|
// Crea los objetos de texto a partir de los archivos de textura y texto
|
||||||
@@ -704,7 +736,7 @@ void Resource::createText() {
|
|||||||
void Resource::clearSounds() {
|
void Resource::clearSounds() {
|
||||||
for (auto& sound : sounds_) {
|
for (auto& sound : sounds_) {
|
||||||
if (sound.sound != nullptr) {
|
if (sound.sound != nullptr) {
|
||||||
JA_DeleteSound(sound.sound);
|
Ja::deleteSound(sound.sound);
|
||||||
sound.sound = nullptr;
|
sound.sound = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -715,7 +747,7 @@ void Resource::clearSounds() {
|
|||||||
void Resource::clearMusics() {
|
void Resource::clearMusics() {
|
||||||
for (auto& music : musics_) {
|
for (auto& music : musics_) {
|
||||||
if (music.music != nullptr) {
|
if (music.music != nullptr) {
|
||||||
JA_DeleteMusic(music.music);
|
Ja::deleteMusic(music.music);
|
||||||
music.music = nullptr;
|
music.music = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -754,8 +786,18 @@ void Resource::renderProgress() {
|
|||||||
screen->start();
|
screen->start();
|
||||||
screen->clean();
|
screen->clean();
|
||||||
|
|
||||||
|
// Si la pantalla de carga está desactivada, dejamos todo en negro.
|
||||||
|
// wait_for_input solo tiene efecto cuando la pantalla está visible.
|
||||||
|
if (!Options::loading.show) {
|
||||||
|
screen->coreRender();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Estamos en la fase de espera explícita al usuario tras terminar la carga
|
||||||
|
const bool WAITING_FOR_INPUT = isLoadDone() && Options::loading.wait_for_input;
|
||||||
|
|
||||||
auto text_color = param.resource.color;
|
auto text_color = param.resource.color;
|
||||||
auto bar_color = param.resource.color.DARKEN(100);
|
auto bar_color = param.resource.color.darken(100);
|
||||||
const auto TEXT_HEIGHT = loading_text_->getCharacterSize();
|
const auto TEXT_HEIGHT = loading_text_->getCharacterSize();
|
||||||
|
|
||||||
// Dibuja el interior de la barra de progreso
|
// Dibuja el interior de la barra de progreso
|
||||||
@@ -766,14 +808,20 @@ void Resource::renderProgress() {
|
|||||||
SDL_SetRenderDrawColor(renderer, bar_color.r, bar_color.g, bar_color.b, bar_color.a);
|
SDL_SetRenderDrawColor(renderer, bar_color.r, bar_color.g, bar_color.b, bar_color.a);
|
||||||
SDL_RenderRect(renderer, &loading_wired_rect_);
|
SDL_RenderRect(renderer, &loading_wired_rect_);
|
||||||
|
|
||||||
// Escribe el texto de carga encima de la barra
|
// Texto centrado sobre la barra: mientras carga, el nombre del recurso;
|
||||||
/*
|
// al terminar en modo wait_for_input, el prompt traducido.
|
||||||
loading_text_->writeColored(
|
const std::string OVER_BAR_TEXT = WAITING_FOR_INPUT
|
||||||
loading_wired_rect_.x,
|
? Lang::getText("[RESOURCE] PRESS_TO_CONTINUE")
|
||||||
loading_wired_rect_.y - 9,
|
: loading_resource_name_;
|
||||||
Lang::getText("[RESOURCE] LOADING") + " : " + loading_resource_name_,
|
if ((Options::loading.show_resource_name || WAITING_FOR_INPUT) && !OVER_BAR_TEXT.empty()) {
|
||||||
text_color);
|
loading_text_->writeDX(
|
||||||
*/
|
Text::CENTER | Text::COLOR,
|
||||||
|
loading_wired_rect_.x + (loading_wired_rect_.w / 2),
|
||||||
|
loading_wired_rect_.y - TEXT_HEIGHT - 2,
|
||||||
|
OVER_BAR_TEXT,
|
||||||
|
1,
|
||||||
|
text_color);
|
||||||
|
}
|
||||||
|
|
||||||
// Muestra nombre de la aplicación
|
// Muestra nombre de la aplicación
|
||||||
loading_text_->writeDX(
|
loading_text_->writeDX(
|
||||||
@@ -784,63 +832,45 @@ void Resource::renderProgress() {
|
|||||||
1,
|
1,
|
||||||
text_color);
|
text_color);
|
||||||
|
|
||||||
// Muestra la versión
|
// Muestra la versión y el hash del commit
|
||||||
loading_text_->writeDX(
|
loading_text_->writeDX(
|
||||||
Text::CENTER | Text::COLOR,
|
Text::CENTER | Text::COLOR,
|
||||||
param.game.game_area.center_x,
|
param.game.game_area.center_x,
|
||||||
param.game.game_area.center_y + TEXT_HEIGHT,
|
param.game.game_area.center_y + TEXT_HEIGHT,
|
||||||
"(" + std::string(Version::GIT_HASH) + ")",
|
"ver. " + std::string(Texts::VERSION) + " (" + std::string(Version::GIT_HASH) + ")",
|
||||||
1,
|
1,
|
||||||
text_color);
|
text_color);
|
||||||
|
|
||||||
// Muestra información del monitor desplazada hacia abajo
|
|
||||||
/*loading_text_->writeColored(
|
|
||||||
X_PADDING,
|
|
||||||
Y_PADDING + 18,
|
|
||||||
screen->getDisplayMonitorName(),
|
|
||||||
text_color);
|
|
||||||
loading_text_->writeColored(
|
|
||||||
X_PADDING,
|
|
||||||
Y_PADDING + 27,
|
|
||||||
std::to_string(screen->getDisplayMonitorWidth()) + "x" + std::to_string(screen->getDisplayMonitorHeight()),
|
|
||||||
text_color);
|
|
||||||
loading_text_->writeColored(
|
|
||||||
X_PADDING,
|
|
||||||
Y_PADDING + 36,
|
|
||||||
std::to_string(screen->getDisplayMonitorRefreshRate()) + "Hz",
|
|
||||||
text_color);*/
|
|
||||||
|
|
||||||
// Renderiza el frame en pantalla
|
// Renderiza el frame en pantalla
|
||||||
screen->coreRender();
|
screen->coreRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga los datos para el modo demostración (sin mostrar progreso)
|
// Carga los datos para el modo demostración (sin mostrar progreso)
|
||||||
void Resource::loadDemoDataQuiet() {
|
void Resource::loadDemoDataQuiet() {
|
||||||
auto list = Asset::get()->getListByType(Asset::Type::DEMODATA);
|
const auto LIST = Asset::get()->getListByType(Asset::Type::DEMODATA);
|
||||||
demos_.clear();
|
demos_.clear();
|
||||||
|
demos_.reserve(LIST.size());
|
||||||
for (const auto& l : list) {
|
std::ranges::transform(LIST, std::back_inserter(demos_), [](const auto& l) { return loadDemoDataFromFile(l); });
|
||||||
demos_.emplace_back(loadDemoDataFromFile(l));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa los rectangulos que definen la barra de progreso
|
// Inicializa los rectangulos que definen la barra de progreso
|
||||||
void Resource::initProgressBar() {
|
void Resource::initProgressBar() {
|
||||||
const float BAR_Y_POSITION = param.game.height - BAR_HEIGHT - Y_PADDING;
|
const float WIRED_BAR_WIDTH = param.game.width * BAR_WIDTH_RATIO;
|
||||||
|
const float BAR_X_POSITION = (param.game.width - WIRED_BAR_WIDTH) / 2.0F;
|
||||||
|
const float BAR_Y_POSITION = (param.game.height * BAR_Y_RATIO) - (BAR_HEIGHT / 2.0F);
|
||||||
|
|
||||||
const float WIRED_BAR_WIDTH = param.game.width - (X_PADDING * 2);
|
loading_wired_rect_ = {.x = BAR_X_POSITION, .y = BAR_Y_POSITION, .w = WIRED_BAR_WIDTH, .h = BAR_HEIGHT};
|
||||||
loading_wired_rect_ = {.x = X_PADDING, .y = BAR_Y_POSITION, .w = WIRED_BAR_WIDTH, .h = BAR_HEIGHT};
|
|
||||||
|
|
||||||
const float FULL_BAR_WIDTH = WIRED_BAR_WIDTH * loading_count_.getPercentage();
|
const float FULL_BAR_WIDTH = WIRED_BAR_WIDTH * loading_count_.getPercentage();
|
||||||
loading_full_rect_ = {.x = X_PADDING, .y = BAR_Y_POSITION, .w = FULL_BAR_WIDTH, .h = BAR_HEIGHT};
|
loading_full_rect_ = {.x = BAR_X_POSITION, .y = BAR_Y_POSITION, .w = FULL_BAR_WIDTH, .h = BAR_HEIGHT};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el progreso de carga y muestra la barra
|
// Actualiza el estado del progreso. No renderiza: el repintado lo hace
|
||||||
|
// Preload::iterate una vez por frame llamando a renderProgress().
|
||||||
void Resource::updateLoadingProgress(std::string name) {
|
void Resource::updateLoadingProgress(std::string name) {
|
||||||
loading_resource_name_ = std::move(name);
|
loading_resource_name_ = std::move(name);
|
||||||
loading_count_.increase();
|
loading_count_.increase();
|
||||||
updateProgressBar();
|
updateProgressBar();
|
||||||
renderProgress();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza la barra de estado
|
// Actualiza la barra de estado
|
||||||
@@ -3,24 +3,27 @@
|
|||||||
#include <SDL3/SDL.h> // Para SDL_FRect
|
#include <SDL3/SDL.h> // Para SDL_FRect
|
||||||
|
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
|
#include <cstdint> // Para std::uint8_t
|
||||||
#include <memory> // Para shared_ptr
|
#include <memory> // Para shared_ptr
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "animated_sprite.hpp" // Para AnimationsFileBuffer
|
#include "core/rendering/sprite/animated_sprite.hpp" // Para AnimationsFileBuffer
|
||||||
#include "demo.hpp" // Para DemoData
|
#include "core/rendering/text.hpp" // Para Text, TextFile
|
||||||
#include "text.hpp" // Para Text, TextFile
|
#include "core/rendering/texture.hpp" // Para Texture
|
||||||
#include "texture.hpp" // Para Texture
|
#include "core/system/demo.hpp" // Para DemoData
|
||||||
|
|
||||||
struct JA_Music_t;
|
namespace Ja {
|
||||||
struct JA_Sound_t;
|
struct Music;
|
||||||
|
struct Sound;
|
||||||
|
} // namespace Ja
|
||||||
|
|
||||||
// --- Clase Resource: gestiona todos los recursos del juego (singleton) ---
|
// --- Clase Resource: gestiona todos los recursos del juego (singleton) ---
|
||||||
class Resource {
|
class Resource {
|
||||||
public:
|
public:
|
||||||
// --- Enum para el modo de carga ---
|
// --- Enum para el modo de carga ---
|
||||||
enum class LoadingMode {
|
enum class LoadingMode : std::uint8_t {
|
||||||
PRELOAD, // Carga todos los recursos al inicio
|
PRELOAD, // Carga todos los recursos al inicio
|
||||||
LAZY_LOAD // Carga los recursos bajo demanda
|
LAZY_LOAD // Carga los recursos bajo demanda
|
||||||
};
|
};
|
||||||
@@ -31,8 +34,8 @@ class Resource {
|
|||||||
static auto get() -> Resource*; // Obtiene el puntero al objeto Resource
|
static auto get() -> Resource*; // Obtiene el puntero al objeto Resource
|
||||||
|
|
||||||
// --- Métodos de acceso a recursos ---
|
// --- Métodos de acceso a recursos ---
|
||||||
auto getSound(const std::string& name) -> JA_Sound_t*; // Obtiene el sonido por nombre
|
auto getSound(const std::string& name) -> Ja::Sound*; // Obtiene el sonido por nombre
|
||||||
auto getMusic(const std::string& name) -> JA_Music_t*; // Obtiene la música por nombre
|
auto getMusic(const std::string& name) -> Ja::Music*; // Obtiene la música por nombre
|
||||||
auto getTexture(const std::string& name) -> std::shared_ptr<Texture>; // Obtiene la textura por nombre
|
auto getTexture(const std::string& name) -> std::shared_ptr<Texture>; // Obtiene la textura por nombre
|
||||||
auto getTextFile(const std::string& name) -> std::shared_ptr<Text::File>; // Obtiene el fichero de texto por nombre
|
auto getTextFile(const std::string& name) -> std::shared_ptr<Text::File>; // Obtiene el fichero de texto por nombre
|
||||||
auto getText(const std::string& name) -> std::shared_ptr<Text>; // Obtiene el objeto de texto por nombre
|
auto getText(const std::string& name) -> std::shared_ptr<Text>; // Obtiene el objeto de texto por nombre
|
||||||
@@ -42,6 +45,15 @@ class Resource {
|
|||||||
// --- Métodos de recarga de recursos ---
|
// --- Métodos de recarga de recursos ---
|
||||||
void reload(); // Recarga todos los recursos
|
void reload(); // Recarga todos los recursos
|
||||||
|
|
||||||
|
// --- Cargador incremental ---
|
||||||
|
// beginLoad prepara el estado; loadStep carga recursos hasta agotar el presupuesto;
|
||||||
|
// devuelve true cuando ya no queda nada. renderProgress se llama una vez por frame
|
||||||
|
// desde la escena Preload.
|
||||||
|
void beginLoad();
|
||||||
|
auto loadStep(int budget_ms) -> bool;
|
||||||
|
[[nodiscard]] auto isLoadDone() const -> bool;
|
||||||
|
void renderProgress();
|
||||||
|
|
||||||
// --- Método para obtener el modo de carga actual ---
|
// --- Método para obtener el modo de carga actual ---
|
||||||
[[nodiscard]] auto getLoadingMode() const -> LoadingMode { return loading_mode_; }
|
[[nodiscard]] auto getLoadingMode() const -> LoadingMode { return loading_mode_; }
|
||||||
|
|
||||||
@@ -49,18 +61,18 @@ class Resource {
|
|||||||
// --- Estructuras para recursos individuales ---
|
// --- Estructuras para recursos individuales ---
|
||||||
struct ResourceSound {
|
struct ResourceSound {
|
||||||
std::string name; // Nombre del sonido
|
std::string name; // Nombre del sonido
|
||||||
JA_Sound_t* sound; // Objeto con el sonido
|
Ja::Sound* sound; // Objeto con el sonido
|
||||||
|
|
||||||
ResourceSound(std::string name, JA_Sound_t* sound = nullptr)
|
explicit ResourceSound(std::string name, Ja::Sound* sound = nullptr)
|
||||||
: name(std::move(name)),
|
: name(std::move(name)),
|
||||||
sound(sound) {}
|
sound(sound) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourceMusic {
|
struct ResourceMusic {
|
||||||
std::string name; // Nombre de la música
|
std::string name; // Nombre de la música
|
||||||
JA_Music_t* music; // Objeto con la música
|
Ja::Music* music; // Objeto con la música
|
||||||
|
|
||||||
ResourceMusic(std::string name, JA_Music_t* music = nullptr)
|
explicit ResourceMusic(std::string name, Ja::Music* music = nullptr)
|
||||||
: name(std::move(name)),
|
: name(std::move(name)),
|
||||||
music(music) {}
|
music(music) {}
|
||||||
};
|
};
|
||||||
@@ -69,7 +81,7 @@ class Resource {
|
|||||||
std::string name; // Nombre de la textura
|
std::string name; // Nombre de la textura
|
||||||
std::shared_ptr<Texture> texture; // Objeto con la textura
|
std::shared_ptr<Texture> texture; // Objeto con la textura
|
||||||
|
|
||||||
ResourceTexture(std::string name, std::shared_ptr<Texture> texture = nullptr)
|
explicit ResourceTexture(std::string name, std::shared_ptr<Texture> texture = nullptr)
|
||||||
: name(std::move(name)),
|
: name(std::move(name)),
|
||||||
texture(std::move(texture)) {}
|
texture(std::move(texture)) {}
|
||||||
};
|
};
|
||||||
@@ -78,7 +90,7 @@ class Resource {
|
|||||||
std::string name; // Nombre del fichero
|
std::string name; // Nombre del fichero
|
||||||
std::shared_ptr<Text::File> text_file; // Objeto con los descriptores de la fuente de texto
|
std::shared_ptr<Text::File> text_file; // Objeto con los descriptores de la fuente de texto
|
||||||
|
|
||||||
ResourceTextFile(std::string name, std::shared_ptr<Text::File> text_file = nullptr)
|
explicit ResourceTextFile(std::string name, std::shared_ptr<Text::File> text_file = nullptr)
|
||||||
: name(std::move(name)),
|
: name(std::move(name)),
|
||||||
text_file(std::move(text_file)) {}
|
text_file(std::move(text_file)) {}
|
||||||
};
|
};
|
||||||
@@ -87,7 +99,7 @@ class Resource {
|
|||||||
std::string name; // Nombre del objeto
|
std::string name; // Nombre del objeto
|
||||||
std::shared_ptr<Text> text; // Objeto de texto
|
std::shared_ptr<Text> text; // Objeto de texto
|
||||||
|
|
||||||
ResourceText(std::string name, std::shared_ptr<Text> text = nullptr)
|
explicit ResourceText(std::string name, std::shared_ptr<Text> text = nullptr)
|
||||||
: name(std::move(name)),
|
: name(std::move(name)),
|
||||||
text(std::move(text)) {}
|
text(std::move(text)) {}
|
||||||
};
|
};
|
||||||
@@ -96,7 +108,7 @@ class Resource {
|
|||||||
std::string name; // Nombre de la animación
|
std::string name; // Nombre de la animación
|
||||||
AnimationsFileBuffer animation; // Objeto con las animaciones
|
AnimationsFileBuffer animation; // Objeto con las animaciones
|
||||||
|
|
||||||
ResourceAnimation(std::string name, AnimationsFileBuffer animation = {})
|
explicit ResourceAnimation(std::string name, AnimationsFileBuffer animation = {})
|
||||||
: name(std::move(name)),
|
: name(std::move(name)),
|
||||||
animation(std::move(animation)) {}
|
animation(std::move(animation)) {}
|
||||||
};
|
};
|
||||||
@@ -107,7 +119,7 @@ class Resource {
|
|||||||
size_t loaded{0}; // Número de recursos cargados
|
size_t loaded{0}; // Número de recursos cargados
|
||||||
|
|
||||||
ResourceCount() = default;
|
ResourceCount() = default;
|
||||||
ResourceCount(size_t total)
|
explicit ResourceCount(size_t total)
|
||||||
: total(total) {}
|
: total(total) {}
|
||||||
|
|
||||||
void add(size_t amount) { loaded += amount; }
|
void add(size_t amount) { loaded += amount; }
|
||||||
@@ -117,12 +129,15 @@ class Resource {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Constantes para la pantalla de carga ---
|
// --- Constantes para la barra de progreso de la pantalla de carga ---
|
||||||
static constexpr float X_PADDING = 60.0F;
|
// BAR_WIDTH_RATIO: fracción del ancho de la pantalla ocupada por la barra (centrada)
|
||||||
static constexpr float Y_PADDING = 20.0F;
|
// 1.0 = ancho completo, 0.5 = la mitad del ancho
|
||||||
|
// BAR_Y_RATIO: posición vertical del CENTRO de la barra en fracción de la altura
|
||||||
|
// 0.0 = centro en el borde superior, 1.0 = centro en el borde inferior
|
||||||
|
// BAR_HEIGHT: grosor de la barra en píxeles
|
||||||
|
static constexpr float BAR_WIDTH_RATIO = 0.5F;
|
||||||
|
static constexpr float BAR_Y_RATIO = 0.85F;
|
||||||
static constexpr float BAR_HEIGHT = 5.0F;
|
static constexpr float BAR_HEIGHT = 5.0F;
|
||||||
static constexpr Color BAR_COLOR = Color(128, 128, 128);
|
|
||||||
static constexpr Color TEXT_COLOR = Color(255, 255, 255);
|
|
||||||
|
|
||||||
// --- Modo de carga ---
|
// --- Modo de carga ---
|
||||||
LoadingMode loading_mode_;
|
LoadingMode loading_mode_;
|
||||||
@@ -143,13 +158,24 @@ class Resource {
|
|||||||
SDL_FRect loading_wired_rect_;
|
SDL_FRect loading_wired_rect_;
|
||||||
SDL_FRect loading_full_rect_;
|
SDL_FRect loading_full_rect_;
|
||||||
|
|
||||||
|
// --- Estado del cargador incremental ---
|
||||||
|
enum class LoadStage : std::uint8_t {
|
||||||
|
SOUNDS,
|
||||||
|
MUSICS,
|
||||||
|
TEXTURES,
|
||||||
|
TEXT_FILES,
|
||||||
|
ANIMATIONS,
|
||||||
|
DEMO_DATA,
|
||||||
|
CREATE_TEXT,
|
||||||
|
CREATE_TEXT_TEXTURES,
|
||||||
|
CREATE_PLAYER_TEXTURES,
|
||||||
|
DONE
|
||||||
|
};
|
||||||
|
LoadStage stage_{LoadStage::DONE};
|
||||||
|
size_t stage_index_{0};
|
||||||
|
bool saved_vsync_{false}; // Vsync previo a beginLoad, restaurado por finishBoot/load
|
||||||
|
|
||||||
// --- Métodos internos de carga y gestión ---
|
// --- Métodos internos de carga y gestión ---
|
||||||
void loadSounds(); // Carga los sonidos
|
|
||||||
void loadMusics(); // Carga las músicas
|
|
||||||
void loadTextures(); // Carga las texturas
|
|
||||||
void loadTextFiles(); // Carga los ficheros de texto
|
|
||||||
void loadAnimations(); // Carga las animaciones
|
|
||||||
void loadDemoData(); // Carga los datos para el modo demostración
|
|
||||||
void loadDemoDataQuiet(); // Carga los datos de demo sin mostrar progreso (para modo lazy)
|
void loadDemoDataQuiet(); // Carga los datos de demo sin mostrar progreso (para modo lazy)
|
||||||
void loadEssentialResources(); // Carga recursos esenciales en modo lazy
|
void loadEssentialResources(); // Carga recursos esenciales en modo lazy
|
||||||
void loadEssentialTextures(); // Carga solo las texturas esenciales (fuentes)
|
void loadEssentialTextures(); // Carga solo las texturas esenciales (fuentes)
|
||||||
@@ -164,8 +190,8 @@ class Resource {
|
|||||||
|
|
||||||
// --- Métodos para carga perezosa ---
|
// --- Métodos para carga perezosa ---
|
||||||
void initResourceLists(); // Inicializa las listas de recursos sin cargar el contenido
|
void initResourceLists(); // Inicializa las listas de recursos sin cargar el contenido
|
||||||
static auto loadSoundLazy(const std::string& name) -> JA_Sound_t*; // Carga un sonido específico bajo demanda
|
static auto loadSoundLazy(const std::string& name) -> Ja::Sound*; // Carga un sonido específico bajo demanda
|
||||||
static auto loadMusicLazy(const std::string& name) -> JA_Music_t*; // Carga una música específica bajo demanda
|
static auto loadMusicLazy(const std::string& name) -> Ja::Music*; // Carga una música específica bajo demanda
|
||||||
static auto loadTextureLazy(const std::string& name) -> std::shared_ptr<Texture>; // Carga una textura específica bajo demanda
|
static auto loadTextureLazy(const std::string& name) -> std::shared_ptr<Texture>; // Carga una textura específica bajo demanda
|
||||||
static auto loadTextFileLazy(const std::string& name) -> std::shared_ptr<Text::File>; // Carga un fichero de texto específico bajo demanda
|
static auto loadTextFileLazy(const std::string& name) -> std::shared_ptr<Text::File>; // Carga un fichero de texto específico bajo demanda
|
||||||
auto loadTextLazy(const std::string& name) -> std::shared_ptr<Text>; // Carga un objeto de texto específico bajo demanda
|
auto loadTextLazy(const std::string& name) -> std::shared_ptr<Text>; // Carga un objeto de texto específico bajo demanda
|
||||||
@@ -173,11 +199,22 @@ class Resource {
|
|||||||
|
|
||||||
// --- Métodos internos para gestionar el progreso ---
|
// --- Métodos internos para gestionar el progreso ---
|
||||||
void calculateTotalResources(); // Calcula el número de recursos para cargar
|
void calculateTotalResources(); // Calcula el número de recursos para cargar
|
||||||
void renderProgress(); // Muestra el progreso de carga
|
|
||||||
void updateLoadingProgress(std::string name); // Actualiza el progreso de carga
|
void updateLoadingProgress(std::string name); // Actualiza el progreso de carga
|
||||||
void initProgressBar(); // Inicializa los rectangulos que definen la barra de progreso
|
void initProgressBar(); // Inicializa los rectangulos que definen la barra de progreso
|
||||||
void updateProgressBar(); // Actualiza la barra de estado
|
void updateProgressBar(); // Actualiza la barra de estado
|
||||||
|
|
||||||
|
// Avança una etapa que descarrega una llista d'assets: si `stage_index_` desborda la mida,
|
||||||
|
// salta a `next_stage`; si no, crida `load_one` per a l'element actual i incrementa.
|
||||||
|
void advanceListLoadStage(const std::vector<std::string>& list, void (Resource::*load_one)(size_t), LoadStage next_stage);
|
||||||
|
|
||||||
|
// --- Helpers del cargador incremental (cargan un único recurso) ---
|
||||||
|
void loadOneSound(size_t idx);
|
||||||
|
void loadOneMusic(size_t idx);
|
||||||
|
void loadOneTexture(size_t idx);
|
||||||
|
void loadOneTextFile(size_t idx);
|
||||||
|
void loadOneAnimation(size_t idx);
|
||||||
|
void loadOneDemoData(size_t idx);
|
||||||
|
|
||||||
// --- Constructores y destructor privados (singleton) ---
|
// --- Constructores y destructor privados (singleton) ---
|
||||||
explicit Resource(LoadingMode mode); // Constructor privado con modo de carga
|
explicit Resource(LoadingMode mode); // Constructor privado con modo de carga
|
||||||
~Resource(); // Destructor privado
|
~Resource(); // Destructor privado
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "resource_helper.hpp"
|
#include "core/resources/resource_helper.hpp"
|
||||||
|
|
||||||
#include <algorithm> // Para replace
|
#include <algorithm> // Para replace
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
#include <fstream> // Para basic_ifstream, basic_ostream, basic_ios, operator<<, ios, basic_istream, endl, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
|
#include <fstream> // Para basic_ifstream, basic_ostream, basic_ios, operator<<, ios, basic_istream, endl, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
|
||||||
#include <iostream> // Para cout
|
#include <iostream> // Para cout
|
||||||
|
|
||||||
#include "resource_loader.hpp" // Para ResourceLoader
|
#include "core/resources/resource_loader.hpp" // Para ResourceLoader
|
||||||
|
|
||||||
namespace ResourceHelper {
|
namespace ResourceHelper {
|
||||||
static bool resource_system_initialized = false;
|
static bool resource_system_initialized = false;
|
||||||
@@ -59,20 +59,10 @@ namespace ResourceHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto shouldUseResourcePack(const std::string& filepath) -> bool {
|
auto shouldUseResourcePack(const std::string& filepath) -> bool {
|
||||||
// Archivos que NO van al pack:
|
// Si la ruta conté "data/" és candidat al pack. La resta (paths absoluts del
|
||||||
// - config/ (ahora está fuera de data/)
|
// SYSTEM_FOLDER o relatives al binari com gamecontrollerdb.txt) van sempre al
|
||||||
// - archivos absolutos del sistema
|
// filesystem.
|
||||||
|
return filepath.find("data/") != std::string::npos;
|
||||||
if (filepath.find("config/") != std::string::npos) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si contiene "data/" es candidato para el pack
|
|
||||||
if (filepath.find("data/") != std::string::npos) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getPackPath(const std::string& asset_path) -> std::string {
|
auto getPackPath(const std::string& asset_path) -> std::string {
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint> // Para uint8_t
|
||||||
|
#include <string> // Para string
|
||||||
|
#include <vector> // Para vector
|
||||||
|
|
||||||
|
// Helper functions para integrar ResourceLoader con el sistema existente
|
||||||
|
namespace ResourceHelper {
|
||||||
|
// Inicializa ResourceLoader (llamar al inicio del programa)
|
||||||
|
auto initializeResourceSystem(const std::string& pack_file = "resources.pack", bool enable_fallback = true) -> bool;
|
||||||
|
|
||||||
|
// Cierra ResourceLoader
|
||||||
|
void shutdownResourceSystem();
|
||||||
|
|
||||||
|
// Carga un archivo usando ResourceLoader o fallback a filesystem
|
||||||
|
auto loadFile(const std::string& filepath) -> std::vector<uint8_t>;
|
||||||
|
|
||||||
|
// Verifica si un archivo debería cargarse del pack vs filesystem
|
||||||
|
auto shouldUseResourcePack(const std::string& filepath) -> bool;
|
||||||
|
|
||||||
|
// Convierte ruta Asset a ruta relativa para ResourceLoader
|
||||||
|
auto getPackPath(const std::string& asset_path) -> std::string;
|
||||||
|
} // namespace ResourceHelper
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
#include "resource_loader.hpp"
|
#include "core/resources/resource_loader.hpp"
|
||||||
|
|
||||||
#include <algorithm> // Para replace
|
#include <algorithm> // Para replace
|
||||||
#include <filesystem> // Para exists, path, recursive_directory_iterator, directory_entry, relative
|
#include <filesystem> // Para exists, path, recursive_directory_iterator, directory_entry, relative
|
||||||
#include <fstream> // Para basic_ostream, basic_ifstream, operator<<, basic_ios, endl, ios, basic_istream, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
|
#include <fstream> // Para basic_ostream, basic_ifstream, operator<<, basic_ios, endl, ios, basic_istream, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
|
||||||
#include <iostream> // Para cerr, cout
|
#include <iostream> // Para cerr, cout
|
||||||
|
|
||||||
#include "resource_pack.hpp" // Para ResourcePack
|
#include "core/resources/resource_pack.hpp" // Para ResourcePack
|
||||||
|
|
||||||
std::unique_ptr<ResourceLoader> ResourceLoader::instance = nullptr;
|
std::unique_ptr<ResourceLoader> ResourceLoader::instance = nullptr;
|
||||||
|
|
||||||
ResourceLoader::ResourceLoader()
|
ResourceLoader::ResourceLoader() = default;
|
||||||
: resource_pack_(nullptr),
|
|
||||||
fallback_to_files_(true) {}
|
|
||||||
|
|
||||||
auto ResourceLoader::getInstance() -> ResourceLoader& {
|
auto ResourceLoader::getInstance() -> ResourceLoader& {
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
@@ -11,9 +11,9 @@ class ResourcePack;
|
|||||||
class ResourceLoader {
|
class ResourceLoader {
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<ResourceLoader> instance;
|
static std::unique_ptr<ResourceLoader> instance;
|
||||||
ResourcePack* resource_pack_;
|
ResourcePack* resource_pack_ = nullptr;
|
||||||
std::string pack_path_;
|
std::string pack_path_;
|
||||||
bool fallback_to_files_;
|
bool fallback_to_files_ = true;
|
||||||
|
|
||||||
ResourceLoader();
|
ResourceLoader();
|
||||||
|
|
||||||
@@ -1,27 +1,23 @@
|
|||||||
#include "resource_pack.hpp"
|
#include "core/resources/resource_pack.hpp"
|
||||||
|
|
||||||
#include <algorithm> // Para replace
|
#include <algorithm> // Para replace, ranges::all_of
|
||||||
#include <array> // Para array
|
#include <array> // Para array
|
||||||
#include <filesystem> // Para path, recursive_directory_iterator, directory_entry, exists, relative
|
#include <filesystem> // Para path, recursive_directory_iterator, directory_entry, exists, relative
|
||||||
#include <fstream> // Para basic_ifstream, basic_ostream, basic_ofstream, operator<<, basic_ios, basic_istream::read, basic_ostream::write, endl, ios, basic_istream, ifstream, operator|, basic_istream::seekg, basic_istream::tellg, ofstream, streamsize
|
#include <fstream> // Para basic_ifstream, basic_ostream, basic_ofstream, operator<<, basic_ios, basic_istream::read, basic_ostream::write, endl, ios, basic_istream, ifstream, operator|, basic_istream::seekg, basic_istream::tellg, ofstream, streamsize
|
||||||
#include <iostream> // Para cerr
|
#include <iostream> // Para cerr
|
||||||
|
#include <numeric> // Para accumulate
|
||||||
#include <utility> // Para pair
|
#include <utility> // Para pair
|
||||||
|
|
||||||
const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES__2024";
|
const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES__2024";
|
||||||
|
|
||||||
ResourcePack::ResourcePack()
|
ResourcePack::ResourcePack() = default;
|
||||||
: loaded_(false) {}
|
|
||||||
|
|
||||||
ResourcePack::~ResourcePack() {
|
ResourcePack::~ResourcePack() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t {
|
auto ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t {
|
||||||
uint32_t checksum = 0x12345678;
|
return std::accumulate(data.begin(), data.end(), static_cast<uint32_t>(0x12345678), [](uint32_t checksum, unsigned char i) { return ((checksum << 5) + checksum) + i; });
|
||||||
for (unsigned char i : data) {
|
|
||||||
checksum = ((checksum << 5) + checksum) + i;
|
|
||||||
}
|
|
||||||
return checksum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourcePack::encryptData(std::vector<uint8_t>& data, const std::string& key) {
|
void ResourcePack::encryptData(std::vector<uint8_t>& data, const std::string& key) {
|
||||||
@@ -159,23 +155,19 @@ auto ResourcePack::addFile(const std::string& filename, const std::string& filep
|
|||||||
auto ResourcePack::addDirectory(const std::string& directory) -> bool {
|
auto ResourcePack::addDirectory(const std::string& directory) -> bool {
|
||||||
if (!std::filesystem::exists(directory)) {
|
if (!std::filesystem::exists(directory)) {
|
||||||
std::cerr << "Error: Directory does not exist: " << directory << '\n';
|
std::cerr << "Error: Directory does not exist: " << directory << '\n';
|
||||||
return false; // NOLINT(readability-simplify-boolean-expr)
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(directory)) {
|
return std::ranges::all_of(std::filesystem::recursive_directory_iterator(directory),
|
||||||
if (entry.is_regular_file()) {
|
[this, &directory](const auto& entry) {
|
||||||
|
if (!entry.is_regular_file()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
std::string filepath = entry.path().string();
|
std::string filepath = entry.path().string();
|
||||||
std::string filename = std::filesystem::relative(entry.path(), directory).string();
|
std::string filename = std::filesystem::relative(entry.path(), directory).string();
|
||||||
|
|
||||||
std::ranges::replace(filename, '\\', '/');
|
std::ranges::replace(filename, '\\', '/');
|
||||||
|
return addFile(filename, filepath);
|
||||||
if (!addFile(filename, filepath)) {
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ResourcePack::getResource(const std::string& filename) -> std::vector<uint8_t> {
|
auto ResourcePack::getResource(const std::string& filename) -> std::vector<uint8_t> {
|
||||||
@@ -17,7 +17,7 @@ class ResourcePack {
|
|||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, ResourceEntry> resources_;
|
std::unordered_map<std::string, ResourceEntry> resources_;
|
||||||
std::vector<uint8_t> data_;
|
std::vector<uint8_t> data_;
|
||||||
bool loaded_;
|
bool loaded_ = false;
|
||||||
|
|
||||||
static auto calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t;
|
static auto calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t;
|
||||||
static void encryptData(std::vector<uint8_t>& data, const std::string& key);
|
static void encryptData(std::vector<uint8_t>& data, const std::string& key);
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "ui/notifier.hpp" // Para Notifier::Position
|
#include "game/ui/notifier.hpp" // Para Notifier::Position
|
||||||
|
|
||||||
namespace Defaults::Game {
|
namespace Defaults::Game {
|
||||||
constexpr float WIDTH = 320.0F;
|
constexpr float WIDTH = 320.0F;
|
||||||
@@ -177,8 +177,8 @@ namespace Defaults::Player::OutlineColor {
|
|||||||
|
|
||||||
namespace Defaults::Window {
|
namespace Defaults::Window {
|
||||||
constexpr const char* CAPTION = "© 2025 Coffee Crisis Arcade Edition — JailDesigner";
|
constexpr const char* CAPTION = "© 2025 Coffee Crisis Arcade Edition — JailDesigner";
|
||||||
constexpr int ZOOM = 2;
|
constexpr int ZOOM = 3;
|
||||||
constexpr int MAX_ZOOM = 2;
|
constexpr int MAX_ZOOM = 3;
|
||||||
} // namespace Defaults::Window
|
} // namespace Defaults::Window
|
||||||
|
|
||||||
namespace Defaults::Video {
|
namespace Defaults::Video {
|
||||||
@@ -188,28 +188,31 @@ namespace Defaults::Video {
|
|||||||
constexpr bool INTEGER_SCALE = true;
|
constexpr bool INTEGER_SCALE = true;
|
||||||
constexpr bool GPU_ACCELERATION = true;
|
constexpr bool GPU_ACCELERATION = true;
|
||||||
constexpr bool SHADER_ENABLED = false;
|
constexpr bool SHADER_ENABLED = false;
|
||||||
constexpr bool SUPERSAMPLING = false;
|
|
||||||
constexpr bool LINEAR_UPSCALE = false;
|
|
||||||
constexpr int DOWNSCALE_ALGO = 1;
|
|
||||||
} // namespace Defaults::Video
|
} // namespace Defaults::Video
|
||||||
|
|
||||||
namespace Defaults::Music {
|
namespace Defaults::Music {
|
||||||
constexpr bool ENABLED = true;
|
constexpr bool ENABLED = true;
|
||||||
constexpr int VOLUME = 100;
|
constexpr float VOLUME = 0.8F;
|
||||||
} // namespace Defaults::Music
|
} // namespace Defaults::Music
|
||||||
|
|
||||||
namespace Defaults::Sound {
|
namespace Defaults::Sound {
|
||||||
constexpr bool ENABLED = true;
|
constexpr bool ENABLED = true;
|
||||||
constexpr int VOLUME = 100;
|
constexpr float VOLUME = 1.0F;
|
||||||
} // namespace Defaults::Sound
|
} // namespace Defaults::Sound
|
||||||
|
|
||||||
namespace Defaults::Audio {
|
namespace Defaults::Audio {
|
||||||
constexpr bool ENABLED = true;
|
constexpr bool ENABLED = true;
|
||||||
constexpr int VOLUME = 100;
|
constexpr float VOLUME = 1.0F;
|
||||||
} // namespace Defaults::Audio
|
} // namespace Defaults::Audio
|
||||||
|
|
||||||
namespace Defaults::Settings {
|
namespace Defaults::Settings {
|
||||||
constexpr bool AUTOFIRE = true;
|
constexpr bool AUTOFIRE = true;
|
||||||
constexpr bool SHUTDOWN_ENABLED = false;
|
constexpr bool SHUTDOWN_ENABLED = false;
|
||||||
constexpr const char* PARAMS_FILE = "param_320x256.txt";
|
constexpr const char* PARAMS_PRESET = "arcade"; // Identificador intern del preset (correspon a data/config/<preset>.txt)
|
||||||
} // namespace Defaults::Settings
|
} // namespace Defaults::Settings
|
||||||
|
|
||||||
|
namespace Defaults::Loading {
|
||||||
|
constexpr bool SHOW = false;
|
||||||
|
constexpr bool SHOW_RESOURCE_NAME = true;
|
||||||
|
constexpr bool WAIT_FOR_INPUT = false;
|
||||||
|
} // namespace Defaults::Loading
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
#include "demo.hpp"
|
#include "core/system/demo.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_IOStream, SDL_IOFromConstMem, SDL_IOFromFile, SDL_ReadIO, SDL_WriteIO, SDL_CloseIO
|
#include <SDL3/SDL.h> // Para SDL_IOStream, SDL_IOFromConstMem, SDL_IOFromFile, SDL_ReadIO, SDL_WriteIO, SDL_CloseIO
|
||||||
|
|
||||||
#include <iostream> // Para std::cout
|
#include <iostream> // Para std::cout
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
|
|
||||||
#include "resource_helper.hpp" // Para ResourceHelper
|
#include "core/resources/resource_helper.hpp" // Para ResourceHelper
|
||||||
#include "utils.hpp" // Para getFileName
|
|
||||||
|
|
||||||
// Carga el fichero de datos para la demo
|
// Carga el fichero de datos para la demo
|
||||||
auto loadDemoDataFromFile(const std::string& file_path) -> DemoData {
|
auto loadDemoDataFromFile(const std::string& file_path) -> DemoData {
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
// IWYU pragma: no_include <bits/chrono.h>
|
// IWYU pragma: no_include <bits/chrono.h>
|
||||||
#include "director.hpp"
|
#include "core/system/director.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_SetLogPriority, SDL_LogCategory, SDL_LogPriority, SDL_Quit
|
#include <SDL3/SDL.h> // Para SDL_SetLogPriority, SDL_LogCategory, SDL_LogPriority, SDL_Quit
|
||||||
|
|
||||||
|
#include <cerrno> // Para errno
|
||||||
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
|
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
|
||||||
|
#include <cstring> // Para std::strerror
|
||||||
#include <ctime> // Para time
|
#include <ctime> // Para time
|
||||||
#include <fstream> // Para ifstream, ofstream
|
#include <fstream> // Para ifstream, ofstream
|
||||||
#include <iostream> // Para basic_ostream, operator<<, cerr
|
#include <iostream> // Para basic_ostream, operator<<, cerr
|
||||||
@@ -11,34 +13,74 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <string> // Para allocator, basic_string, char_traits, operator+, string, operator==
|
#include <string> // Para allocator, basic_string, char_traits, operator+, string, operator==
|
||||||
|
|
||||||
#include "asset.hpp" // Para Asset
|
#ifdef _WIN32
|
||||||
#include "audio.hpp" // Para Audio
|
#include <process.h> // Per _execv
|
||||||
#include "external/fkyaml_node.hpp" // Para fkyaml::node
|
#else
|
||||||
#include "global_events.hpp" // Para GlobalEvents::handle
|
#include <unistd.h> // Per execv
|
||||||
#include "input.hpp" // Para Input
|
#endif
|
||||||
#include "lang.hpp" // Para setLanguage
|
|
||||||
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable
|
#include "core/audio/audio.hpp" // Para Audio
|
||||||
#include "options.hpp" // Para Settings, loadFromFile, saveToFile, settings, setConfigFile, setControllersFile
|
#include "core/input/input.hpp" // Para Input
|
||||||
#include "param.hpp" // Para loadParamsFromFile
|
#include "core/locale/lang.hpp" // Para setLanguage
|
||||||
#include "player.hpp" // Para Player
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "resource.hpp" // Para Resource
|
#include "core/resources/asset.hpp" // Para Asset
|
||||||
#include "resource_helper.hpp" // Para initializeResourceSystem
|
#include "core/resources/resource.hpp" // Para Resource
|
||||||
#include "screen.hpp" // Para Screen
|
#include "core/resources/resource_helper.hpp" // Para initializeResourceSystem
|
||||||
#include "section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode
|
#include "core/system/global_events.hpp" // Para GlobalEvents::handle
|
||||||
#include "sections/credits.hpp" // Para Credits
|
#include "core/system/section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode
|
||||||
#include "sections/game.hpp" // Para Game
|
#include "core/system/shutdown.hpp" // Para resultToString, shutdownSystem, ShutdownResult
|
||||||
#include "sections/hiscore_table.hpp" // Para HiScoreTable
|
#include "core/system/system_utils.hpp" // Para createApplicationFolder, resultToString, Result
|
||||||
#include "sections/instructions.hpp" // Para Instructions
|
#include "external/fkyaml_node.hpp" // Para fkyaml::node
|
||||||
#include "sections/intro.hpp" // Para Intro
|
#include "game/entities/player.hpp" // Para Player
|
||||||
#include "sections/logo.hpp" // Para Logo
|
#include "game/gameplay/manage_hiscore_table.hpp" // Para ManageHiScoreTable
|
||||||
#include "sections/title.hpp" // Para Title
|
#include "game/options.hpp" // Para Settings, loadFromFile, saveToFile, settings, setConfigFile, setControllersFile
|
||||||
#include "shutdown.hpp" // Para resultToString, shutdownSystem, ShutdownResult
|
#include "game/scenes/credits.hpp" // Para Credits
|
||||||
#include "system_utils.hpp" // Para createApplicationFolder, resultToString, Result
|
#include "game/scenes/game.hpp" // Para Game
|
||||||
#include "ui/notifier.hpp" // Para Notifier
|
#include "game/scenes/hiscore_table.hpp" // Para HiScoreTable
|
||||||
#include "ui/service_menu.hpp" // Para ServiceMenu
|
#include "game/scenes/instructions.hpp" // Para Instructions
|
||||||
|
#include "game/scenes/intro.hpp" // Para Intro
|
||||||
|
#include "game/scenes/logo.hpp" // Para Logo
|
||||||
|
#include "game/scenes/preload.hpp" // Para Preload
|
||||||
|
#include "game/scenes/title.hpp" // Para Title
|
||||||
|
#include "game/ui/notifier.hpp" // Para Notifier
|
||||||
|
#include "game/ui/service_menu.hpp" // Para ServiceMenu
|
||||||
|
#include "utils/param.hpp" // Para loadParamsFromFile
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Llig un camp opcional d'un YAML cap a `dest`. Si no existeix, no toca `dest`.
|
||||||
|
// Si existeix però el tipus no encaixa, deixa el valor per defecte i avisa per stderr
|
||||||
|
// (un debug.yaml mal escrit no ha de tombar l'arrencada, però l'usuari ha de saber-ho).
|
||||||
|
template <typename T>
|
||||||
|
void loadYamlField(const fkyaml::node& yaml, const std::string& key, T& dest) {
|
||||||
|
if (!yaml.contains(key)) { return; }
|
||||||
|
try {
|
||||||
|
dest = yaml[key].get_value<T>();
|
||||||
|
} catch (...) {
|
||||||
|
std::cerr << "debug.yaml: valor invàlid per a '" << key << "', es manté el valor per defecte\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parseInitialSection(const std::string& value) -> Section::Name {
|
||||||
|
if (value == "logo") { return Section::Name::LOGO; }
|
||||||
|
if (value == "intro") { return Section::Name::INTRO; }
|
||||||
|
if (value == "title") { return Section::Name::TITLE; }
|
||||||
|
if (value == "credits") { return Section::Name::CREDITS; }
|
||||||
|
if (value == "instructions") { return Section::Name::INSTRUCTIONS; }
|
||||||
|
if (value == "hiscore") { return Section::Name::HI_SCORE_TABLE; }
|
||||||
|
return Section::Name::GAME; // "game" i qualsevol valor desconegut
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parseInitialOptions(const std::string& value) -> Section::Options {
|
||||||
|
if (value == "none") { return Section::Options::NONE; }
|
||||||
|
if (value == "2p") { return Section::Options::GAME_PLAY_2P; }
|
||||||
|
if (value == "both") { return Section::Options::GAME_PLAY_BOTH; }
|
||||||
|
return Section::Options::GAME_PLAY_1P; // "1p" i qualsevol valor desconegut
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Director::Director() {
|
Director::Director(int /*argc*/, char** argv)
|
||||||
|
: argv_(argv) {
|
||||||
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO;
|
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO;
|
||||||
|
|
||||||
// Establece el nivel de prioridad de la categoría de registro
|
// Establece el nivel de prioridad de la categoría de registro
|
||||||
@@ -51,8 +93,14 @@ Director::Director() {
|
|||||||
std::cout << "Game start\n";
|
std::cout << "Game start\n";
|
||||||
|
|
||||||
// Obtener la ruta del ejecutable desde SDL
|
// Obtener la ruta del ejecutable desde SDL
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
// En Emscripten los assets viven en la raíz del MEMFS virtual (/data, /config),
|
||||||
|
// preloaded vía --preload-file en el linker. No hay ruta de ejecutable.
|
||||||
|
executable_path_ = "";
|
||||||
|
#else
|
||||||
const char* base_path = SDL_GetBasePath();
|
const char* base_path = SDL_GetBasePath();
|
||||||
executable_path_ = (base_path != nullptr) ? base_path : "";
|
executable_path_ = (base_path != nullptr) ? base_path : "";
|
||||||
|
#endif
|
||||||
|
|
||||||
// Crea la carpeta del sistema donde guardar los datos persistentes
|
// Crea la carpeta del sistema donde guardar los datos persistentes
|
||||||
createSystemFolder("jailgames");
|
createSystemFolder("jailgames");
|
||||||
@@ -92,17 +140,19 @@ void Director::init() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Inicializar sistema de recursos con o sin fallback según el tipo de build
|
// Inicializar sistema de recursos con o sin fallback según el tipo de build
|
||||||
#ifdef RELEASE_BUILD
|
#if defined(RELEASE_BUILD) && !defined(__EMSCRIPTEN__)
|
||||||
// Release: Sin fallback - Solo resources.pack (estricto)
|
// Release nativo: Sin fallback - Solo resources.pack (estricto)
|
||||||
ResourceHelper::initializeResourceSystem(pack_path, false);
|
ResourceHelper::initializeResourceSystem(pack_path, false);
|
||||||
#else
|
#else
|
||||||
// Desarrollo: Con fallback - Puede usar data/ si falta el pack (flexible)
|
// Desarrollo o Emscripten: Con fallback - carga desde filesystem/MEMFS
|
||||||
ResourceHelper::initializeResourceSystem(pack_path, true);
|
ResourceHelper::initializeResourceSystem(pack_path, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
loadAssets(); // Crea el índice de archivos
|
loadAssets(); // Crea el índice de archivos
|
||||||
|
|
||||||
Input::init(Asset::get()->getPath("gamecontrollerdb.txt"), Asset::get()->getPath("controllers.json")); // Carga configuración de controles
|
// gamecontrollerdb.txt no pot anar al pack (SDL_AddGamepadMappingsFromFile només llegeix del FS).
|
||||||
|
// Sempre viu al costat del binari, fora del índex d'assets.
|
||||||
|
Input::init(executable_path_ + "gamecontrollerdb.txt", Asset::get()->getPath("controllers.json")); // Carga configuración de controles
|
||||||
|
|
||||||
Options::setConfigFile(Asset::get()->getPath("config.yaml")); // Establece el fichero de configuración
|
Options::setConfigFile(Asset::get()->getPath("config.yaml")); // Establece el fichero de configuración
|
||||||
Options::setControllersFile(Asset::get()->getPath("controllers.json")); // Establece el fichero de configuración de mandos
|
Options::setControllersFile(Asset::get()->getPath("controllers.json")); // Establece el fichero de configuración de mandos
|
||||||
@@ -111,8 +161,19 @@ void Director::init() {
|
|||||||
Options::loadFromFile(); // Carga el archivo de configuración
|
Options::loadFromFile(); // Carga el archivo de configuración
|
||||||
Options::loadPostFXFromFile(); // Carga los presets PostFX
|
Options::loadPostFXFromFile(); // Carga los presets PostFX
|
||||||
Options::loadCrtPiFromFile(); // Carga los presets CrtPi
|
Options::loadCrtPiFromFile(); // Carga los presets CrtPi
|
||||||
loadParams(); // Carga los parámetros del programa
|
|
||||||
loadScoreFile(); // Carga el archivo de puntuaciones
|
#ifdef __EMSCRIPTEN__
|
||||||
|
// En la versión web el navegador gestiona la ventana: ventana (no
|
||||||
|
// fullscreen — el canvas ya marca el área), integer scale para píxeles nítidos.
|
||||||
|
Options::window.zoom = 3;
|
||||||
|
Options::video.fullscreen = false;
|
||||||
|
Options::video.integer_scale = true;
|
||||||
|
// Precarga silenciosa: pantalla negra mientras el .data termina de descargarse.
|
||||||
|
Options::loading.show = false;
|
||||||
|
Options::loading.wait_for_input = false;
|
||||||
|
#endif
|
||||||
|
loadParams(); // Carga los parámetros del programa
|
||||||
|
loadScoreFile(); // Carga el archivo de puntuaciones
|
||||||
|
|
||||||
// Inicialización de subsistemas principales
|
// Inicialización de subsistemas principales
|
||||||
Lang::setLanguage(Options::settings.language); // Carga el archivo de idioma
|
Lang::setLanguage(Options::settings.language); // Carga el archivo de idioma
|
||||||
@@ -126,13 +187,44 @@ void Director::init() {
|
|||||||
#else
|
#else
|
||||||
Resource::init(Resource::LoadingMode::PRELOAD);
|
Resource::init(Resource::LoadingMode::PRELOAD);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (Resource::get()->getLoadingMode() == Resource::LoadingMode::PRELOAD) {
|
||||||
|
// Guarda la sección destino (la que fijó loadDebugConfig o el default)
|
||||||
|
// y redirige el arranque a la escena PRELOAD hasta que loadStep termine.
|
||||||
|
Section::post_preload = Section::name;
|
||||||
|
Section::name = Section::Name::PRELOAD;
|
||||||
|
Resource::get()->beginLoad();
|
||||||
|
} else {
|
||||||
|
// LAZY_LOAD: el constructor de Resource ya cargó lo esencial síncronamente;
|
||||||
|
// no hay fase de preload, pasamos directamente a post-boot.
|
||||||
|
finishBoot();
|
||||||
|
boot_loading_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceMenu/Notifier/getSingletons se mueven a finishBoot() — dependen
|
||||||
|
// de Resource y se inicializan al terminar la carga incremental.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicializaciones que dependen del Resource cargado. Se llama desde iterate()
|
||||||
|
// cuando Resource::loadStep() devuelve true, con la ventana y el bucle vivos.
|
||||||
|
void Director::finishBoot() {
|
||||||
ServiceMenu::init(); // Inicializa el menú de servicio
|
ServiceMenu::init(); // Inicializa el menú de servicio
|
||||||
Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones
|
Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones
|
||||||
Screen::get()->getSingletons(); // Obtiene los punteros al resto de singletones
|
Screen::get()->getSingletons(); // Obtiene los punteros al resto de singletones
|
||||||
|
|
||||||
|
// Restaura el vsync a la preferencia del usuario (beginLoad lo había puesto a false)
|
||||||
|
Screen::get()->setVSync(Options::video.vsync);
|
||||||
|
|
||||||
|
// Si NO estamos en modo "wait for input", transiciona ya al destino.
|
||||||
|
// Si wait_for_input está activo (y la pantalla es visible), nos quedamos
|
||||||
|
// en PRELOAD hasta que el usuario pulse tecla/botón.
|
||||||
|
if (!(Options::loading.show && Options::loading.wait_for_input)) {
|
||||||
|
Section::name = Section::post_preload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cierra todo y libera recursos del sistema y de los singletons
|
// Allibera tots els singletons i SDL (compartit entre close() i relaunch())
|
||||||
void Director::close() {
|
void Director::shutdownSubsystems() {
|
||||||
// Guarda las opciones actuales en el archivo de configuración
|
// Guarda las opciones actuales en el archivo de configuración
|
||||||
Options::saveToFile();
|
Options::saveToFile();
|
||||||
|
|
||||||
@@ -145,22 +237,47 @@ void Director::close() {
|
|||||||
Screen::destroy(); // Libera el sistema de pantalla y renderizado
|
Screen::destroy(); // Libera el sistema de pantalla y renderizado
|
||||||
Asset::destroy(); // Libera el gestor de archivos
|
Asset::destroy(); // Libera el gestor de archivos
|
||||||
|
|
||||||
std::cout << "\nBye!\n";
|
|
||||||
|
|
||||||
// Libera todos los recursos de SDL
|
// Libera todos los recursos de SDL
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cierra todo y libera recursos del sistema y de los singletons
|
||||||
|
void Director::close() {
|
||||||
|
shutdownSubsystems();
|
||||||
|
std::cout << "\nBye!\n";
|
||||||
// Apaga el sistema
|
// Apaga el sistema
|
||||||
shutdownSystem(Section::options == Section::Options::SHUTDOWN);
|
shutdownSystem(Section::options == Section::Options::SHUTDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reemplaça el procés actual per ell mateix (reinici en calent). En cas d'èxit no torna.
|
||||||
|
// Si no es pot reiniciar (Emscripten, argv invàlid), retorna i el caller fa el reset clàssic.
|
||||||
|
void Director::relaunch() const {
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
// Al navegador el reinici real seria location.reload(); aquí caiem al reset intern.
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
if (argv_ == nullptr || argv_[0] == nullptr) { return; }
|
||||||
|
std::cout << "Relaunching " << argv_[0] << "...\n";
|
||||||
|
shutdownSubsystems();
|
||||||
|
#ifdef _WIN32
|
||||||
|
_execv(argv_[0], argv_);
|
||||||
|
#else
|
||||||
|
execv(argv_[0], argv_);
|
||||||
|
#endif
|
||||||
|
// Si arribem aquí, execv ha fallat. Tots els subsistemes ja estan destruïts: no
|
||||||
|
// podem reprendre el bucle. Sortim amb error.
|
||||||
|
std::cerr << "Relaunch failed: " << std::strerror(errno) << "\n";
|
||||||
|
std::exit(EXIT_FAILURE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Carga los parametros
|
// Carga los parametros
|
||||||
void Director::loadParams() {
|
void Director::loadParams() {
|
||||||
// Carga los parametros para configurar el juego
|
// Carga los parametros para configurar el juego
|
||||||
#ifdef ANBERNIC
|
#ifdef ANBERNIC
|
||||||
const std::string PARAM_FILE_PATH = Asset::get()->getPath("param_320x240.txt");
|
const std::string PARAM_FILE_PATH = Asset::get()->getPath("classic.txt");
|
||||||
#else
|
#else
|
||||||
const std::string PARAM_FILE_PATH = Asset::get()->getPath(Options::settings.params_file);
|
const std::string PARAM_FILE_PATH = Asset::get()->getPath(Options::settings.params_preset + ".txt");
|
||||||
#endif
|
#endif
|
||||||
loadParamsFromFile(PARAM_FILE_PATH);
|
loadParamsFromFile(PARAM_FILE_PATH);
|
||||||
}
|
}
|
||||||
@@ -175,7 +292,7 @@ void Director::loadScoreFile() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carga el indice de ficheros desde un fichero
|
// Carga el indice de ficheros desde el pack (o filesystem como fallback)
|
||||||
void Director::loadAssets() {
|
void Director::loadAssets() {
|
||||||
#ifdef MACOS_BUNDLE
|
#ifdef MACOS_BUNDLE
|
||||||
const std::string PREFIX = "/../Resources";
|
const std::string PREFIX = "/../Resources";
|
||||||
@@ -183,9 +300,13 @@ void Director::loadAssets() {
|
|||||||
const std::string PREFIX;
|
const std::string PREFIX;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Cargar la configuración de assets (también aplicar el prefijo al archivo de configuración)
|
// El índice ahora vive dins el pack a "config/assets.txt" (ResourceHelper li trau el "data/" prefix).
|
||||||
std::string config_path = executable_path_ + PREFIX + "/config/assets.txt";
|
// ResourceHelper::loadFile fa fallback automàtic al filesystem si el pack no està o no conté el fitxer.
|
||||||
Asset::get()->loadFromFile(config_path, PREFIX, system_folder_);
|
auto buffer = ResourceHelper::loadFile("/data/config/assets.txt");
|
||||||
|
if (buffer.empty()) {
|
||||||
|
throw std::runtime_error("No s'ha pogut carregar l'índex d'assets (data/config/assets.txt)");
|
||||||
|
}
|
||||||
|
Asset::get()->loadFromBuffer(buffer, PREFIX, system_folder_);
|
||||||
|
|
||||||
// Si falta algun fichero, sale del programa
|
// Si falta algun fichero, sale del programa
|
||||||
if (!Asset::get()->check()) {
|
if (!Asset::get()->check()) {
|
||||||
@@ -216,6 +337,8 @@ void Director::loadDebugConfig() {
|
|||||||
out << "initial_stage: 0\n";
|
out << "initial_stage: 0\n";
|
||||||
out << "show_render_info: true\n";
|
out << "show_render_info: true\n";
|
||||||
out << "resource_loading: preload\n";
|
out << "resource_loading: preload\n";
|
||||||
|
out << "autoplay: false\n";
|
||||||
|
out << "invincibility: false\n";
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
// Usar defaults de DebugConfig
|
// Usar defaults de DebugConfig
|
||||||
@@ -224,68 +347,20 @@ void Director::loadDebugConfig() {
|
|||||||
file.close();
|
file.close();
|
||||||
try {
|
try {
|
||||||
auto yaml = fkyaml::node::deserialize(content);
|
auto yaml = fkyaml::node::deserialize(content);
|
||||||
if (yaml.contains("initial_section")) {
|
loadYamlField(yaml, "initial_section", debug_config.initial_section);
|
||||||
try {
|
loadYamlField(yaml, "initial_options", debug_config.initial_options);
|
||||||
debug_config.initial_section = yaml["initial_section"].get_value<std::string>();
|
loadYamlField(yaml, "initial_stage", debug_config.initial_stage);
|
||||||
} catch (...) {}
|
loadYamlField(yaml, "show_render_info", debug_config.show_render_info);
|
||||||
}
|
loadYamlField(yaml, "resource_loading", debug_config.resource_loading);
|
||||||
if (yaml.contains("initial_options")) {
|
loadYamlField(yaml, "autoplay", debug_config.autoplay);
|
||||||
try {
|
loadYamlField(yaml, "invincibility", debug_config.invincibility);
|
||||||
debug_config.initial_options = yaml["initial_options"].get_value<std::string>();
|
|
||||||
} catch (...) {}
|
|
||||||
}
|
|
||||||
if (yaml.contains("initial_stage")) {
|
|
||||||
try {
|
|
||||||
debug_config.initial_stage = yaml["initial_stage"].get_value<int>();
|
|
||||||
} catch (...) {}
|
|
||||||
}
|
|
||||||
if (yaml.contains("show_render_info")) {
|
|
||||||
try {
|
|
||||||
debug_config.show_render_info = yaml["show_render_info"].get_value<bool>();
|
|
||||||
} catch (...) {}
|
|
||||||
}
|
|
||||||
if (yaml.contains("resource_loading")) {
|
|
||||||
try {
|
|
||||||
debug_config.resource_loading = yaml["resource_loading"].get_value<std::string>();
|
|
||||||
} catch (...) {}
|
|
||||||
}
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
std::cout << "Error parsing debug.yaml, using defaults" << '\n';
|
std::cout << "Error parsing debug.yaml, using defaults" << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mapear strings a enums
|
Section::name = parseInitialSection(debug_config.initial_section);
|
||||||
const auto& sec = debug_config.initial_section;
|
Section::options = parseInitialOptions(debug_config.initial_options);
|
||||||
if (sec == "logo") {
|
|
||||||
Section::name = Section::Name::LOGO;
|
|
||||||
} else if (sec == "intro") {
|
|
||||||
Section::name = Section::Name::INTRO;
|
|
||||||
} else if (sec == "title") {
|
|
||||||
Section::name = Section::Name::TITLE;
|
|
||||||
} else if (sec == "game") {
|
|
||||||
Section::name = Section::Name::GAME;
|
|
||||||
} else if (sec == "credits") {
|
|
||||||
Section::name = Section::Name::CREDITS;
|
|
||||||
} else if (sec == "instructions") {
|
|
||||||
Section::name = Section::Name::INSTRUCTIONS;
|
|
||||||
} else if (sec == "hiscore") {
|
|
||||||
Section::name = Section::Name::HI_SCORE_TABLE;
|
|
||||||
} else {
|
|
||||||
Section::name = Section::Name::GAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& opt = debug_config.initial_options;
|
|
||||||
if (opt == "none") {
|
|
||||||
Section::options = Section::Options::NONE;
|
|
||||||
} else if (opt == "1p") {
|
|
||||||
Section::options = Section::Options::GAME_PLAY_1P;
|
|
||||||
} else if (opt == "2p") {
|
|
||||||
Section::options = Section::Options::GAME_PLAY_2P;
|
|
||||||
} else if (opt == "both") {
|
|
||||||
Section::options = Section::Options::GAME_PLAY_BOTH;
|
|
||||||
} else {
|
|
||||||
Section::options = Section::Options::GAME_PLAY_1P;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea la carpeta del sistema donde guardar datos
|
// Crea la carpeta del sistema donde guardar datos
|
||||||
@@ -301,6 +376,7 @@ void Director::createSystemFolder(const std::string& folder) {
|
|||||||
|
|
||||||
// Libera todos los unique_ptr de sección (solo uno tiene propiedad a la vez)
|
// Libera todos los unique_ptr de sección (solo uno tiene propiedad a la vez)
|
||||||
void Director::resetActiveSection() {
|
void Director::resetActiveSection() {
|
||||||
|
preload_.reset();
|
||||||
logo_.reset();
|
logo_.reset();
|
||||||
intro_.reset();
|
intro_.reset();
|
||||||
title_.reset();
|
title_.reset();
|
||||||
@@ -312,9 +388,11 @@ void Director::resetActiveSection() {
|
|||||||
|
|
||||||
// Destruye la sección anterior y construye la nueva cuando Section::name cambia
|
// Destruye la sección anterior y construye la nueva cuando Section::name cambia
|
||||||
void Director::handleSectionTransition() {
|
void Director::handleSectionTransition() {
|
||||||
// RESET: recarga recursos y vuelve a LOGO (el propio reset() cambia Section::name)
|
// RESET: intenta reinici real via execv; si no es pot (Emscripten o argv invàlid),
|
||||||
|
// cau al reset intern (recarrega recursos i torna a LOGO, sense recrear Screen/Params).
|
||||||
if (Section::name == Section::Name::RESET) {
|
if (Section::name == Section::Name::RESET) {
|
||||||
resetActiveSection(); // libera recursos actuales antes del reload
|
relaunch(); // En èxit no torna; el binari es reemplaça
|
||||||
|
resetActiveSection(); // Fallback: libera recursos actuales antes del reload
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,6 +405,10 @@ void Director::handleSectionTransition() {
|
|||||||
|
|
||||||
// Construye la nueva
|
// Construye la nueva
|
||||||
switch (Section::name) {
|
switch (Section::name) {
|
||||||
|
case Section::Name::PRELOAD:
|
||||||
|
preload_ = std::make_unique<Preload>();
|
||||||
|
break;
|
||||||
|
|
||||||
case Section::Name::LOGO:
|
case Section::Name::LOGO:
|
||||||
logo_ = std::make_unique<Logo>();
|
logo_ = std::make_unique<Logo>();
|
||||||
break;
|
break;
|
||||||
@@ -409,11 +491,32 @@ auto Director::iterate() -> SDL_AppResult {
|
|||||||
return SDL_APP_SUCCESS;
|
return SDL_APP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fase de boot: carga incremental frame a frame con presupuesto de 50ms.
|
||||||
|
// Durante esta fase la escena activa es Preload (una barra de progreso).
|
||||||
|
if (boot_loading_) {
|
||||||
|
try {
|
||||||
|
if (Resource::get()->loadStep(50 /*ms*/)) {
|
||||||
|
finishBoot();
|
||||||
|
boot_loading_ = false;
|
||||||
|
// Los SDL_EVENT_GAMEPAD_ADDED iniciales ya los ha drenado la rama
|
||||||
|
// durante la carga: marcamos startup completo ahora para que los
|
||||||
|
// ADDED/REMOVED posteriores sí generen notificación.
|
||||||
|
GlobalEvents::markStartupComplete();
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Fatal error during resource load: " << e.what() << '\n';
|
||||||
|
Section::name = Section::Name::QUIT;
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Gestiona las transiciones entre secciones (destruye la anterior y construye la nueva)
|
// Gestiona las transiciones entre secciones (destruye la anterior y construye la nueva)
|
||||||
handleSectionTransition();
|
handleSectionTransition();
|
||||||
|
|
||||||
// Ejecuta un frame de la sección activa
|
// Ejecuta un frame de la sección activa
|
||||||
if (logo_) {
|
if (preload_) {
|
||||||
|
Preload::iterate();
|
||||||
|
} else if (logo_) {
|
||||||
logo_->iterate();
|
logo_->iterate();
|
||||||
} else if (intro_) {
|
} else if (intro_) {
|
||||||
intro_->iterate();
|
intro_->iterate();
|
||||||
@@ -433,12 +536,14 @@ auto Director::iterate() -> SDL_AppResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Procesa un evento SDL (llamado desde SDL_AppEvent)
|
// Procesa un evento SDL (llamado desde SDL_AppEvent)
|
||||||
auto Director::handleEvent(SDL_Event& event) -> SDL_AppResult {
|
auto Director::handleEvent(const SDL_Event& event) -> SDL_AppResult {
|
||||||
// Eventos globales (SDL_EVENT_QUIT, resize, render target reset, hotplug, service menu, ratón)
|
// Eventos globales (SDL_EVENT_QUIT, resize, render target reset, hotplug, service menu, ratón)
|
||||||
GlobalEvents::handle(event);
|
GlobalEvents::handle(event);
|
||||||
|
|
||||||
// Reenvía a la sección activa
|
// Reenvía a la sección activa
|
||||||
if (logo_) {
|
if (preload_) {
|
||||||
|
Preload::handleEvent(event);
|
||||||
|
} else if (logo_) {
|
||||||
logo_->handleEvent(event);
|
logo_->handleEvent(event);
|
||||||
} else if (intro_) {
|
} else if (intro_) {
|
||||||
intro_->handleEvent(event);
|
intro_->handleEvent(event);
|
||||||
@@ -2,16 +2,18 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_AppResult, SDL_Event
|
#include <SDL3/SDL.h> // Para SDL_AppResult, SDL_Event
|
||||||
|
|
||||||
#include <memory> // Para unique_ptr
|
#include <cstdint> // Para std::uint8_t
|
||||||
#include <string> // Para string
|
#include <memory> // Para unique_ptr
|
||||||
|
#include <string> // Para string
|
||||||
|
|
||||||
#include "section.hpp" // Para Section::Name
|
#include "core/system/section.hpp" // Para Section::Name
|
||||||
|
|
||||||
namespace Lang {
|
namespace Lang {
|
||||||
enum class Code : int;
|
enum class Code : std::uint8_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declaraciones adelantadas de las secciones
|
// Declaraciones adelantadas de las secciones
|
||||||
|
class Preload;
|
||||||
class Logo;
|
class Logo;
|
||||||
class Intro;
|
class Intro;
|
||||||
class Title;
|
class Title;
|
||||||
@@ -24,12 +26,12 @@ class Credits;
|
|||||||
class Director {
|
class Director {
|
||||||
public:
|
public:
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
Director();
|
Director(int argc, char** argv);
|
||||||
~Director();
|
~Director();
|
||||||
|
|
||||||
// --- Callbacks para SDL_MAIN_USE_CALLBACKS ---
|
// --- Callbacks para SDL_MAIN_USE_CALLBACKS ---
|
||||||
auto iterate() -> SDL_AppResult; // Avanza un frame de la sección activa
|
auto iterate() -> SDL_AppResult; // Avanza un frame de la sección activa
|
||||||
auto handleEvent(SDL_Event& event) -> SDL_AppResult; // Procesa un evento SDL
|
auto handleEvent(const SDL_Event& event) -> SDL_AppResult; // Procesa un evento SDL
|
||||||
|
|
||||||
// --- Debug config (accesible desde otras clases) ---
|
// --- Debug config (accesible desde otras clases) ---
|
||||||
struct DebugConfig {
|
struct DebugConfig {
|
||||||
@@ -38,6 +40,8 @@ class Director {
|
|||||||
int initial_stage = 0;
|
int initial_stage = 0;
|
||||||
bool show_render_info = true;
|
bool show_render_info = true;
|
||||||
std::string resource_loading;
|
std::string resource_loading;
|
||||||
|
bool autoplay = false;
|
||||||
|
bool invincibility = false;
|
||||||
|
|
||||||
DebugConfig()
|
DebugConfig()
|
||||||
: initial_section("game"),
|
: initial_section("game"),
|
||||||
@@ -50,8 +54,10 @@ class Director {
|
|||||||
// --- Variables internas ---
|
// --- Variables internas ---
|
||||||
std::string executable_path_; // Ruta del ejecutable
|
std::string executable_path_; // Ruta del ejecutable
|
||||||
std::string system_folder_; // Carpeta del sistema para almacenar datos
|
std::string system_folder_; // Carpeta del sistema para almacenar datos
|
||||||
|
char** argv_ = nullptr; // argv original; usat per relaunch() (execv)
|
||||||
|
|
||||||
// --- Sección activa (una y sólo una viva en cada momento) ---
|
// --- Sección activa (una y sólo una viva en cada momento) ---
|
||||||
|
std::unique_ptr<Preload> preload_;
|
||||||
std::unique_ptr<Logo> logo_;
|
std::unique_ptr<Logo> logo_;
|
||||||
std::unique_ptr<Intro> intro_;
|
std::unique_ptr<Intro> intro_;
|
||||||
std::unique_ptr<Title> title_;
|
std::unique_ptr<Title> title_;
|
||||||
@@ -61,9 +67,15 @@ class Director {
|
|||||||
std::unique_ptr<Credits> credits_;
|
std::unique_ptr<Credits> credits_;
|
||||||
Section::Name last_built_section_name_ = Section::Name::RESET;
|
Section::Name last_built_section_name_ = Section::Name::RESET;
|
||||||
|
|
||||||
|
// --- Fase de arranque no bloqueante ---
|
||||||
|
bool boot_loading_ = true; // True mientras Resource::loadStep está cargando incremental
|
||||||
|
|
||||||
// --- Inicialización y cierre del sistema ---
|
// --- Inicialización y cierre del sistema ---
|
||||||
void init(); // Inicializa la aplicación
|
void init(); // Inicializa la aplicación (pre-boot)
|
||||||
static void close(); // Cierra y libera recursos
|
static void finishBoot(); // Post-boot: inicializa lo que depende de recursos cargados
|
||||||
|
static void shutdownSubsystems(); // Allibera singletons i SDL (sense apagar el sistema)
|
||||||
|
static void close(); // Cierra y libera recursos
|
||||||
|
void relaunch() const; // Reemplaça el procés via execv (fallback silenciós si no es pot)
|
||||||
|
|
||||||
// --- Configuración inicial ---
|
// --- Configuración inicial ---
|
||||||
static void loadParams(); // Carga los parámetros del programa
|
static void loadParams(); // Carga los parámetros del programa
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "global_events.hpp"
|
#include "core/system/global_events.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_EventType, SDL_Event, SDL_LogInfo, SDL_LogCategory
|
#include <SDL3/SDL.h> // Para SDL_EventType, SDL_Event, SDL_LogInfo, SDL_LogCategory
|
||||||
|
|
||||||
@@ -7,22 +7,42 @@
|
|||||||
#include <string> // Para allocator, operator+, string
|
#include <string> // Para allocator, operator+, string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "input.hpp" // Para Input
|
#include "core/input/input.hpp" // Para Input
|
||||||
#include "lang.hpp" // Para getText
|
#include "core/input/mouse.hpp" // Para handleEvent
|
||||||
#include "mouse.hpp" // Para handleEvent
|
#include "core/locale/lang.hpp" // Para getText
|
||||||
#include "options.hpp" // Para GamepadManager, gamepad_manager
|
#include "core/rendering/screen.hpp" // Para Screen
|
||||||
#include "screen.hpp" // Para Screen
|
#include "core/system/section.hpp" // Para Name, Options, name, options
|
||||||
#include "section.hpp" // Para Name, Options, name, options
|
#include "game/options.hpp" // Para GamepadManager, gamepad_manager
|
||||||
#include "ui/notifier.hpp" // Para Notifier
|
#include "game/ui/notifier.hpp" // Para Notifier
|
||||||
#include "ui/service_menu.hpp" // Para ServiceMenu
|
#include "game/ui/service_menu.hpp" // Para ServiceMenu
|
||||||
|
|
||||||
namespace GlobalEvents {
|
namespace GlobalEvents {
|
||||||
|
namespace {
|
||||||
|
// Durante el arranque se drenan los SDL_EVENT_GAMEPAD_ADDED de los mandos
|
||||||
|
// ya conectados. Esos eventos sí deben reasignar mandos a jugadores, pero
|
||||||
|
// no deben mostrar notificación: no son hotplug, son detección inicial.
|
||||||
|
bool startup_in_progress = true;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// Comprueba los eventos de Input y muestra notificaciones
|
// Comprueba los eventos de Input y muestra notificaciones
|
||||||
void handleInputEvents(const SDL_Event& event) {
|
void handleInputEvents(const SDL_Event& event) {
|
||||||
|
if (event.type != SDL_EVENT_GAMEPAD_ADDED && event.type != SDL_EVENT_GAMEPAD_REMOVED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static auto* input_ = Input::get();
|
static auto* input_ = Input::get();
|
||||||
auto message = input_->handleEvent(event);
|
auto message = input_->handleEvent(event);
|
||||||
|
|
||||||
if (message.empty()) {
|
// Reasignar siempre: tanto en arranque como en hotplug en caliente.
|
||||||
|
Options::gamepad_manager.assignAndLinkGamepads();
|
||||||
|
Options::gamepad_manager.resyncGamepadsWithPlayers();
|
||||||
|
|
||||||
|
// Durante el preload ServiceMenu aún no existe: solo refresca si está vivo.
|
||||||
|
if (ServiceMenu::get() != nullptr) {
|
||||||
|
ServiceMenu::get()->refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startup_in_progress || message.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,10 +55,15 @@ namespace GlobalEvents {
|
|||||||
message.replace(pos, std::string(" DISCONNECTED").length(), " " + Lang::getText("[NOTIFICATIONS] DISCONNECTED"));
|
message.replace(pos, std::string(" DISCONNECTED").length(), " " + Lang::getText("[NOTIFICATIONS] DISCONNECTED"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Options::gamepad_manager.assignAndLinkGamepads();
|
// Notifier también puede no existir todavía si la notificación se
|
||||||
Options::gamepad_manager.resyncGamepadsWithPlayers();
|
// disparase antes de finishBoot(). Protegido por si acaso.
|
||||||
Notifier::get()->show({message});
|
if (Notifier::get() != nullptr) {
|
||||||
ServiceMenu::get()->refresh();
|
Notifier::get()->show({message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void markStartupComplete() {
|
||||||
|
startup_in_progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba los eventos que se pueden producir en cualquier sección del juego
|
// Comprueba los eventos que se pueden producir en cualquier sección del juego
|
||||||
@@ -62,7 +87,10 @@ namespace GlobalEvents {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceMenu::get()->handleEvent(event);
|
// Durante el preload ServiceMenu aún no existe
|
||||||
|
if (ServiceMenu::get() != nullptr) {
|
||||||
|
ServiceMenu::get()->handleEvent(event);
|
||||||
|
}
|
||||||
Mouse::handleEvent(event);
|
Mouse::handleEvent(event);
|
||||||
handleInputEvents(event);
|
handleInputEvents(event);
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user