Compare commits
224 Commits
e46a346d20
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 20b9a95619 | |||
| 513eacf356 | |||
| 5889df2a47 | |||
| 7f703390f9 | |||
| 1bb0ebdef8 | |||
| 5fec0110b3 | |||
| 55caef3210 | |||
| 007c1d3554 | |||
| 28606a9fe1 | |||
| 294e665b11 | |||
| 0faa605ad9 | |||
| c3534ace9c | |||
| 517bc2caa1 | |||
| f9b0f64b81 | |||
| e0498d642d | |||
| ccdf9732d1 | |||
| 1451327fcc | |||
| a035fecb04 | |||
| 9d70138855 | |||
| dfe0a3d4e6 | |||
| 66c3e0089c | |||
| 86323a0e56 | |||
| 58cacf7bda | |||
| 978cbcc9fc | |||
| fb023df1e1 | |||
| 555f347375 | |||
| 85a47c1a2b | |||
| 06d4712493 | |||
| 18c4d6032d | |||
| 9365f80e8b | |||
| 4bd07216f3 | |||
| c25d4dc7e5 | |||
| 550a005ca6 | |||
| 8673736120 | |||
| 8f1aeadeee | |||
| 7e570e2814 | |||
| 1e73a3159f | |||
| cf19194e7a | |||
| 8a43e7cd65 | |||
| 370120345e | |||
| 134b679a75 | |||
| 788aec0dab | |||
| a08da3b983 | |||
| 62a61ecad4 | |||
| 2e6436cc4e | |||
| 7c50cc00fa | |||
| 8f5d56af7f | |||
| 424c243ffc | |||
| 78f858831f | |||
| d3e031e8b5 | |||
| 4792e4f91d | |||
| e1801a9255 | |||
| f0d9e39bb1 | |||
| eb94a17f26 | |||
| ea5c2c15d6 | |||
| ff7170934e | |||
| 1c1762f6b1 | |||
| ee8c075213 | |||
| 958e9f7f75 | |||
| 8fda06e232 | |||
| fb2ffd58ee | |||
| 3f183a5489 | |||
| b044fe1702 | |||
| 32f06ce754 | |||
| a59bfce0bf | |||
| 18c90a5f9c | |||
| b76e271fa7 | |||
| df987e33b2 | |||
| 00e25e1b51 | |||
| 5a03401424 | |||
| 3ac9157fbf | |||
| c1c88032de | |||
| bae3ce7028 | |||
| 744f5d5711 | |||
| 8fa40c802e | |||
| a6262bea4f | |||
| 8627c4c405 | |||
| e41aec37b0 | |||
| d7533c5504 | |||
| 45d02440f6 | |||
| 769e057a81 | |||
| 08f3e04600 | |||
| 3e7aeeedbf | |||
| 26f7cf2a37 | |||
| 58d3a75976 | |||
| 458be05547 | |||
| 6f1eee21b9 | |||
| 9513a6c57e | |||
| 337e6ed6cc | |||
| 2e5f52d836 | |||
| 3ece7f9ec5 | |||
| 9bb4696eb9 | |||
| b9b7aeb8f9 | |||
| 9f17ffdeb3 | |||
| 10e9abece9 | |||
| abe48d5995 | |||
| e7b1af237a | |||
| d58d990205 | |||
| 980f7c1e8e | |||
| 67b1c2cb4d | |||
| 69616fddb5 | |||
| 3fa7324569 | |||
| ec9572175f | |||
| 7dc8a88b8f | |||
| 8df2638905 | |||
| 3da900b102 | |||
| e11cabb9e2 | |||
| c4eaeefb13 | |||
| b8bb1b144f | |||
| 856415c8c4 | |||
| 64138c1017 | |||
| 50a2038ef9 | |||
| cbb5d54250 | |||
| ca99857b5b | |||
| dfed098ffb | |||
| d9b08cf13a | |||
| bbe82d329b | |||
| c87e1e68a9 | |||
| 7adb049b37 | |||
| 6aebb28f37 | |||
| cbdee55148 | |||
| 3cca4373d3 | |||
| 90785d2506 | |||
| fbeea9f424 | |||
| 5f263fa71d | |||
| a32582f1ec | |||
| 09a205a288 | |||
| cdb5040b9d | |||
| ded9b40922 | |||
| 1144fc3626 | |||
| ea994bcc2f | |||
| 74d5bbddaa | |||
| 8ec0914bb5 | |||
| 6d1bc066bd | |||
| 975078307f | |||
| 74d3066871 | |||
| 53c6da4a37 | |||
| 3e666689c5 | |||
| ef124cf309 | |||
| 09d2ef9891 | |||
| 8e609b2e3b | |||
| 09560a001c | |||
| 7b00dc0303 | |||
| 5380ea6bc5 | |||
| 1a20e85af4 | |||
| 94fdd77712 | |||
| 2d0b579425 | |||
| a0042b91cc | |||
| 3ac9c1afce | |||
| ce65a30699 | |||
| def2d16734 | |||
| 9708f4e7ff | |||
| 452ef4c91d | |||
| 860c35992b | |||
| b1c3e0d2af | |||
| 54cee20883 | |||
| 754671e695 | |||
| 7d62b3a339 | |||
| 845af2c93c | |||
| a2b04828f4 | |||
| 361b9250c8 | |||
| c5c1996865 | |||
| 26a696ff57 | |||
| 9321ab223a | |||
| 8c293a6b7f | |||
| a3599d2d3d | |||
| 7ab81eaf29 | |||
| 4f1a596e46 | |||
| b07baa4669 | |||
| cf357560b2 | |||
| 3d52c45f5c | |||
| 3276027044 | |||
| 8041595976 | |||
| fa53c1b01a | |||
| 20b362160e | |||
| 5cabbfc487 | |||
| 9f5e001c70 | |||
| 112c3afc76 | |||
| f4215384fe | |||
| 7796cee51a | |||
| f83154c062 | |||
| 9e73f7f97d | |||
| 742ca02573 | |||
| d77757853d | |||
| ca7ae7418e | |||
| f880bb7d74 | |||
| 9784b5517a | |||
| 88041eba23 | |||
| 698721ae03 | |||
| c7109a46cd | |||
| bb20522172 | |||
| bebc016f3c | |||
| 56c1a1d7f3 | |||
| 50d2a5d1c7 | |||
| 83103ddfea | |||
| f4f7bb52b3 | |||
| b861f33867 | |||
| 2576d62002 | |||
| 02312e1342 | |||
| 83a34d61bf | |||
| 8076d8a765 | |||
| 901757b9b2 | |||
| f5ba15a4af | |||
| 6eda55cdae | |||
| 18c36ad3fb | |||
| a5adf1ba01 | |||
| d5ab7cbe2a | |||
| adad58ccfa | |||
| 33b7c6082e | |||
| 5fd1ffa865 | |||
| 9f93de1d06 | |||
| c3fd348a61 | |||
| ddb70c8c85 | |||
| 95d6396dfa | |||
| 99b61c4b2d | |||
| 91b868572e | |||
| 9c35fadd55 | |||
| 80ca04fd64 | |||
| 4ac7496eff | |||
| b6225d2d2f | |||
| a148c38ef8 | |||
| 902d901698 | |||
| a1bdb6add3 | |||
| 0063a2ede5 |
22
.clang-format
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
|
NamespaceIndentation: All
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
ColumnLimit: 0 # Sin límite de longitud de línea
|
||||||
|
BreakBeforeBraces: Attach # Llaves en la misma línea
|
||||||
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AlignOperands: DontAlign
|
||||||
|
AlignAfterOpenBracket: DontAlign
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
PackConstructorInitializers: Never
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
79
.clang-tidy
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
Checks:
|
||||||
|
- readability-*
|
||||||
|
- modernize-*
|
||||||
|
- performance-*
|
||||||
|
- bugprone-*
|
||||||
|
- -readability-identifier-length
|
||||||
|
- -readability-magic-numbers
|
||||||
|
- -bugprone-integer-division
|
||||||
|
- -bugprone-easily-swappable-parameters
|
||||||
|
- -bugprone-narrowing-conversions
|
||||||
|
- -modernize-avoid-c-arrays,-warnings-as-errors
|
||||||
|
|
||||||
|
WarningsAsErrors: '*'
|
||||||
|
# Solo headers del propio código fuente (external/ y spv/ tienen su propio .clang-tidy dummy)
|
||||||
|
HeaderFilterRegex: 'source/.*'
|
||||||
|
FormatStyle: file
|
||||||
|
|
||||||
|
CheckOptions:
|
||||||
|
# bugprone-empty-catch: aceptar catches vacíos marcados con @INTENTIONAL en un comentario
|
||||||
|
- { key: bugprone-empty-catch.IgnoreCatchWithKeywords, value: '@INTENTIONAL' }
|
||||||
|
|
||||||
|
# Variables locales en snake_case
|
||||||
|
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||||
|
|
||||||
|
# Miembros privados en snake_case con sufijo _
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
|
||||||
|
|
||||||
|
# Miembros protegidos en snake_case con sufijo _
|
||||||
|
- { key: readability-identifier-naming.ProtectedMemberCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.ProtectedMemberSuffix, value: _ }
|
||||||
|
|
||||||
|
# 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.StaticVariableSuffix, value: _ }
|
||||||
|
|
||||||
|
# Constantes estáticas sin sufijo
|
||||||
|
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constantes globales en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Variables constexpr globales en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Constantes locales en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# 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.StructCase, value: CamelCase }
|
||||||
|
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
|
||||||
|
|
||||||
|
# Valores de enums en UPPER_CASE
|
||||||
|
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
||||||
|
|
||||||
|
# Métodos en camelBack (sin sufijos)
|
||||||
|
- { key: readability-identifier-naming.MethodCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.PrivateMethodCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.ProtectedMethodCase, value: camelBack }
|
||||||
|
- { key: readability-identifier-naming.PublicMethodCase, 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 }
|
||||||
18
.gitignore
vendored
@@ -1,5 +1,17 @@
|
|||||||
.vscode
|
.vscode
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
bin
|
thumbs.db
|
||||||
data/config.bin
|
*.exe
|
||||||
data/score.bin
|
*.dmg
|
||||||
|
*.tar.gz
|
||||||
|
*.zip
|
||||||
|
*.app
|
||||||
|
*config.bin
|
||||||
|
*score.bin
|
||||||
|
coffee_crisis
|
||||||
|
coffee_crisis_debug
|
||||||
|
release/windows/coffee.res
|
||||||
|
resources.pack
|
||||||
|
tools/pack_resources/pack_resources
|
||||||
|
|||||||
104
CLAUDE.md
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
Coffee Crisis is a C++20 arcade game built with SDL3. The player controls a character defending the UPV (university) from bouncing coffee-ball enemies across 10 stages. Supports 1-2 players, keyboard and gamepad input, and multiple languages (Spanish, Basque, English).
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
Dependencies: `libsdl3-dev` and `g++` (Linux) or `clang++` (macOS). Build system is CMake (driven by `Makefile` wrappers).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make # Release build
|
||||||
|
make debug # Debug build (defines DEBUG and PAUSE)
|
||||||
|
make release # Empaqueta .tar.gz / .dmg / .zip segons SO
|
||||||
|
make pack # Regenera resources.pack
|
||||||
|
make compile_shaders # Compila shaders GLSL → headers SPIR-V (requereix glslc)
|
||||||
|
make controllerdb # Descarga gamecontrollerdb.txt
|
||||||
|
make format # clang-format -i
|
||||||
|
make tidy # clang-tidy
|
||||||
|
make cppcheck # cppcheck
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Source layout (alineat amb la resta de projectes germans):
|
||||||
|
|
||||||
|
```
|
||||||
|
source/
|
||||||
|
├── main.cpp
|
||||||
|
├── core/
|
||||||
|
│ ├── audio/ jail_audio.hpp
|
||||||
|
│ ├── input/ input.*, mouse.*
|
||||||
|
│ ├── locale/ lang.*
|
||||||
|
│ ├── rendering/ screen, fade, text, writer, texture, sprite + animated/moving/smart
|
||||||
|
│ │ ├── shader_backend.hpp (interfície abstracta de post-procesado)
|
||||||
|
│ │ └── sdl3gpu/ (pipeline SDL3 GPU)
|
||||||
|
│ │ ├── sdl3gpu_shader.* (implementació del backend GPU)
|
||||||
|
│ │ └── spv/ (headers SPIR-V generats — protegits amb dummies `.clang-*`)
|
||||||
|
│ ├── resources/ asset, resource, resource_pack, resource_loader, resource_helper
|
||||||
|
│ └── system/ director
|
||||||
|
├── game/
|
||||||
|
│ ├── defaults.hpp (constants de gameplay: block size, canvas, áreas, colors)
|
||||||
|
│ ├── game.* (hub de gameplay)
|
||||||
|
│ ├── entities/ player, balloon, bullet, item
|
||||||
|
│ ├── scenes/ logo, intro, title, instructions
|
||||||
|
│ └── ui/ menu
|
||||||
|
├── utils/
|
||||||
|
│ ├── defines.hpp (macros de build)
|
||||||
|
│ └── utils.* (helpers, enum de dificultat, circle_t, ...)
|
||||||
|
└── external/ (stb_image, stb_vorbis — protegits amb dummies `.clang-*`)
|
||||||
|
```
|
||||||
|
|
||||||
|
Flux general controlat per la classe **Director** (`core/system/director.h`): inicialitza SDL, finestra/renderer i executa seccions en seqüència **Logo → Intro → Title → Game → Quit**. Les classes principals:
|
||||||
|
|
||||||
|
- **Game** (`game/game.h`): gameplay nuclear. Gestiona jugadors, balloons, bullets, items, stages, nivell d'amenaça i col·lisions. Té el seu bucle d'update/render i sub-bucles per pausa i game-over.
|
||||||
|
- **Screen** (`core/rendering/screen.h`): abstracció de render. Canvas virtual 256×192 escalat a la finestra. Fullscreen/windowed, borders, fades.
|
||||||
|
- **Input** (`core/input/input.h`): abstracció de teclat i gamepad.
|
||||||
|
- **Asset** (`core/resources/asset.h`): índex de fitxers de recurs (`add`/`get` per nom).
|
||||||
|
- **Lang** (`core/locale/lang.h`): i18n, carrega strings des de `data/lang/`.
|
||||||
|
|
||||||
|
### Sprite hierarchy (`core/rendering/`)
|
||||||
|
|
||||||
|
- **Sprite** → base per dibuixar des d'un spritesheet PNG
|
||||||
|
- **AnimatedSprite** → afegeix animació per frames (arxius `.ani`)
|
||||||
|
- **MovingSprite** → sprite amb posició/velocitat
|
||||||
|
- **SmartSprite** → sprite autònom (score popups, objectes llençats)
|
||||||
|
|
||||||
|
### Audio
|
||||||
|
|
||||||
|
**jail_audio** (`core/audio/jail_audio.hpp`): wrapper audio SDL3 first-party. Usa stb_vorbis per OGG. API `JA_*` per música i efectes amb mesclat per canals.
|
||||||
|
|
||||||
|
### GPU / shaders (post-procesado)
|
||||||
|
|
||||||
|
Pipeline SDL3 GPU portat de `coffee_crisis_arcade_edition`. El canvas 256×192 es pot passar per un backend GPU que aplica PostFX (vinyeta, scanlines, chroma, gamma, mask, curvatura, bleeding, flicker) o CrtPi (scanlines continues amb bloom). Fallback transparent al `SDL_Renderer` clàssic si la GPU falla o si es desactiva.
|
||||||
|
|
||||||
|
- **Interfície**: `core/rendering/shader_backend.hpp` (`Rendering::ShaderBackend`).
|
||||||
|
- **Implementació**: `core/rendering/sdl3gpu/sdl3gpu_shader.*` + shaders GLSL a `data/shaders/` compilats a `spv/*_spv.h` via `glslc` (o precompilats si no hi ha `glslc`).
|
||||||
|
- **Emscripten**: compile-time `NO_SHADERS` → sempre ruta clàssica.
|
||||||
|
- **macOS**: shaders Metal (MSL) inline dins `sdl3gpu_shader.cpp`; no SPIR-V.
|
||||||
|
- **Opcions persistents** a `config.txt` (migració a YAML pendent):
|
||||||
|
- `videoGpuAcceleration` (bool)
|
||||||
|
- `videoGpuPreferredDriver` (string, buit = auto)
|
||||||
|
- `videoShaderEnabled` (bool)
|
||||||
|
- `videoShaderType` (0=POSTFX, 1=CRTPI)
|
||||||
|
- **Hotkeys** (provisionals fins que hi hagi menú d'opcions): `F9` toggle GPU · `F10` toggle shader · `F11` alterna POSTFX ↔ CRTPI.
|
||||||
|
- **API** a `Screen`: `setGpuAcceleration`/`toggleGpuAcceleration`/`isGpuAccelerated`, `setShaderEnabled`/`toggleShaderEnabled`/`isShaderEnabled`, `setActiveShader`/`toggleActiveShader`/`getActiveShader`.
|
||||||
|
|
||||||
|
Presets PostFX/CrtPi i cicle de presets encara **no** estan implementats — arribaran amb la migració a YAML. Per ara, valors per defecte hardcoded.
|
||||||
|
|
||||||
|
## Data Directory
|
||||||
|
|
||||||
|
- `data/gfx/` — PNG spritesheets and `.ani` animation definition files
|
||||||
|
- `data/font/` — bitmap font files
|
||||||
|
- `data/music/` and `data/sound/` — audio assets
|
||||||
|
- `data/lang/` — language files (es_ES, ba_BA, en_UK)
|
||||||
|
- `data/demo/` — demo recording data (gamecontrollerdb.txt vive en la raíz del proyecto, fuera del pack)
|
||||||
|
- `data/menu/` — menu definition files
|
||||||
|
- `data/shaders/` — fonts GLSL per al post-procesado SDL3 GPU (no van al pack; s'empotren al binari via headers SPIR-V)
|
||||||
|
|
||||||
|
## Language
|
||||||
|
|
||||||
|
Code comments and variable names are primarily in Spanish/Catalan-Valencian. README is in Catalan-Valencian.
|
||||||
308
CMakeLists.txt
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
# CMakeLists.txt
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(coffee_crisis VERSION 1.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()
|
||||||
|
|
||||||
|
# Configuración de compilador para MinGW en Windows
|
||||||
|
if(WIN32 AND NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
|
set(CMAKE_CXX_COMPILER "g++")
|
||||||
|
set(CMAKE_C_COMPILER "gcc")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Establecer estándar de C++
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# Configuración global de flags de compilación
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os -ffunction-sections -fdata-sections")
|
||||||
|
|
||||||
|
# Define el directorio de los archivos fuente
|
||||||
|
set(DIR_SOURCES "${CMAKE_SOURCE_DIR}/source")
|
||||||
|
|
||||||
|
# Cargar todos los archivos fuente en DIR_SOURCES (recursivo, sin external/)
|
||||||
|
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "${DIR_SOURCES}/*.cpp")
|
||||||
|
list(FILTER SOURCES EXCLUDE REGEX "${DIR_SOURCES}/external/.*")
|
||||||
|
|
||||||
|
# En Emscripten no compilamos sdl3gpu_shader (SDL3 GPU no está soportado en WebGL2).
|
||||||
|
# Define NO_SHADERS más abajo y filtra el fuente aquí.
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
list(REMOVE_ITEM SOURCES "${DIR_SOURCES}/core/rendering/sdl3gpu/sdl3gpu_shader.cpp")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Verificar si se encontraron archivos fuente
|
||||||
|
if(NOT SOURCES)
|
||||||
|
message(FATAL_ERROR "No se encontraron archivos fuente en ${DIR_SOURCES}.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Configuración de SDL3
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
# 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, Emscripten no soporta SDL3 GPU) ---
|
||||||
|
if(NOT APPLE AND NOT EMSCRIPTEN)
|
||||||
|
find_program(GLSLC_EXE NAMES glslc)
|
||||||
|
|
||||||
|
set(SHADER_VERT_SRC "${CMAKE_SOURCE_DIR}/data/shaders/postfx.vert")
|
||||||
|
set(SHADER_FRAG_SRC "${CMAKE_SOURCE_DIR}/data/shaders/postfx.frag")
|
||||||
|
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/core/rendering/sdl3gpu/spv/postfx_vert_spv.h")
|
||||||
|
set(SHADER_FRAG_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/spv/postfx_frag_spv.h")
|
||||||
|
set(SHADER_CRTPI_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/spv/crtpi_frag_spv.h")
|
||||||
|
set(SHADER_UPSCALE_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/spv/upscale_frag_spv.h")
|
||||||
|
set(SHADER_DOWNSCALE_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/spv/downscale_frag_spv.h")
|
||||||
|
|
||||||
|
set(ALL_SHADER_HEADERS "${SHADER_VERT_H}" "${SHADER_FRAG_H}" "${SHADER_CRTPI_H}" "${SHADER_UPSCALE_H}" "${SHADER_DOWNSCALE_H}")
|
||||||
|
|
||||||
|
if(GLSLC_EXE)
|
||||||
|
set(COMPILE_SHADER_SCRIPT "${CMAKE_SOURCE_DIR}/tools/shaders/compile_shader.cmake")
|
||||||
|
|
||||||
|
macro(add_shader SRC_FILE OUT_H VAR_NAME)
|
||||||
|
cmake_parse_arguments(S "" "STAGE" "" ${ARGN})
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${OUT_H}"
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
"-DGLSLC=${GLSLC_EXE}"
|
||||||
|
"-DSRC=${SRC_FILE}"
|
||||||
|
"-DOUT_H=${OUT_H}"
|
||||||
|
"-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})
|
||||||
|
message(STATUS "glslc encontrado: shaders se compilarán automáticamente")
|
||||||
|
else()
|
||||||
|
foreach(_h IN LISTS ALL_SHADER_HEADERS)
|
||||||
|
if(NOT EXISTS "${_h}")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"glslc no encontrado y header SPIR-V no existe: ${_h}\n"
|
||||||
|
" Instala glslc: sudo apt install glslang-tools (Linux)\n"
|
||||||
|
" choco install vulkan-sdk (Windows)"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
message(STATUS "glslc no encontrado - usando headers SPIR-V precompilados")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
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 inline)")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Añadir ejecutable principal
|
||||||
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
|
|
||||||
|
if(NOT APPLE AND NOT EMSCRIPTEN AND GLSLC_EXE)
|
||||||
|
add_dependencies(${PROJECT_NAME} shaders)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Includes relatius a source/ (p.e. `#include "core/rendering/texture.h"`)
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${DIR_SOURCES})
|
||||||
|
|
||||||
|
# Configuración de salida: el ejecutable principal va a la raíz del proyecto.
|
||||||
|
# Per-target (no global) perquè `pack_resources` acabe a `build/` com la resta
|
||||||
|
# de projectes.
|
||||||
|
if(NOT EMSCRIPTEN)
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Añadir definiciones de compilación dependiendo del tipo de build
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||||
|
$<$<CONFIG:DEBUG>:DEBUG PAUSE>
|
||||||
|
$<$<CONFIG:RELEASE>:RELEASE_BUILD>
|
||||||
|
)
|
||||||
|
|
||||||
|
# Enlazar bibliotecas
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3)
|
||||||
|
|
||||||
|
# Configuración específica para cada plataforma
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE WINDOWS_BUILD)
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 mingw32 gdi32 winmm imm32 ole32 version)
|
||||||
|
elseif(APPLE)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated)
|
||||||
|
if(NOT CMAKE_OSX_ARCHITECTURES)
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||||
|
endif()
|
||||||
|
if(MACOS_BUNDLE)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUNDLE)
|
||||||
|
target_link_options(${PROJECT_NAME} PRIVATE
|
||||||
|
-framework SDL3
|
||||||
|
-F ${CMAKE_SOURCE_DIR}/release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64
|
||||||
|
-rpath @executable_path/../Frameworks/
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
elseif(EMSCRIPTEN)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE EMSCRIPTEN_BUILD NO_SHADERS)
|
||||||
|
# En wasm NO empaquetamos un resources.pack: el propio --preload-file de
|
||||||
|
# emscripten ya hace el mismo trabajo (bundle del directorio en un .data),
|
||||||
|
# así que metemos directamente 'data' y dejamos que el Resource lea por
|
||||||
|
# filesystem (MEMFS). Evita doble empaquetado y el uso de memoria extra.
|
||||||
|
target_link_options(${PROJECT_NAME} PRIVATE
|
||||||
|
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/data@/data"
|
||||||
|
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt@/gamecontrollerdb.txt"
|
||||||
|
-sALLOW_MEMORY_GROWTH=1
|
||||||
|
-sMAX_WEBGL_VERSION=2
|
||||||
|
)
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")
|
||||||
|
elseif(UNIX AND NOT APPLE)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
||||||
|
target_link_options(${PROJECT_NAME} PRIVATE -Wl,--gc-sections)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# STATIC ANALYSIS TARGETS
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
find_program(CLANG_TIDY_EXE NAMES clang-tidy)
|
||||||
|
find_program(CLANG_FORMAT_EXE NAMES clang-format)
|
||||||
|
find_program(CPPCHECK_EXE NAMES cppcheck)
|
||||||
|
|
||||||
|
# Recopilar todos los archivos fuente para analisis
|
||||||
|
file(GLOB_RECURSE ALL_SOURCE_FILES
|
||||||
|
"${CMAKE_SOURCE_DIR}/source/*.cpp"
|
||||||
|
"${CMAKE_SOURCE_DIR}/source/*.h"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CLANG_TIDY_SOURCES ${ALL_SOURCE_FILES})
|
||||||
|
|
||||||
|
set(FORMAT_SOURCES ${ALL_SOURCE_FILES})
|
||||||
|
|
||||||
|
# Para cppcheck, pasar solo .cpp (los headers se procesan transitivamente).
|
||||||
|
set(CPPCHECK_SOURCES ${ALL_SOURCE_FILES})
|
||||||
|
list(FILTER CPPCHECK_SOURCES INCLUDE REGEX ".*\\.cpp$")
|
||||||
|
list(FILTER CPPCHECK_SOURCES EXCLUDE REGEX ".*/source/external/.*")
|
||||||
|
|
||||||
|
# Targets de clang-tidy
|
||||||
|
if(CLANG_TIDY_EXE)
|
||||||
|
add_custom_target(tidy
|
||||||
|
COMMAND ${CLANG_TIDY_EXE}
|
||||||
|
-p ${CMAKE_BINARY_DIR}
|
||||||
|
${CLANG_TIDY_SOURCES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Running clang-tidy..."
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(tidy-fix
|
||||||
|
COMMAND ${CLANG_TIDY_EXE}
|
||||||
|
-p ${CMAKE_BINARY_DIR}
|
||||||
|
--fix
|
||||||
|
${CLANG_TIDY_SOURCES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Running clang-tidy with fixes..."
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(STATUS "clang-tidy no encontrado - targets 'tidy' y 'tidy-fix' no disponibles")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Targets de clang-format
|
||||||
|
if(CLANG_FORMAT_EXE)
|
||||||
|
add_custom_target(format
|
||||||
|
COMMAND ${CLANG_FORMAT_EXE}
|
||||||
|
-i
|
||||||
|
${FORMAT_SOURCES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Running clang-format..."
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(format-check
|
||||||
|
COMMAND ${CLANG_FORMAT_EXE}
|
||||||
|
--dry-run
|
||||||
|
--Werror
|
||||||
|
${FORMAT_SOURCES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Checking clang-format..."
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(STATUS "clang-format no encontrado - targets 'format' y 'format-check' no disponibles")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Target de cppcheck
|
||||||
|
if(CPPCHECK_EXE)
|
||||||
|
add_custom_target(cppcheck
|
||||||
|
COMMAND ${CPPCHECK_EXE}
|
||||||
|
--enable=warning,style,performance,portability
|
||||||
|
--std=c++20
|
||||||
|
--language=c++
|
||||||
|
--inline-suppr
|
||||||
|
--suppress=missingIncludeSystem
|
||||||
|
--suppress=toomanyconfigs
|
||||||
|
--quiet
|
||||||
|
-I ${CMAKE_SOURCE_DIR}/source
|
||||||
|
${CPPCHECK_SOURCES}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Running cppcheck..."
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(STATUS "cppcheck no encontrado - target 'cppcheck' no disponible")
|
||||||
|
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)
|
||||||
|
|
||||||
|
# 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_SOURCE_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)
|
||||||
|
endif()
|
||||||
626
LICENSE
@@ -1,625 +1 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
GNU General Public License v3.0 only
|
||||||
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
|
||||||
document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for software and
|
|
||||||
other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed to take
|
|
||||||
away your freedom to share and change the works. By contrast, the GNU General
|
|
||||||
Public License is intended to guarantee your freedom to share and change all
|
|
||||||
versions of a program--to make sure it remains free software for all its users.
|
|
||||||
We, the Free Software Foundation, use the GNU General Public License for most
|
|
||||||
of our software; it applies also to any other work released this way by its
|
|
||||||
authors. You can apply it to your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not price. Our
|
|
||||||
General Public Licenses are designed to make sure that you have the freedom
|
|
||||||
to distribute copies of free software (and charge for them if you wish), that
|
|
||||||
you receive source code or can get it if you want it, that you can change
|
|
||||||
the software or use pieces of it in new free programs, and that you know you
|
|
||||||
can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you these rights
|
|
||||||
or asking you to surrender the rights. Therefore, you have certain responsibilities
|
|
||||||
if you distribute copies of the software, or if you modify it: responsibilities
|
|
||||||
to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether gratis or
|
|
||||||
for a fee, you must pass on to the recipients the same freedoms that you received.
|
|
||||||
You must make sure that they, too, receive or can get the source code. And
|
|
||||||
you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps: (1) assert
|
|
||||||
copyright on the software, and (2) offer you this License giving you legal
|
|
||||||
permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains that
|
|
||||||
there is no warranty for this free software. For both users' and authors'
|
|
||||||
sake, the GPL requires that modified versions be marked as changed, so that
|
|
||||||
their problems will not be attributed erroneously to authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run modified
|
|
||||||
versions of the software inside them, although the manufacturer can do so.
|
|
||||||
This is fundamentally incompatible with the aim of protecting users' freedom
|
|
||||||
to change the software. The systematic pattern of such abuse occurs in the
|
|
||||||
area of products for individuals to use, which is precisely where it is most
|
|
||||||
unacceptable. Therefore, we have designed this version of the GPL to prohibit
|
|
||||||
the practice for those products. If such problems arise substantially in other
|
|
||||||
domains, we stand ready to extend this provision to those domains in future
|
|
||||||
versions of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents. States
|
|
||||||
should not allow patents to restrict development and use of software on general-purpose
|
|
||||||
computers, but in those that do, we wish to avoid the special danger that
|
|
||||||
patents applied to a free program could make it effectively proprietary. To
|
|
||||||
prevent this, the GPL assures that patents cannot be used to render the program
|
|
||||||
non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and modification
|
|
||||||
follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of works,
|
|
||||||
such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this License.
|
|
||||||
Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
|
|
||||||
or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work in
|
|
||||||
a fashion requiring copyright permission, other than the making of an exact
|
|
||||||
copy. The resulting work is called a "modified version" of the earlier work
|
|
||||||
or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based on the
|
|
||||||
Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without permission,
|
|
||||||
would make you directly or secondarily liable for infringement under applicable
|
|
||||||
copyright law, except executing it on a computer or modifying a private copy.
|
|
||||||
Propagation includes copying, distribution (with or without modification),
|
|
||||||
making available to the public, and in some countries other activities as
|
|
||||||
well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other parties
|
|
||||||
to make or receive copies. Mere interaction with a user through a computer
|
|
||||||
network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices" to the
|
|
||||||
extent that it includes a convenient and prominently visible feature that
|
|
||||||
(1) displays an appropriate copyright notice, and (2) tells the user that
|
|
||||||
there is no warranty for the work (except to the extent that warranties are
|
|
||||||
provided), that licensees may convey the work under this License, and how
|
|
||||||
to view a copy of this License. If the interface presents a list of user commands
|
|
||||||
or options, such as a menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work for making
|
|
||||||
modifications to it. "Object code" means any non-source form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official standard
|
|
||||||
defined by a recognized standards body, or, in the case of interfaces specified
|
|
||||||
for a particular programming language, one that is widely used among developers
|
|
||||||
working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other than
|
|
||||||
the work as a whole, that (a) is included in the normal form of packaging
|
|
||||||
a Major Component, but which is not part of that Major Component, and (b)
|
|
||||||
serves only to enable use of the work with that Major Component, or to implement
|
|
||||||
a Standard Interface for which an implementation is available to the public
|
|
||||||
in source code form. A "Major Component", in this context, means a major essential
|
|
||||||
component (kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to produce
|
|
||||||
the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all the source
|
|
||||||
code needed to generate, install, and (for an executable work) run the object
|
|
||||||
code and to modify the work, including scripts to control those activities.
|
|
||||||
However, it does not include the work's System Libraries, or general-purpose
|
|
||||||
tools or generally available free programs which are used unmodified in performing
|
|
||||||
those activities but which are not part of the work. For example, Corresponding
|
|
||||||
Source includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically linked
|
|
||||||
subprograms that the work is specifically designed to require, such as by
|
|
||||||
intimate data communication or control flow between those subprograms and
|
|
||||||
other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users can regenerate
|
|
||||||
automatically from other parts of the Corresponding Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of copyright
|
|
||||||
on the Program, and are irrevocable provided the stated conditions are met.
|
|
||||||
This License explicitly affirms your unlimited permission to run the unmodified
|
|
||||||
Program. The output from running a covered work is covered by this License
|
|
||||||
only if the output, given its content, constitutes a covered work. This License
|
|
||||||
acknowledges your rights of fair use or other equivalent, as provided by copyright
|
|
||||||
law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not convey, without
|
|
||||||
conditions so long as your license otherwise remains in force. You may convey
|
|
||||||
covered works to others for the sole purpose of having them make modifications
|
|
||||||
exclusively for you, or provide you with facilities for running those works,
|
|
||||||
provided that you comply with the terms of this License in conveying all material
|
|
||||||
for which you do not control copyright. Those thus making or running the covered
|
|
||||||
works for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of your copyrighted
|
|
||||||
material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under the conditions
|
|
||||||
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological measure
|
|
||||||
under any applicable law fulfilling obligations under article 11 of the WIPO
|
|
||||||
copyright treaty adopted on 20 December 1996, or similar laws prohibiting
|
|
||||||
or restricting circumvention of such measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid circumvention
|
|
||||||
of technological measures to the extent such circumvention is effected by
|
|
||||||
exercising rights under this License with respect to the covered work, and
|
|
||||||
you disclaim any intention to limit operation or modification of the work
|
|
||||||
as a means of enforcing, against the work's users, your or third parties'
|
|
||||||
legal rights to forbid circumvention of technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you receive
|
|
||||||
it, in any medium, provided that you conspicuously and appropriately publish
|
|
||||||
on each copy an appropriate copyright notice; keep intact all notices stating
|
|
||||||
that this License and any non-permissive terms added in accord with section
|
|
||||||
7 apply to the code; keep intact all notices of the absence of any warranty;
|
|
||||||
and give all recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey, and you
|
|
||||||
may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to produce
|
|
||||||
it from the Program, in the form of source code under the terms of section
|
|
||||||
4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified it, and
|
|
||||||
giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is released under
|
|
||||||
this License and any conditions added under section 7. This requirement modifies
|
|
||||||
the requirement in section 4 to "keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this License to anyone
|
|
||||||
who comes into possession of a copy. This License will therefore apply, along
|
|
||||||
with any applicable section 7 additional terms, to the whole of the work,
|
|
||||||
and all its parts, regardless of how they are packaged. This License gives
|
|
||||||
no permission to license the work in any other way, but it does not invalidate
|
|
||||||
such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display Appropriate
|
|
||||||
Legal Notices; however, if the Program has interactive interfaces that do
|
|
||||||
not display Appropriate Legal Notices, your work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent works,
|
|
||||||
which are not by their nature extensions of the covered work, and which are
|
|
||||||
not combined with it such as to form a larger program, in or on a volume of
|
|
||||||
a storage or distribution medium, is called an "aggregate" if the compilation
|
|
||||||
and its resulting copyright are not used to limit the access or legal rights
|
|
||||||
of the compilation's users beyond what the individual works permit. Inclusion
|
|
||||||
of a covered work in an aggregate does not cause this License to apply to
|
|
||||||
the other parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms of sections
|
|
||||||
4 and 5, provided that you also convey the machine-readable Corresponding
|
|
||||||
Source under the terms of this License, in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product (including
|
|
||||||
a physical distribution medium), accompanied by the Corresponding Source fixed
|
|
||||||
on a durable physical medium customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product (including
|
|
||||||
a physical distribution medium), accompanied by a written offer, valid for
|
|
||||||
at least three years and valid for as long as you offer spare parts or customer
|
|
||||||
support for that product model, to give anyone who possesses the object code
|
|
||||||
either (1) a copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical medium customarily
|
|
||||||
used for software interchange, for a price no more than your reasonable cost
|
|
||||||
of physically performing this conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the written
|
|
||||||
offer to provide the Corresponding Source. This alternative is allowed only
|
|
||||||
occasionally and noncommercially, and only if you received the object code
|
|
||||||
with such an offer, in accord with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated place (gratis
|
|
||||||
or for a charge), and offer equivalent access to the Corresponding Source
|
|
||||||
in the same way through the same place at no further charge. You need not
|
|
||||||
require recipients to copy the Corresponding Source along with the object
|
|
||||||
code. If the place to copy the object code is a network server, the Corresponding
|
|
||||||
Source may be on a different server (operated by you or a third party) that
|
|
||||||
supports equivalent copying facilities, provided you maintain clear directions
|
|
||||||
next to the object code saying where to find the Corresponding Source. Regardless
|
|
||||||
of what server hosts the Corresponding Source, you remain obligated to ensure
|
|
||||||
that it is available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided you inform
|
|
||||||
other peers where the object code and Corresponding Source of the work are
|
|
||||||
being offered to the general public at no charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded from
|
|
||||||
the Corresponding Source as a System Library, need not be included in conveying
|
|
||||||
the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any tangible
|
|
||||||
personal property which is normally used for personal, family, or household
|
|
||||||
purposes, or (2) anything designed or sold for incorporation into a dwelling.
|
|
||||||
In determining whether a product is a consumer product, doubtful cases shall
|
|
||||||
be resolved in favor of coverage. For a particular product received by a particular
|
|
||||||
user, "normally used" refers to a typical or common use of that class of product,
|
|
||||||
regardless of the status of the particular user or of the way in which the
|
|
||||||
particular user actually uses, or expects or is expected to use, the product.
|
|
||||||
A product is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent the
|
|
||||||
only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods, procedures,
|
|
||||||
authorization keys, or other information required to install and execute modified
|
|
||||||
versions of a covered work in that User Product from a modified version of
|
|
||||||
its Corresponding Source. The information must suffice to ensure that the
|
|
||||||
continued functioning of the modified object code is in no case prevented
|
|
||||||
or interfered with solely because modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or specifically
|
|
||||||
for use in, a User Product, and the conveying occurs as part of a transaction
|
|
||||||
in which the right of possession and use of the User Product is transferred
|
|
||||||
to the recipient in perpetuity or for a fixed term (regardless of how the
|
|
||||||
transaction is characterized), the Corresponding Source conveyed under this
|
|
||||||
section must be accompanied by the Installation Information. But this requirement
|
|
||||||
does not apply if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has been installed
|
|
||||||
in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a requirement
|
|
||||||
to continue to provide support service, warranty, or updates for a work that
|
|
||||||
has been modified or installed by the recipient, or for the User Product in
|
|
||||||
which it has been modified or installed. Access to a network may be denied
|
|
||||||
when the modification itself materially and adversely affects the operation
|
|
||||||
of the network or violates the rules and protocols for communication across
|
|
||||||
the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided, in accord
|
|
||||||
with this section must be in a format that is publicly documented (and with
|
|
||||||
an implementation available to the public in source code form), and must require
|
|
||||||
no special password or key for unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this License
|
|
||||||
by making exceptions from one or more of its conditions. Additional permissions
|
|
||||||
that are applicable to the entire Program shall be treated as though they
|
|
||||||
were included in this License, to the extent that they are valid under applicable
|
|
||||||
law. If additional permissions apply only to part of the Program, that part
|
|
||||||
may be used separately under those permissions, but the entire Program remains
|
|
||||||
governed by this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option remove any
|
|
||||||
additional permissions from that copy, or from any part of it. (Additional
|
|
||||||
permissions may be written to require their own removal in certain cases when
|
|
||||||
you modify the work.) You may place additional permissions on material, added
|
|
||||||
by you to a covered work, for which you have or can give appropriate copyright
|
|
||||||
permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you add
|
|
||||||
to a covered work, you may (if authorized by the copyright holders of that
|
|
||||||
material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the terms of
|
|
||||||
sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or author
|
|
||||||
attributions in that material or in the Appropriate Legal Notices displayed
|
|
||||||
by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or requiring
|
|
||||||
that modified versions of such material be marked in reasonable ways as different
|
|
||||||
from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or authors
|
|
||||||
of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some trade names,
|
|
||||||
trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that material by
|
|
||||||
anyone who conveys the material (or modified versions of it) with contractual
|
|
||||||
assumptions of liability to the recipient, for any liability that these contractual
|
|
||||||
assumptions directly impose on those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further restrictions"
|
|
||||||
within the meaning of section 10. If the Program as you received it, or any
|
|
||||||
part of it, contains a notice stating that it is governed by this License
|
|
||||||
along with a term that is a further restriction, you may remove that term.
|
|
||||||
If a license document contains a further restriction but permits relicensing
|
|
||||||
or conveying under this License, you may add to a covered work material governed
|
|
||||||
by the terms of that license document, provided that the further restriction
|
|
||||||
does not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you must place,
|
|
||||||
in the relevant source files, a statement of the additional terms that apply
|
|
||||||
to those files, or a notice indicating where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the form
|
|
||||||
of a separately written license, or stated as exceptions; the above requirements
|
|
||||||
apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly provided
|
|
||||||
under this License. Any attempt otherwise to propagate or modify it is void,
|
|
||||||
and will automatically terminate your rights under this License (including
|
|
||||||
any patent licenses granted under the third paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your license from
|
|
||||||
a particular copyright holder is reinstated (a) provisionally, unless and
|
|
||||||
until the copyright holder explicitly and finally terminates your license,
|
|
||||||
and (b) permanently, if the copyright holder fails to notify you of the violation
|
|
||||||
by some reasonable means prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is reinstated permanently
|
|
||||||
if the copyright holder notifies you of the violation by some reasonable means,
|
|
||||||
this is the first time you have received notice of violation of this License
|
|
||||||
(for any work) from that copyright holder, and you cure the violation prior
|
|
||||||
to 30 days after your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the licenses
|
|
||||||
of parties who have received copies or rights from you under this License.
|
|
||||||
If your rights have been terminated and not permanently reinstated, you do
|
|
||||||
not qualify to receive new licenses for the same material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or run a copy
|
|
||||||
of the Program. Ancillary propagation of a covered work occurring solely as
|
|
||||||
a consequence of using peer-to-peer transmission to receive a copy likewise
|
|
||||||
does not require acceptance. However, nothing other than this License grants
|
|
||||||
you permission to propagate or modify any covered work. These actions infringe
|
|
||||||
copyright if you do not accept this License. Therefore, by modifying or propagating
|
|
||||||
a covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically receives
|
|
||||||
a license from the original licensors, to run, modify and propagate that work,
|
|
||||||
subject to this License. You are not responsible for enforcing compliance
|
|
||||||
by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an organization,
|
|
||||||
or substantially all assets of one, or subdividing an organization, or merging
|
|
||||||
organizations. If propagation of a covered work results from an entity transaction,
|
|
||||||
each party to that transaction who receives a copy of the work also receives
|
|
||||||
whatever licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the Corresponding
|
|
||||||
Source of the work from the predecessor in interest, if the predecessor has
|
|
||||||
it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the rights
|
|
||||||
granted or affirmed under this License. For example, you may not impose a
|
|
||||||
license fee, royalty, or other charge for exercise of rights granted under
|
|
||||||
this License, and you may not initiate litigation (including a cross-claim
|
|
||||||
or counterclaim in a lawsuit) alleging that any patent claim is infringed
|
|
||||||
by making, using, selling, offering for sale, or importing the Program or
|
|
||||||
any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this License
|
|
||||||
of the Program or a work on which the Program is based. The work thus licensed
|
|
||||||
is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims owned or controlled
|
|
||||||
by the contributor, whether already acquired or hereafter acquired, that would
|
|
||||||
be infringed by some manner, permitted by this License, of making, using,
|
|
||||||
or selling its contributor version, but do not include claims that would be
|
|
||||||
infringed only as a consequence of further modification of the contributor
|
|
||||||
version. For purposes of this definition, "control" includes the right to
|
|
||||||
grant patent sublicenses in a manner consistent with the requirements of this
|
|
||||||
License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
|
|
||||||
license under the contributor's essential patent claims, to make, use, sell,
|
|
||||||
offer for sale, import and otherwise run, modify and propagate the contents
|
|
||||||
of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express agreement
|
|
||||||
or commitment, however denominated, not to enforce a patent (such as an express
|
|
||||||
permission to practice a patent or covenant not to sue for patent infringement).
|
|
||||||
To "grant" such a patent license to a party means to make such an agreement
|
|
||||||
or commitment not to enforce a patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license, and the
|
|
||||||
Corresponding Source of the work is not available for anyone to copy, free
|
|
||||||
of charge and under the terms of this License, through a publicly available
|
|
||||||
network server or other readily accessible means, then you must either (1)
|
|
||||||
cause the Corresponding Source to be so available, or (2) arrange to deprive
|
|
||||||
yourself of the benefit of the patent license for this particular work, or
|
|
||||||
(3) arrange, in a manner consistent with the requirements of this License,
|
|
||||||
to extend the patent license to downstream recipients. "Knowingly relying"
|
|
||||||
means you have actual knowledge that, but for the patent license, your conveying
|
|
||||||
the covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that country
|
|
||||||
that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or arrangement,
|
|
||||||
you convey, or propagate by procuring conveyance of, a covered work, and grant
|
|
||||||
a patent license to some of the parties receiving the covered work authorizing
|
|
||||||
them to use, propagate, modify or convey a specific copy of the covered work,
|
|
||||||
then the patent license you grant is automatically extended to all recipients
|
|
||||||
of the covered work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within the scope
|
|
||||||
of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
|
|
||||||
of one or more of the rights that are specifically granted under this License.
|
|
||||||
You may not convey a covered work if you are a party to an arrangement with
|
|
||||||
a third party that is in the business of distributing software, under which
|
|
||||||
you make payment to the third party based on the extent of your activity of
|
|
||||||
conveying the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory patent
|
|
||||||
license (a) in connection with copies of the covered work conveyed by you
|
|
||||||
(or copies made from those copies), or (b) primarily for and in connection
|
|
||||||
with specific products or compilations that contain the covered work, unless
|
|
||||||
you entered into that arrangement, or that patent license was granted, prior
|
|
||||||
to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting any implied
|
|
||||||
license or other defenses to infringement that may otherwise be available
|
|
||||||
to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or otherwise)
|
|
||||||
that contradict the conditions of this License, they do not excuse you from
|
|
||||||
the conditions of this License. If you cannot convey a covered work so as
|
|
||||||
to satisfy simultaneously your obligations under this License and any other
|
|
||||||
pertinent obligations, then as a consequence you may not convey it at all.
|
|
||||||
For example, if you agree to terms that obligate you to collect a royalty
|
|
||||||
for further conveying from those to whom you convey the Program, the only
|
|
||||||
way you could satisfy both those terms and this License would be to refrain
|
|
||||||
entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have permission to
|
|
||||||
link or combine any covered work with a work licensed under version 3 of the
|
|
||||||
GNU Affero General Public License into a single combined work, and to convey
|
|
||||||
the resulting work. The terms of this License will continue to apply to the
|
|
||||||
part which is the covered work, but the special requirements of the GNU Affero
|
|
||||||
General Public License, section 13, concerning interaction through a network
|
|
||||||
will apply to the combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of the
|
|
||||||
GNU General Public License from time to time. Such new versions will be similar
|
|
||||||
in spirit to the present version, but may differ in detail to address new
|
|
||||||
problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program specifies
|
|
||||||
that a certain numbered version of the GNU General Public License "or any
|
|
||||||
later version" applies to it, you have the option of following the terms and
|
|
||||||
conditions either of that numbered version or of any later version published
|
|
||||||
by the Free Software Foundation. If the Program does not specify a version
|
|
||||||
number of the GNU General Public License, you may choose any version ever
|
|
||||||
published by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future versions of
|
|
||||||
the GNU General Public License can be used, that proxy's public statement
|
|
||||||
of acceptance of a version permanently authorizes you to choose that version
|
|
||||||
for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different permissions. However,
|
|
||||||
no additional obligations are imposed on any author or copyright holder as
|
|
||||||
a result of your choosing to follow a later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
|
|
||||||
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
||||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
|
|
||||||
PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
|
||||||
CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
|
|
||||||
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
|
|
||||||
AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
|
||||||
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
|
|
||||||
USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
|
||||||
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
|
|
||||||
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
|
||||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided above cannot
|
|
||||||
be given local legal effect according to their terms, reviewing courts shall
|
|
||||||
apply local law that most closely approximates an absolute waiver of all civil
|
|
||||||
liability in connection with the Program, unless a warranty or assumption
|
|
||||||
of liability accompanies a copy of the Program in return for a fee. END OF
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest possible
|
|
||||||
use to the public, the best way to achieve this is to make it free software
|
|
||||||
which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to attach
|
|
||||||
them to the start of each source file to most effectively state the exclusion
|
|
||||||
of warranty; and each file should have at least the "copyright" line and a
|
|
||||||
pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
|
||||||
Foundation, either version 3 of the License, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short notice like
|
|
||||||
this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
|
|
||||||
This is free software, and you are welcome to redistribute it under certain
|
|
||||||
conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands might
|
|
||||||
be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary. For
|
|
||||||
more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Lesser General Public
|
|
||||||
License instead of this License. But first, please read <https://www.gnu.org/
|
|
||||||
licenses /why-not-lgpl.html>.
|
|
||||||
411
Makefile
@@ -1,13 +1,400 @@
|
|||||||
executable = coffee_crisis
|
# ==============================================================================
|
||||||
|
# DIRECTORIES
|
||||||
|
# ==============================================================================
|
||||||
|
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
||||||
|
DIR_BIN := $(addsuffix /, $(DIR_ROOT))
|
||||||
|
|
||||||
macos:
|
# ==============================================================================
|
||||||
mkdir -p bin
|
# TARGET NAMES
|
||||||
g++ -std=c++11 -Wall -O2 source/*.cpp -o bin/$(executable)_macos -lSDL2
|
# ==============================================================================
|
||||||
linux:
|
TARGET_NAME := coffee_crisis
|
||||||
mkdir -p bin
|
TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
|
||||||
g++ source/*.cpp -std=c++11 -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o bin/$(executable)_linux
|
APP_NAME := Coffee Crisis
|
||||||
strip -s -R .comment -R .gnu.version bin/$(executable)_linux --strip-unneeded
|
DIST_DIR := dist
|
||||||
opendingux:
|
RELEASE_FOLDER := dist/_tmp
|
||||||
mkdir -p bin
|
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
||||||
/opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -D GCWZERO -O2 -std=c++11 -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lSDL2_mixer -lstdc++ source/*.cpp -o bin/$(executable)_opendingux
|
RESOURCE_FILE := release/windows/coffee.res
|
||||||
/opt/gcw0-toolchain/usr/bin/mksquashfs ./default.gcw0.desktop ./icon.png ./bin ./data ./media coffee_crisis.opk -all-root -noappend -no-exports -no-xattrs
|
|
||||||
|
# ==============================================================================
|
||||||
|
# VERSION (extracted from defines.hpp)
|
||||||
|
# ==============================================================================
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
VERSION := $(shell powershell -Command "(Select-String -Path 'source/utils/defines.hpp' -Pattern 'constexpr const char\* VERSION = \"(.+?)\"').Matches.Groups[1].Value")
|
||||||
|
else
|
||||||
|
VERSION := $(shell grep 'constexpr const char\* VERSION' source/utils/defines.hpp | sed -E 's/.*VERSION = "([^"]+)".*/\1/')
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# GIT HASH (computat al host, passat a CMake via -DGIT_HASH)
|
||||||
|
# Evita que CMake haja de cridar git des de Docker/emscripten on falla per
|
||||||
|
# "dubious ownership" del volum muntat.
|
||||||
|
# ==============================================================================
|
||||||
|
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
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# RELEASE NAMES
|
||||||
|
# ==============================================================================
|
||||||
|
WINDOWS_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
||||||
|
MACOS_INTEL_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-intel.dmg
|
||||||
|
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-macos-apple-silicon.dmg
|
||||||
|
LINUX_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux.tar.gz
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# PLATAFORMA
|
||||||
|
# ==============================================================================
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
FixPath = $(subst /,\\,$1)
|
||||||
|
RM := del /Q
|
||||||
|
MKDIR := mkdir
|
||||||
|
else
|
||||||
|
FixPath = $1
|
||||||
|
RMFILE := rm -f
|
||||||
|
RMDIR := rm -rdf
|
||||||
|
MKDIR := mkdir -p
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# SHELL (Windows usa cmd.exe)
|
||||||
|
# ==============================================================================
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
SHELL := cmd.exe
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# WINDOWS-SPECIFIC VARIABLES
|
||||||
|
# ==============================================================================
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
WIN_TARGET_FILE := $(DIR_BIN)$(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
|
||||||
|
WIN_TARGET_FILE := $(TARGET_FILE)
|
||||||
|
WIN_RELEASE_FILE := $(RELEASE_FILE)
|
||||||
|
WIN_RELEASE_FILE_PS := $(WIN_RELEASE_FILE)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# CMAKE GENERATOR (Windows needs explicit MinGW Makefiles generator)
|
||||||
|
# ==============================================================================
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
CMAKE_GEN := -G "MinGW Makefiles"
|
||||||
|
else
|
||||||
|
CMAKE_GEN :=
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# COMPILACIÓN CON CMAKE
|
||||||
|
# ==============================================================================
|
||||||
|
all:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build
|
||||||
|
|
||||||
|
debug:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Debug -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# EMPAQUETADO DE RECURSOS (build previ de l'eina + execució)
|
||||||
|
# ==============================================================================
|
||||||
|
pack:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build --target pack_resources
|
||||||
|
@./build/pack_resources data resources.pack
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# RELEASE AUTOMÁTICO (detecta SO)
|
||||||
|
# ==============================================================================
|
||||||
|
release:
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
@"$(MAKE)" _windows_release
|
||||||
|
else
|
||||||
|
ifeq ($(UNAME_S),Darwin)
|
||||||
|
@$(MAKE) _macos_release
|
||||||
|
else
|
||||||
|
@$(MAKE) _linux_release
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# COMPILACIÓN PARA WINDOWS (RELEASE)
|
||||||
|
# ==============================================================================
|
||||||
|
_windows_release:
|
||||||
|
@$(MAKE) pack
|
||||||
|
@echo off
|
||||||
|
@echo Creando release para Windows - Version: $(VERSION)
|
||||||
|
|
||||||
|
# Compila con cmake
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build
|
||||||
|
|
||||||
|
# Crea carpeta de distribución y carpeta temporal
|
||||||
|
@powershell -Command "if (-not (Test-Path '$(DIST_DIR)')) {New-Item '$(DIST_DIR)' -ItemType Directory}"
|
||||||
|
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
|
||||||
|
@powershell -Command "if (-not (Test-Path '$(RELEASE_FOLDER)')) {New-Item '$(RELEASE_FOLDER)' -ItemType Directory}"
|
||||||
|
|
||||||
|
# Copia ficheros
|
||||||
|
@powershell -Command "Copy-Item 'resources.pack' -Destination '$(RELEASE_FOLDER)'"
|
||||||
|
@powershell -Command "Copy-Item 'gamecontrollerdb.txt' -Destination '$(RELEASE_FOLDER)'"
|
||||||
|
@powershell -Command "Copy-Item 'LICENSE' -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 -Path '$(TARGET_FILE).exe' -Destination '$(WIN_RELEASE_FILE_PS).exe'"
|
||||||
|
strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded
|
||||||
|
|
||||||
|
# Crea el fichero .zip
|
||||||
|
@powershell -Command "if (Test-Path '$(WINDOWS_RELEASE)') {Remove-Item '$(WINDOWS_RELEASE)'}"
|
||||||
|
@powershell -Command "Compress-Archive -Path '$(RELEASE_FOLDER)/*' -DestinationPath '$(WINDOWS_RELEASE)'"
|
||||||
|
@echo Release creado: $(WINDOWS_RELEASE)
|
||||||
|
|
||||||
|
# Elimina la carpeta temporal
|
||||||
|
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# COMPILACIÓN PARA MACOS (RELEASE)
|
||||||
|
# ==============================================================================
|
||||||
|
_macos_release:
|
||||||
|
@$(MAKE) pack
|
||||||
|
@echo "Creando release para macOS - Version: $(VERSION)"
|
||||||
|
|
||||||
|
# Verificar e instalar create-dmg si es necesario
|
||||||
|
@which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg)
|
||||||
|
|
||||||
|
# Compila la versión para procesadores Intel con cmake
|
||||||
|
@cmake -S . -B build/intel -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DMACOS_BUNDLE=ON -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build/intel
|
||||||
|
|
||||||
|
# Elimina datos de compilaciones anteriores
|
||||||
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
$(RMFILE) tmp.dmg
|
||||||
|
$(RMFILE) "$(DIST_DIR)"/rw.*
|
||||||
|
$(RMFILE) "$(MACOS_INTEL_RELEASE)"
|
||||||
|
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||||
|
|
||||||
|
# Crea la carpeta temporal y las carpetas del app bundle
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
|
|
||||||
|
# Copia carpetas y ficheros
|
||||||
|
cp resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
|
cp gamecontrollerdb.txt "$(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 release/icons/*.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||||
|
cp release/macos/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
|
||||||
|
cp LICENSE "$(RELEASE_FOLDER)"
|
||||||
|
cp README.md "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
|
# Actualiza versión en Info.plist
|
||||||
|
@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"
|
||||||
|
|
||||||
|
# Copia el ejecutable Intel al bundle
|
||||||
|
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
||||||
|
|
||||||
|
# Firma la aplicación
|
||||||
|
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
||||||
|
|
||||||
|
# Empaqueta el .dmg de la versión Intel con create-dmg
|
||||||
|
@echo "Creando DMG Intel..."
|
||||||
|
create-dmg \
|
||||||
|
--volname "$(APP_NAME)" \
|
||||||
|
--window-pos 200 120 \
|
||||||
|
--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)"
|
||||||
|
|
||||||
|
# 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 -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build/arm
|
||||||
|
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
||||||
|
|
||||||
|
# Firma la aplicación
|
||||||
|
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
||||||
|
|
||||||
|
# Empaqueta el .dmg de la versión Apple Silicon con create-dmg
|
||||||
|
@echo "Creando DMG Apple Silicon..."
|
||||||
|
create-dmg \
|
||||||
|
--volname "$(APP_NAME)" \
|
||||||
|
--window-pos 200 120 \
|
||||||
|
--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_APPLE_SILICON_RELEASE)" \
|
||||||
|
"$(RELEASE_FOLDER)" || true
|
||||||
|
@echo "Release Apple Silicon creado: $(MACOS_APPLE_SILICON_RELEASE)"
|
||||||
|
|
||||||
|
# Elimina las carpetas temporales
|
||||||
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
$(RMDIR) build/intel
|
||||||
|
$(RMDIR) build/arm
|
||||||
|
$(RMFILE) "$(DIST_DIR)"/rw.*
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# COMPILACIÓN PARA LINUX (RELEASE)
|
||||||
|
# ==============================================================================
|
||||||
|
_linux_release:
|
||||||
|
@$(MAKE) pack
|
||||||
|
@echo "Creando release para Linux - Version: $(VERSION)"
|
||||||
|
|
||||||
|
# Compila con cmake
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build
|
||||||
|
|
||||||
|
# Elimina carpeta temporal previa y la recrea
|
||||||
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
|
# Copia ficheros
|
||||||
|
cp resources.pack "$(RELEASE_FOLDER)"
|
||||||
|
cp gamecontrollerdb.txt "$(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) "$(LINUX_RELEASE)"
|
||||||
|
tar -czvf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
||||||
|
@echo "Release creado: $(LINUX_RELEASE)"
|
||||||
|
|
||||||
|
# Elimina la carpeta temporal
|
||||||
|
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# COMPILACIÓN PARA WEBASSEMBLY (requiere Docker)
|
||||||
|
# ==============================================================================
|
||||||
|
wasm:
|
||||||
|
@$(MAKE) pack
|
||||||
|
@echo "Compilando para WebAssembly - 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/wasm/
|
||||||
|
ssh maverick 'cd /home/sergio/gitea/web_jailgames && ./deploy.sh'
|
||||||
|
@echo "Deployed to maverick"
|
||||||
|
|
||||||
|
# Versió Debug del build wasm: build local sense deploy. Sortida a dist/wasm_debug/.
|
||||||
|
wasm_debug:
|
||||||
|
@$(MAKE) pack
|
||||||
|
@echo "Compilando WebAssembly Debug - 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_debug -DCMAKE_BUILD_TYPE=Debug -DGIT_HASH=$(GIT_HASH) && cmake --build build/wasm_debug"
|
||||||
|
$(MKDIR) "$(DIST_DIR)/wasm_debug"
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).html $(DIST_DIR)/wasm_debug/
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).js $(DIST_DIR)/wasm_debug/
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).wasm $(DIST_DIR)/wasm_debug/
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).data $(DIST_DIR)/wasm_debug/
|
||||||
|
@echo "Output: $(DIST_DIR)/wasm_debug/"
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# ==============================================================================
|
||||||
|
# CODE QUALITY (delegados a cmake)
|
||||||
|
# ==============================================================================
|
||||||
|
format:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build --target format
|
||||||
|
|
||||||
|
format-check:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build --target format-check
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build --target tidy
|
||||||
|
|
||||||
|
tidy-fix:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@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
|
||||||
|
|
||||||
|
# SHADERS (SPIR-V) — sólo Linux/Windows. Requiere glslc en el PATH.
|
||||||
|
compile_shaders:
|
||||||
|
@cmake $(CMAKE_GEN) -S . -B build -DCMAKE_BUILD_TYPE=Release -DGIT_HASH=$(GIT_HASH)
|
||||||
|
@cmake --build build --target shaders
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# ==============================================================================
|
||||||
|
show_version:
|
||||||
|
@echo "Version actual: $(VERSION)"
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Makefile para Coffee Crisis"
|
||||||
|
@echo "Comandos disponibles:"
|
||||||
|
@echo ""
|
||||||
|
@echo " Compilacion:"
|
||||||
|
@echo " make - Compilar con cmake (Release)"
|
||||||
|
@echo " make debug - Compilar con cmake (Debug)"
|
||||||
|
@echo ""
|
||||||
|
@echo " Release:"
|
||||||
|
@echo " make release - Crear release (detecta SO automaticamente)"
|
||||||
|
@echo " make wasm - Compilar para WebAssembly (requiere Docker) y deploy a maverick"
|
||||||
|
@echo " make wasm_debug - Compilar WebAssembly Debug local (sin deploy)"
|
||||||
|
@echo ""
|
||||||
|
@echo " Herramientas:"
|
||||||
|
@echo " make pack - Empaquetar recursos a resources.pack"
|
||||||
|
@echo " make compile_shaders - Compilar shaders GLSL a headers SPIR-V (requiere glslc)"
|
||||||
|
@echo " make controllerdb - Descargar gamecontrollerdb.txt actualizado"
|
||||||
|
@echo ""
|
||||||
|
@echo " Calidad de codigo:"
|
||||||
|
@echo " make format - Formatear codigo con clang-format"
|
||||||
|
@echo " make format-check - Verificar formato sin modificar"
|
||||||
|
@echo " make tidy - Analisis estatico con clang-tidy"
|
||||||
|
@echo " make tidy-fix - Analisis estatico con auto-fix"
|
||||||
|
@echo " make cppcheck - Analisis estatico con cppcheck"
|
||||||
|
@echo ""
|
||||||
|
@echo " Otros:"
|
||||||
|
@echo " make show_version - Mostrar version actual ($(VERSION))"
|
||||||
|
@echo " make help - Mostrar esta ayuda"
|
||||||
|
|
||||||
|
.PHONY: all debug release _windows_release _macos_release _linux_release wasm wasm_debug controllerdb pack format format-check tidy tidy-fix cppcheck compile_shaders show_version help
|
||||||
|
|||||||
43
README.md
@@ -1,22 +1,34 @@
|
|||||||
# Coffee Crisis
|
# Coffee Crisis
|
||||||
|
|
||||||
Coffee Crisis es un juego arcade que pondrá a prueba tus reflejos. Empezado durante el verano de 2020 y terminado un año despues, en el verano de 2021. Intenta conseguir todos los puntos que puedas con una sola vida a traves de los 10 niveles de juego y ayuda a Bal1 a defender la UPV de la invasión de la cafeína esférica y saltarina.
|
Coffee Crisis és un joc arcade que posarà a prova els teus reflexos. Començat durant l'estiu de 2020 i acabat un any després a l'estiu de 2021. Intenta aconseguir tots els punts que pugues amb una sola vida a través dels 10 nivells de joc i ajuda a Bal1 a defensar la UPV de la invasió de la cafeïna esfèrica i saltarina.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Teclat
|
||||||
|
|
||||||
|
El joc es maneja amb teclat, encara que també es pot connectar un comandament de control.
|
||||||
|
Les tecles són les següents:
|
||||||
|
* **Fletxes**: Moure el personatge, moure's pels menús
|
||||||
|
* **Q, W, E**: Disparar a l'esquerra, al centre i a la dreta respectivament
|
||||||
|
* **ESCAPE**: Posa en pausa el joc durant la partida. Surt dels menús. Tanca el joc
|
||||||
|
* **ENTER**: Accepta les opcions en els menús
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Compilar
|
## Compilar
|
||||||
|
|
||||||
Para compilar el código se necesitan tener las librerías SDL instaladas en el sistema y el compilador g++.
|
Per compilar el codi cal tindre les biblioteques SDL instal·lades al sistema i el compilador g++.
|
||||||
|
|
||||||
En Linux:
|
En Linux:
|
||||||
```bash
|
```bash
|
||||||
sudo apt install libsdl2-dev g++
|
sudo apt install libsdl2-dev g++
|
||||||
```
|
```
|
||||||
|
|
||||||
En macOS se pueden instalar fácilmente con [brew](https://brew.sh):
|
En macOS es poden instal·lar fàcilment amb [brew](https://brew.sh):
|
||||||
```bash
|
```bash
|
||||||
brew install sdl2 g++
|
brew install sdl2 g++
|
||||||
```
|
```
|
||||||
|
|
||||||
Una vez instaladas las librerías SDL, se puede compilar utilizando el fichero Makefile suministrado.
|
Un cop instal·lades les biblioteques SDL, es pot compilar utilitzant el fitxer Makefile subministrat.
|
||||||
|
|
||||||
En Linux:
|
En Linux:
|
||||||
```bash
|
```bash
|
||||||
@@ -27,27 +39,28 @@ En macOS:
|
|||||||
```bash
|
```bash
|
||||||
make macos
|
make macos
|
||||||
```
|
```
|
||||||
|

|
||||||
|
|
||||||
## Como ejecutar
|
## Com executar
|
||||||
|
|
||||||
Para ejecutar el juego hay que escribir en la terminal la orden que se muestra a continuación.
|
Per executar el joc cal escriure a la terminal l'ordre que es mostra a continuació.
|
||||||
|
|
||||||
En Linux:
|
En Linux:
|
||||||
```bash
|
```bash
|
||||||
bin/coffee_crisis_linux
|
./coffee_crisis_linux
|
||||||
```
|
```
|
||||||
|
|
||||||
En macOS:
|
En macOS:
|
||||||
```bash
|
```bash
|
||||||
bin/coffee_crisis_macos
|
./coffee_crisis_macos
|
||||||
```
|
```
|
||||||
|
|
||||||
En macOS tambien puedes hacer doble click sobre el archivo coffee_crisis_macos que hay en la carpeta bin
|
En macOS també pots fer doble clic sobre l'arxiu coffee_crisis_macos
|
||||||
|
|
||||||
## Agradecimientos
|
## Agraïments
|
||||||
A los jailers y a la jail. Y entre ellos, a JailDoctor por estar siempre ahí apoyándonos/obligándonos a sacar un Jailgame más.
|
Als jailers i a la jail. I entre ells, a JailDoctor per estar sempre donant-nos suport/obligant-nos a traure un Jailgame més.
|
||||||
|
|
||||||
Y por supuesto a ti por estar aquí.
|
I per descomptat a tu per estar aquí.
|
||||||
|
|
||||||
## Licencia
|
## Llicència
|
||||||
Usa el código para lo que quieras: aprender, reirte, curiosear... excepto para sacar beneficio económico. Si lo consigues, por favor avísame y vamos a medias.
|
Utilitza el codi per a el que vulgues: aprendre, riure't, tafanejar... excepte per treure'n benefici econòmic. Si ho aconsegueixes, si us plau avisa'm i anem a mitges.
|
||||||
|
Before Width: | Height: | Size: 57 KiB |
37
data/gfx/balloon1.ani
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
frameWidth=8
|
||||||
|
frameHeight=8
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=orange
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=blue
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=12,13,14,15,16,17,18,19,20,21
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=green
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27,28,29,30,31,32,33
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=red
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=36,37,38,39,40,41,42,43,44,45
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=pop
|
||||||
|
speed=5
|
||||||
|
loop=-1
|
||||||
|
frames=48,49,50,51,52,53,54,55,56,57,58,59
|
||||||
|
[/animation]
|
||||||
BIN
data/gfx/balloon1.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
37
data/gfx/balloon2.ani
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
frameWidth=13
|
||||||
|
frameHeight=13
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=orange
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=blue
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=12,13,14,15,16,17,18,19,20,21
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=green
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27,28,29,30,31,32,33
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=red
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=36,37,38,39,40,41,42,43,44,45
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=pop
|
||||||
|
speed=5
|
||||||
|
loop=-1
|
||||||
|
frames=48,49,50,51,52,53,54,55,56,57,58,59
|
||||||
|
[/animation]
|
||||||
BIN
data/gfx/balloon2.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
37
data/gfx/balloon3.ani
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
frameWidth=21
|
||||||
|
frameHeight=21
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=orange
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=blue
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=12,13,14,15,16,17,18,19,20,21
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=green
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27,28,29,30,31,32,33
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=red
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=36,37,38,39,40,41,42,43,44,45
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=pop
|
||||||
|
speed=5
|
||||||
|
loop=-1
|
||||||
|
frames=48,49,50,51,52,53,54,55,56,57,58,59
|
||||||
|
[/animation]
|
||||||
BIN
data/gfx/balloon3.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
44
data/gfx/balloon4.ani
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
frameWidth=37
|
||||||
|
frameHeight=37
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=orange
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3,4,5,6,7,8,9
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=blue
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=12,13,14,15,16,17,18,19,20,21
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=green
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27,28,29,30,31,32,33
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=red
|
||||||
|
speed=20
|
||||||
|
loop=0
|
||||||
|
frames=36,37,38,39,40,41,42,43,44,45
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=powerball
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=10
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=pop
|
||||||
|
speed=5
|
||||||
|
loop=-1
|
||||||
|
frames=48,49,50,51,52,53,54,55,56,57,58,59
|
||||||
|
[/animation]
|
||||||
BIN
data/gfx/balloon4.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB |
BIN
data/gfx/game_buildings.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
data/gfx/game_clouds.png
Normal file
|
After Width: | Height: | Size: 901 B |
BIN
data/gfx/game_grass.png
Normal file
|
After Width: | Height: | Size: 468 B |
BIN
data/gfx/game_power_meter.png
Normal file
|
After Width: | Height: | Size: 270 B |
BIN
data/gfx/game_sky_colors.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 795 B After Width: | Height: | Size: 438 B |
@@ -3,7 +3,7 @@ frameHeight=16
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=10
|
||||||
loop=-1
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6
|
frames=0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/gfx/item_clock.png
Normal file
|
After Width: | Height: | Size: 334 B |
@@ -3,7 +3,7 @@ frameHeight=16
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=10
|
||||||
loop=-1
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6
|
frames=0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/gfx/item_coffee.png
Normal file
|
After Width: | Height: | Size: 462 B |
9
data/gfx/item_coffee_machine.ani
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
frameWidth=23
|
||||||
|
frameHeight=29
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=default
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3
|
||||||
|
[/animation]
|
||||||
BIN
data/gfx/item_coffee_machine.png
Normal file
|
After Width: | Height: | Size: 553 B |
@@ -3,7 +3,7 @@ frameHeight=16
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=10
|
||||||
loop=-1
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6
|
frames=0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/gfx/item_points1_disk.png
Normal file
|
After Width: | Height: | Size: 263 B |
@@ -3,7 +3,7 @@ frameHeight=16
|
|||||||
|
|
||||||
[animation]
|
[animation]
|
||||||
name=default
|
name=default
|
||||||
speed=8
|
speed=10
|
||||||
loop=-1
|
loop=0
|
||||||
frames=0,1,2,3,4,5,6
|
frames=0,1
|
||||||
[/animation]
|
[/animation]
|
||||||
BIN
data/gfx/item_points2_gavina.png
Normal file
|
After Width: | Height: | Size: 422 B |
9
data/gfx/item_points3_pacmar.ani
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
frameWidth=16
|
||||||
|
frameHeight=16
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=default
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=0,1
|
||||||
|
[/animation]
|
||||||
BIN
data/gfx/item_points3_pacmar.png
Normal file
|
After Width: | Height: | Size: 388 B |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.5 KiB |
BIN
data/gfx/menu_game_over.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
data/gfx/menu_game_over_end.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 654 B |
BIN
data/gfx/player_arounder_body.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
data/gfx/player_arounder_death.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
data/gfx/player_arounder_fire.png
Normal file
|
After Width: | Height: | Size: 887 B |
BIN
data/gfx/player_arounder_head.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
data/gfx/player_arounder_legs.png
Normal file
|
After Width: | Height: | Size: 443 B |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
BIN
data/gfx/player_bal1_death.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
data/gfx/player_bal1_fire.png
Normal file
|
After Width: | Height: | Size: 835 B |
BIN
data/gfx/player_bal1_head.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 529 B |
176
data/gfx/player_body.ani
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
frameWidth=24
|
||||||
|
frameHeight=24
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=4,5,6,7
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_1C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=8,9,10,11
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_1C
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=12,13,14,15
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_2C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=16,17,18,19
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_2C
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=20,21,22,23
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=28,29,30,31
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_1C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=32,33,34,35
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_1C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=36,37,38,39
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_2C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=40,41,42,43
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_2C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=44,45,46,47
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_pwr
|
||||||
|
speed=3
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_pwr
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=4,5,6,7
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_1C_pwr
|
||||||
|
speed=3
|
||||||
|
loop=0
|
||||||
|
frames=8,9,10,11
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_1C_pwr
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=12,13,14,15
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_2C_pwr
|
||||||
|
speed=3
|
||||||
|
loop=0
|
||||||
|
frames=16,17,18,19
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_2C_pwr
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=20,21,22,23
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=28,29,30,31
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_1C_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=32,33,34,35
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_1C_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=36,37,38,39
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_2C_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=40,41,42,43
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_2C_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=44,45,46,47
|
||||||
|
[/animation]
|
||||||
9
data/gfx/player_death.ani
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
frameWidth=24
|
||||||
|
frameHeight=24
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=default
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3
|
||||||
|
[/animation]
|
||||||
9
data/gfx/player_fire.ani
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
frameWidth=28
|
||||||
|
frameHeight=32
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=default
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3
|
||||||
|
[/animation]
|
||||||
114
data/gfx/player_head.ani
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
frameWidth=24
|
||||||
|
frameHeight=24
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=4,5,6,7
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_1C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=8,9,10,11
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_1C
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=12,13,14,15
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_pwr
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=16,17,18,19
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_pwr
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=20,21,22,23
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk_1C_pwr
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand_1C_pwr
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=28,29,30,31
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=16,17,18,19
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=20,21,22,23
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_1C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_1C
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=28,29,30,31
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=16,17,18,19
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=20,21,22,23
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=sideshoot_1C_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=24,25,26,27
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=centershoot_1C_pwr
|
||||||
|
speed=2
|
||||||
|
loop=0
|
||||||
|
frames=28,29,30,31
|
||||||
|
[/animation]
|
||||||
16
data/gfx/player_legs.ani
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
frameWidth=24
|
||||||
|
frameHeight=24
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=walk
|
||||||
|
speed=5
|
||||||
|
loop=0
|
||||||
|
frames=0,1,2,3
|
||||||
|
[/animation]
|
||||||
|
|
||||||
|
[animation]
|
||||||
|
name=stand
|
||||||
|
speed=10
|
||||||
|
loop=0
|
||||||
|
frames=4,5,6,7
|
||||||
|
[/animation]
|
||||||
@@ -1,160 +1,287 @@
|
|||||||
## 0 - MENU DEL TITULO
|
## 0 - MENU DEL TITULO
|
||||||
JUGAR
|
JUGAR
|
||||||
|
|
||||||
## 1 - MENU DEL TITULO
|
## 1 - MENU DEL TITULO
|
||||||
OPCIONS
|
OPCIONS
|
||||||
|
|
||||||
## 2 - MENU DEL TITULO
|
## 2 - MENU DEL TITULO
|
||||||
INSTRUCCIONS
|
INSTRUCCIONS
|
||||||
|
|
||||||
## 3 - MENU DEL TITULO
|
## 3 - MENU DEL TITULO
|
||||||
EIXIR
|
EIXIR
|
||||||
|
|
||||||
## 4 - MENU DE OPCIONES
|
## 4 - MENU DE OPCIONES
|
||||||
FINESTRA
|
FINESTRA
|
||||||
|
|
||||||
## 5 - MENU DE OPCIONES
|
## 5 - MENU DE OPCIONES
|
||||||
PANTALLA COMPLETA
|
PANTALLA COMPLETA
|
||||||
|
|
||||||
## 6 - MENU DE OPCIONES
|
## 6 - MENU DE OPCIONES
|
||||||
PANTALLA COMPLETA FALSA
|
PANTALLA COMPLETA FALSA
|
||||||
|
|
||||||
## 7 - MENU DE OPCIONES
|
## 7 - MENU DE OPCIONES
|
||||||
TAMANY DE FINESTRA
|
TAMANY DE FINESTRA
|
||||||
|
|
||||||
## 8 - MENU DE OPCIONES
|
## 8 - MENU DE OPCIONES
|
||||||
IDIOMA
|
IDIOMA
|
||||||
|
|
||||||
## 9 - MENU DE OPCIONES
|
## 9 - MENU DE OPCIONES
|
||||||
[ ACEPTAR ]
|
[ ACEPTAR ]
|
||||||
|
|
||||||
## 10 - MENU DE OPCIONES
|
## 10 - MENU DE OPCIONES
|
||||||
[ CANCELAR ]
|
[ CANCELAR ]
|
||||||
|
|
||||||
## 11 - INSTRUCCIONES
|
## 11 - INSTRUCCIONES
|
||||||
OBJECTIU
|
OBJECTIU
|
||||||
|
|
||||||
## 12 - INSTRUCCIONES
|
## 12 - INSTRUCCIONES
|
||||||
HAS D'EXPLOTAR
|
HAS D'EXPLOTAR
|
||||||
|
|
||||||
## 13 - INSTRUCCIONES
|
## 13 - INSTRUCCIONES
|
||||||
TANTS GLOBUS COM PUGUES
|
TANTS GLOBUS COM PUGUES
|
||||||
|
|
||||||
## 14 - INSTRUCCIONES
|
## 14 - INSTRUCCIONES
|
||||||
LA DIFICULTAT AUGMENTA
|
LA DIFICULTAT AUGMENTA
|
||||||
|
|
||||||
## 15 - INSTRUCCIONES
|
## 15 - INSTRUCCIONES
|
||||||
A MESURA QUE VAS PUNTUANT
|
A MESURA QUE VAS PUNTUANT
|
||||||
|
|
||||||
## 16 - INSTRUCCIONES
|
## 16 - INSTRUCCIONES
|
||||||
OBJECTES
|
OBJECTES
|
||||||
|
|
||||||
## 17 - INSTRUCCIONES
|
## 17 - INSTRUCCIONES
|
||||||
1.000 PUNTS
|
1.000 PUNTS
|
||||||
|
|
||||||
## 18 - INSTRUCCIONES
|
## 18 - INSTRUCCIONES
|
||||||
2.500 PUNTS
|
2.500 PUNTS
|
||||||
|
|
||||||
## 19 - INSTRUCCIONES
|
## 19 - INSTRUCCIONES
|
||||||
5.000 PUNTS
|
5.000 PUNTS
|
||||||
|
|
||||||
## 20 - INSTRUCCIONES
|
## 20 - INSTRUCCIONES
|
||||||
PARA EL TEMPS
|
PARA EL TEMPS
|
||||||
|
|
||||||
## 21 - INSTRUCCIONES
|
## 21 - INSTRUCCIONES
|
||||||
VIDA EXTRA
|
VIDA EXTRA
|
||||||
|
|
||||||
## 22 - INSTRUCCIONES
|
## 22 - INSTRUCCIONES
|
||||||
PREM UNA TECLA PER A TORNAR
|
PREM UNA TECLA PER A TORNAR
|
||||||
|
|
||||||
## 23 - TITULO
|
## 23 - TITULO
|
||||||
PREM QUALSEVOL TECLA
|
PREM QUALSEVOL TECLA
|
||||||
|
|
||||||
## 24 - MENU SELECCION DE IDIOMA
|
## 24 - MENU SELECCION DE IDIOMA
|
||||||
ESPA{OL (ESPANYOL)
|
ESPA{OL (ESPANYOL)
|
||||||
|
|
||||||
## 25 - MENU SELECCION DE IDIOMA
|
## 25 - MENU SELECCION DE IDIOMA
|
||||||
BALOONCIA
|
BALOONCIA
|
||||||
|
|
||||||
## 26 - MENU SELECCION DE IDIOMA
|
## 26 - MENU SELECCION DE IDIOMA
|
||||||
ENGLISH (ANGLES)
|
ENGLISH (ANGLES)
|
||||||
|
|
||||||
## 27 - INTRO
|
## 27 - INTRO
|
||||||
Un dia qualsevol de l'any 2000
|
Un dia qualsevol de l'any 2000
|
||||||
|
|
||||||
## 28 - INTRO
|
## 28 - INTRO
|
||||||
Tot esta tranquil a la UPV
|
Tot esta tranquil a la UPV
|
||||||
|
|
||||||
## 29 - INTRO
|
## 29 - INTRO
|
||||||
Fins que un desaprensiu...
|
Fins que un desaprensiu...
|
||||||
|
|
||||||
## 30 - INTRO
|
## 30 - INTRO
|
||||||
HEY! ME ANE A FERME UN CORTAET...
|
HEY! ME ANE A FERME UN CORTAET...
|
||||||
|
|
||||||
## 31 - INTRO
|
## 31 - INTRO
|
||||||
UAAAAAAAAAAAAA!!!
|
UAAAAAAAAAAAAA!!!
|
||||||
|
|
||||||
## 32 - INTRO
|
## 32 - INTRO
|
||||||
Espera un moment...
|
Espera un moment...
|
||||||
|
|
||||||
## 33 - INTRO
|
## 33 - INTRO
|
||||||
Si resulta que no tinc solt!
|
Si resulta que no tinc solt!
|
||||||
|
|
||||||
## 34 - INTRO
|
## 34 - INTRO
|
||||||
MERDA DE MAQUINA!
|
MERDA DE MAQUINA!
|
||||||
|
|
||||||
## 35 - INTRO
|
## 35 - INTRO
|
||||||
Blop... blop... blop...
|
Blop... blop... blop...
|
||||||
|
|
||||||
## 36 - TEXTOS DEL JUEGO
|
## 36 - TEXTOS DEL JUEGO
|
||||||
Temps detes:
|
Temps detes:
|
||||||
|
|
||||||
## 37 - TEXTOS DEL JUEGO
|
## 37 - TEXTOS DEL JUEGO
|
||||||
D E M O
|
D E M O
|
||||||
|
|
||||||
## 38 - TEXTOS DEL JUEGO
|
## 38 - TEXTOS DEL JUEGO
|
||||||
fases mes!
|
fases mes!
|
||||||
## 39 -
|
|
||||||
|
|
||||||
## 40 -
|
## 39 - MENU SELECCION DE JUGADOR
|
||||||
|
Selecciona personatge
|
||||||
|
|
||||||
## 41 -
|
## 40 - MENU SELECCION DE JUGADOR
|
||||||
|
Enrere
|
||||||
|
|
||||||
## 42 -
|
## 41 - MENU DE PAUSA
|
||||||
|
Menu de pausa
|
||||||
|
|
||||||
|
## 42 - TABLA DE RECORDS
|
||||||
|
Millors puntuacions
|
||||||
|
|
||||||
## 43 - PANTALLA DE GAME OVER
|
## 43 - PANTALLA DE GAME OVER
|
||||||
FI DEL JOC
|
FI DEL JOC
|
||||||
|
|
||||||
## 44 - PANTALLA DE GAME OVER
|
## 44 - PANTALLA DE GAME OVER
|
||||||
ELS TEUS PUNTS:
|
ELS TEUS PUNTS:
|
||||||
|
|
||||||
## 45 - PANTALLA DE GAME OVER
|
## 45 - PANTALLA DE GAME OVER
|
||||||
CONTINUAR?
|
CONTINUAR?
|
||||||
|
|
||||||
## 46 - MENU DE PAUSA
|
## 46 - MENU DE PAUSA
|
||||||
CONTINUAR
|
CONTINUAR
|
||||||
|
|
||||||
## 47 - MENU DE PAUSA
|
## 47 - MENU DE PAUSA
|
||||||
EIXIR DEL JOC
|
EIXIR DEL JOC
|
||||||
|
|
||||||
## 48 - MENU GAME OVER
|
## 48 - MENU GAME OVER
|
||||||
SI
|
SI
|
||||||
|
|
||||||
## 49 - MENU GAME OVER
|
## 49 - MENU GAME OVER
|
||||||
NO
|
NO
|
||||||
|
|
||||||
## 50 - TEXTO DE COMPLETAR EL JUEGO
|
## 50 - TEXTO DE COMPLETAR EL JUEGO
|
||||||
Felicitats!!
|
Felicitats!!
|
||||||
|
|
||||||
## 51 - MENU DEL TITULO
|
## 51 - MENU DEL TITULO
|
||||||
1 JUGADOR
|
1 JUGADOR
|
||||||
|
|
||||||
## 52 - MENU DEL TITULO
|
## 52 - MENU DEL TITULO
|
||||||
2 JUGADORS
|
2 JUGADORS
|
||||||
|
|
||||||
## 53 MARCADOR
|
## 53 MARCADOR
|
||||||
jugador 1
|
jugador 1
|
||||||
|
|
||||||
## 54 MARCADOR
|
## 54 MARCADOR
|
||||||
jugador 2
|
jugador 2
|
||||||
|
|
||||||
## 55 MARCADOR
|
## 55 MARCADOR
|
||||||
mult
|
mult
|
||||||
|
|
||||||
## 56 MARCADOR
|
## 56 MARCADOR
|
||||||
max. puntuacio
|
max. puntuacio
|
||||||
|
|
||||||
## 57 MARCADOR
|
## 57 MARCADOR
|
||||||
fase
|
fase
|
||||||
|
|
||||||
## 58 - MENU DE OPCIONES
|
## 58 - MENU DE OPCIONES
|
||||||
MODE DE VISUALITZACIO
|
MODE DE VISUALITZACIO
|
||||||
|
|
||||||
## 59 - MENU DE OPCIONES
|
## 59 - MENU DE OPCIONES
|
||||||
DIFICULTAT
|
DIFICULTAT
|
||||||
|
|
||||||
## 60 - MENU DE OPCIONES
|
## 60 - MENU DE OPCIONES
|
||||||
FILTRE
|
FILTRE
|
||||||
|
|
||||||
## 61 - MENU DE OPCIONES
|
## 61 - MENU DE OPCIONES
|
||||||
SINC. VERTICAL
|
SINC. VERTICAL
|
||||||
|
|
||||||
## 62 - MENU DE OPCIONES
|
## 62 - MENU DE OPCIONES
|
||||||
CONTROLS DEL JUGADOR 1
|
CONTROLS DEL JUGADOR 1
|
||||||
|
|
||||||
## 63 - MENU DE OPCIONES
|
## 63 - MENU DE OPCIONES
|
||||||
CONTROLS DEL JUGADOR 2
|
CONTROLS DEL JUGADOR 2
|
||||||
## 64 -
|
|
||||||
|
## 64 - MENU DE OPCIONES
|
||||||
|
(FORA DE LINEA)
|
||||||
|
|
||||||
## 65 -
|
## 65 -
|
||||||
|
-
|
||||||
|
|
||||||
## 66 - MENU DE OPCIONES
|
## 66 - MENU DE OPCIONES
|
||||||
FACIL
|
FACIL
|
||||||
|
|
||||||
## 67 - MENU DE OPCIONES
|
## 67 - MENU DE OPCIONES
|
||||||
NORMAL
|
NORMAL
|
||||||
|
|
||||||
## 68 - MENU DE OPCIONES
|
## 68 - MENU DE OPCIONES
|
||||||
DIFICIL
|
DIFICIL
|
||||||
|
|
||||||
## 69 - MENU DE OPCIONES
|
## 69 - MENU DE OPCIONES
|
||||||
TECLAT
|
TECLAT
|
||||||
|
|
||||||
## 70 - MENU DE OPCIONES
|
## 70 - MENU DE OPCIONES
|
||||||
MANDO
|
MANDO
|
||||||
|
|
||||||
## 71 - MENU DE OPCIONES
|
## 71 - MENU DE OPCIONES
|
||||||
LINEAL
|
LINEAL
|
||||||
|
|
||||||
## 72 - MENU DE OPCIONES
|
## 72 - MENU DE OPCIONES
|
||||||
NEAREST
|
NEAREST
|
||||||
|
|
||||||
## 73 - MENU DE OPCIONES
|
## 73 - MENU DE OPCIONES
|
||||||
ACTIVADA
|
ACTIVADA
|
||||||
|
|
||||||
## 74 - MENU DE OPCIONES
|
## 74 - MENU DE OPCIONES
|
||||||
DESACTIVADA
|
DESACTIVADA
|
||||||
|
|
||||||
## 75 - JUEGO
|
## 75 - JUEGO
|
||||||
Endavant!
|
Endavant!
|
||||||
|
|
||||||
## 76 - JUEGO
|
## 76 - JUEGO
|
||||||
1.000.000 de punts!
|
1.000.000 de punts!
|
||||||
|
|
||||||
## 77 - PANTALLA DE GAME OVER
|
## 77 - PANTALLA DE GAME OVER
|
||||||
PUNTS J1:
|
PUNTS J1:
|
||||||
|
|
||||||
## 78 - PANTALLA DE GAME OVER
|
## 78 - PANTALLA DE GAME OVER
|
||||||
PUNTS J2:
|
PUNTS J2:
|
||||||
|
|
||||||
## 79 - TEXTOS DEL JUEGO
|
## 79 - TEXTOS DEL JUEGO
|
||||||
Ultima fase!
|
Ultima fase!
|
||||||
|
|
||||||
|
## 80 - NOTIFICACIONES
|
||||||
|
Fallo al conectar a
|
||||||
|
|
||||||
|
## 81 - NOTIFICACIONES
|
||||||
|
No s'ha pogut obtenir
|
||||||
|
|
||||||
|
## 82 - NOTIFICACIONES
|
||||||
|
la puntuacio online
|
||||||
|
|
||||||
|
## 83 - NOTIFICACIONES
|
||||||
|
No ha especificat
|
||||||
|
|
||||||
|
## 84 - NOTIFICACIONES
|
||||||
|
cap jailerID
|
||||||
|
|
||||||
|
## 85 - NOTIFICACIONES
|
||||||
|
ha iniciat la sesio
|
||||||
|
|
||||||
|
## 86 - NOTIFICACIONES
|
||||||
|
Punts enviats:
|
||||||
|
|
||||||
|
## 87 - NOTIFICACIONES
|
||||||
|
No s'ha pogut
|
||||||
|
|
||||||
|
## 88 - NOTIFICACIONES
|
||||||
|
enviar la puntuacio
|
||||||
|
|
||||||
|
## 89 - ENTER ID
|
||||||
|
CONFIGURACIO EN LINEA
|
||||||
|
|
||||||
|
## 90 - ENTER ID
|
||||||
|
INTRODUEIX UN JAILER_ID
|
||||||
|
|
||||||
|
## 91 - ENTER ID
|
||||||
|
DEIXA BUIT PER A
|
||||||
|
|
||||||
|
## 92 - ENTER ID
|
||||||
|
MODE FORA DE LINEA
|
||||||
|
|
||||||
|
## 93 - MENU OPCIONES
|
||||||
|
TAULER DE PUNTS
|
||||||
|
|
||||||
|
## 94 - NOTIFICACIO COMANDAMENT
|
||||||
|
CONNECTAT
|
||||||
|
|
||||||
|
## 95 - NOTIFICACIO COMANDAMENT
|
||||||
|
DESCONNECTAT
|
||||||
@@ -1,160 +1,287 @@
|
|||||||
## 0 - MENU DEL TITULO
|
## 0 - MENU DEL TITULO
|
||||||
PLAY
|
PLAY
|
||||||
|
|
||||||
## 1 - MENU DEL TITULO
|
## 1 - MENU DEL TITULO
|
||||||
OPTIONS
|
OPTIONS
|
||||||
|
|
||||||
## 2 - MENU DEL TITULO
|
## 2 - MENU DEL TITULO
|
||||||
HOW TO PLAY
|
HOW TO PLAY
|
||||||
|
|
||||||
## 3 - MENU DEL TITULO
|
## 3 - MENU DEL TITULO
|
||||||
QUIT
|
QUIT
|
||||||
|
|
||||||
## 4 - MENU DE OPCIONES
|
## 4 - MENU DE OPCIONES
|
||||||
WINDOW
|
WINDOW
|
||||||
|
|
||||||
## 5 - MENU DE OPCIONES
|
## 5 - MENU DE OPCIONES
|
||||||
FULLSCREEN
|
FULLSCREEN
|
||||||
|
|
||||||
## 6 - MENU DE OPCIONES
|
## 6 - MENU DE OPCIONES
|
||||||
FAKE FULLSCREEN
|
FAKE FULLSCREEN
|
||||||
|
|
||||||
## 7 - MENU DE OPCIONES
|
## 7 - MENU DE OPCIONES
|
||||||
WINDOW SIZE
|
WINDOW SIZE
|
||||||
|
|
||||||
## 8 - MENU DE OPCIONES
|
## 8 - MENU DE OPCIONES
|
||||||
LANGUAGE
|
LANGUAGE
|
||||||
|
|
||||||
## 9 - MENU DE OPCIONES
|
## 9 - MENU DE OPCIONES
|
||||||
[ ACCEPT ]
|
[ ACCEPT ]
|
||||||
|
|
||||||
## 10 - MENU DE OPCIONES
|
## 10 - MENU DE OPCIONES
|
||||||
[ CANCEL ]
|
[ CANCEL ]
|
||||||
|
|
||||||
## 11 - INSTRUCCIONES
|
## 11 - INSTRUCCIONES
|
||||||
OBJECTIVE
|
OBJECTIVE
|
||||||
|
|
||||||
## 12 - INSTRUCCIONES
|
## 12 - INSTRUCCIONES
|
||||||
YOU HAVE TO POP AS MANY
|
YOU HAVE TO POP AS MANY
|
||||||
|
|
||||||
## 13 - INSTRUCCIONES
|
## 13 - INSTRUCCIONES
|
||||||
BALLOONS AS YOU CAN
|
BALLOONS AS YOU CAN
|
||||||
|
|
||||||
## 14 - INSTRUCCIONES
|
## 14 - INSTRUCCIONES
|
||||||
DIFFICULTY WILL BE INCREASED
|
DIFFICULTY WILL BE INCREASED
|
||||||
|
|
||||||
## 15 - INSTRUCCIONES
|
## 15 - INSTRUCCIONES
|
||||||
AS YOU SCORE POINTS
|
AS YOU SCORE POINTS
|
||||||
|
|
||||||
## 16 - INSTRUCCIONES
|
## 16 - INSTRUCCIONES
|
||||||
ITEMS
|
ITEMS
|
||||||
|
|
||||||
## 17 - INSTRUCCIONES
|
## 17 - INSTRUCCIONES
|
||||||
1.000 POINTS
|
1.000 POINTS
|
||||||
|
|
||||||
## 18 - INSTRUCCIONES
|
## 18 - INSTRUCCIONES
|
||||||
2.500 POINTS
|
2.500 POINTS
|
||||||
|
|
||||||
## 19 - INSTRUCCIONES
|
## 19 - INSTRUCCIONES
|
||||||
5.000 POINTS
|
5.000 POINTS
|
||||||
|
|
||||||
## 20 - INSTRUCCIONES
|
## 20 - INSTRUCCIONES
|
||||||
TIME STOPPER
|
TIME STOPPER
|
||||||
|
|
||||||
## 21 - INSTRUCCIONES
|
## 21 - INSTRUCCIONES
|
||||||
EXTRA HIT
|
EXTRA HIT
|
||||||
|
|
||||||
## 22 - INSTRUCCIONES
|
## 22 - INSTRUCCIONES
|
||||||
PRESS ANY KEY TO RETURN
|
PRESS ANY KEY TO RETURN
|
||||||
|
|
||||||
## 23 - TITULO
|
## 23 - TITULO
|
||||||
PRESS ANY KEY
|
PRESS ANY KEY
|
||||||
|
|
||||||
## 24 - MENU SELECCION DE IDIOMA
|
## 24 - MENU SELECCION DE IDIOMA
|
||||||
ESPA{OL (SPANISH)
|
ESPA{OL (SPANISH)
|
||||||
|
|
||||||
## 25 - MENU SELECCION DE IDIOMA
|
## 25 - MENU SELECCION DE IDIOMA
|
||||||
BALOONCIA (VALENCIAN)
|
BALOONCIA (VALENCIAN)
|
||||||
|
|
||||||
## 26 - MENU SELECCION DE IDIOMA
|
## 26 - MENU SELECCION DE IDIOMA
|
||||||
ENGLISH
|
ENGLISH
|
||||||
|
|
||||||
## 27 - INTRO
|
## 27 - INTRO
|
||||||
Any day of the year 2000
|
Any day of the year 2000
|
||||||
|
|
||||||
## 28 - INTRO
|
## 28 - INTRO
|
||||||
Everything is quiet at the UPV
|
Everything is quiet at the UPV
|
||||||
|
|
||||||
## 29 - INTRO
|
## 29 - INTRO
|
||||||
Until a bastard arrives...
|
Until a bastard arrives...
|
||||||
|
|
||||||
## 30 - INTRO
|
## 30 - INTRO
|
||||||
YO! GONNA TAKE A CAFELITO...
|
YO! GONNA TAKE A CAFELITO...
|
||||||
|
|
||||||
## 31 - INTRO
|
## 31 - INTRO
|
||||||
AAAAAAAARGHHHH!!!
|
AAAAAAAARGHHHH!!!
|
||||||
|
|
||||||
## 32 - INTRO
|
## 32 - INTRO
|
||||||
Wait a moment...
|
Wait a moment...
|
||||||
|
|
||||||
## 33 - INTRO
|
## 33 - INTRO
|
||||||
I don't have any loose!
|
I don't have any loose!
|
||||||
|
|
||||||
## 34 - INTRO
|
## 34 - INTRO
|
||||||
FUCKING MACHINE!
|
FUCKING MACHINE!
|
||||||
|
|
||||||
## 35 - INTRO
|
## 35 - INTRO
|
||||||
Blop... blop... blop...
|
Blop... blop... blop...
|
||||||
|
|
||||||
## 36 - TEXTOS DEL JUEGO
|
## 36 - TEXTOS DEL JUEGO
|
||||||
Time stopped:
|
Time stopped:
|
||||||
|
|
||||||
## 37 - TEXTOS DEL JUEGO
|
## 37 - TEXTOS DEL JUEGO
|
||||||
D E M O
|
D E M O
|
||||||
|
|
||||||
## 38 - TEXTOS DEL JUEGO
|
## 38 - TEXTOS DEL JUEGO
|
||||||
stages left!
|
stages left!
|
||||||
## 39 -
|
|
||||||
|
|
||||||
## 40 -
|
## 39 - MENU SELECCION DE JUGADOR
|
||||||
|
Select Player
|
||||||
|
|
||||||
## 41 -
|
## 40 - MENU SELECCION DE JUGADOR
|
||||||
|
Back
|
||||||
|
|
||||||
## 42 -
|
## 41 - MENU DE PAUSA
|
||||||
|
Pause Menu
|
||||||
|
|
||||||
|
## 42 - TABLA DE RECORDS
|
||||||
|
Best scores
|
||||||
|
|
||||||
## 43 - PANTALLA DE GAME OVER
|
## 43 - PANTALLA DE GAME OVER
|
||||||
GAME OVER
|
GAME OVER
|
||||||
|
|
||||||
## 44 - PANTALLA DE GAME OVER
|
## 44 - PANTALLA DE GAME OVER
|
||||||
YOUR SCORE:
|
YOUR SCORE:
|
||||||
|
|
||||||
## 45 - PANTALLA DE GAME OVER
|
## 45 - PANTALLA DE GAME OVER
|
||||||
CONTINUE?
|
CONTINUE?
|
||||||
|
|
||||||
## 46 - MENU DE PAUSA
|
## 46 - MENU DE PAUSA
|
||||||
CONTINUE
|
CONTINUE
|
||||||
|
|
||||||
## 47 - MENU DE PAUSA
|
## 47 - MENU DE PAUSA
|
||||||
LEAVE GAME
|
LEAVE GAME
|
||||||
|
|
||||||
## 48 - MENU GAME OVER
|
## 48 - MENU GAME OVER
|
||||||
YES
|
YES
|
||||||
|
|
||||||
## 49 - MENU GAME OVER
|
## 49 - MENU GAME OVER
|
||||||
NO
|
NO
|
||||||
|
|
||||||
## 50 - TEXTO DE COMPLETAR EL JUEGO
|
## 50 - TEXTO DE COMPLETAR EL JUEGO
|
||||||
Congratulations!!
|
Congratulations!!
|
||||||
|
|
||||||
## 51 - MENU DEL TITULO
|
## 51 - MENU DEL TITULO
|
||||||
1 PLAYER
|
1 PLAYER
|
||||||
|
|
||||||
## 52 - MENU DEL TITULO
|
## 52 - MENU DEL TITULO
|
||||||
2 PLAYERS
|
2 PLAYERS
|
||||||
|
|
||||||
## 53 - MARCADOR
|
## 53 - MARCADOR
|
||||||
player 1
|
player 1
|
||||||
|
|
||||||
## 54 - MARCADOR
|
## 54 - MARCADOR
|
||||||
player 2
|
player 2
|
||||||
|
|
||||||
## 55 - MARCADOR
|
## 55 - MARCADOR
|
||||||
mult
|
mult
|
||||||
|
|
||||||
## 56 - MARCADOR
|
## 56 - MARCADOR
|
||||||
high score
|
high score
|
||||||
|
|
||||||
## 57 - MARCADOR
|
## 57 - MARCADOR
|
||||||
stage
|
stage
|
||||||
|
|
||||||
## 58 - MENU DE OPCIONES
|
## 58 - MENU DE OPCIONES
|
||||||
DISPLAY MODE
|
DISPLAY MODE
|
||||||
|
|
||||||
## 59 - MENU DE OPCIONES
|
## 59 - MENU DE OPCIONES
|
||||||
DIFFICULTY
|
DIFFICULTY
|
||||||
|
|
||||||
## 60 - MENU DE OPCIONES
|
## 60 - MENU DE OPCIONES
|
||||||
FILTER
|
FILTER
|
||||||
|
|
||||||
## 61 - MENU DE OPCIONES
|
## 61 - MENU DE OPCIONES
|
||||||
VSYNC
|
VSYNC
|
||||||
|
|
||||||
## 62 - MENU DE OPCIONES
|
## 62 - MENU DE OPCIONES
|
||||||
PLAYER 1 CONTROLS
|
PLAYER 1 CONTROLS
|
||||||
|
|
||||||
## 63 - MENU DE OPCIONES
|
## 63 - MENU DE OPCIONES
|
||||||
PLAYER 2 CONTROLS
|
PLAYER 2 CONTROLS
|
||||||
## 64 -
|
|
||||||
|
## 64 - MENU DE OPCIONES
|
||||||
|
(OFFLINE MODE)
|
||||||
|
|
||||||
## 65 -
|
## 65 -
|
||||||
|
-
|
||||||
|
|
||||||
## 66 - MENU DE OPCIONES
|
## 66 - MENU DE OPCIONES
|
||||||
EASY
|
EASY
|
||||||
|
|
||||||
## 67 - MENU DE OPCIONES
|
## 67 - MENU DE OPCIONES
|
||||||
NORMAL
|
NORMAL
|
||||||
|
|
||||||
## 68 - MENU DE OPCIONES
|
## 68 - MENU DE OPCIONES
|
||||||
HARD
|
HARD
|
||||||
|
|
||||||
## 69 - MENU DE OPCIONES
|
## 69 - MENU DE OPCIONES
|
||||||
KEYBOARD
|
KEYBOARD
|
||||||
|
|
||||||
## 70 - MENU DE OPCIONES
|
## 70 - MENU DE OPCIONES
|
||||||
GAME CONTROLLER
|
GAME CONTROLLER
|
||||||
|
|
||||||
## 71 - MENU DE OPCIONES
|
## 71 - MENU DE OPCIONES
|
||||||
LINEAL
|
LINEAL
|
||||||
|
|
||||||
## 72 - MENU DE OPCIONES
|
## 72 - MENU DE OPCIONES
|
||||||
NEAREST
|
NEAREST
|
||||||
|
|
||||||
## 73 - MENU DE OPCIONES
|
## 73 - MENU DE OPCIONES
|
||||||
ON
|
ON
|
||||||
|
|
||||||
## 74 - MENU DE OPCIONES
|
## 74 - MENU DE OPCIONES
|
||||||
OFF
|
OFF
|
||||||
|
|
||||||
## 75 - JUEGO
|
## 75 - JUEGO
|
||||||
Get Ready!
|
Get Ready!
|
||||||
|
|
||||||
## 76 - JUEGO
|
## 76 - JUEGO
|
||||||
1.000.000 points!
|
1.000.000 points!
|
||||||
|
|
||||||
## 77 - PANTALLA DE GAME OVER
|
## 77 - PANTALLA DE GAME OVER
|
||||||
PLAYER1 SCORE:
|
PLAYER1 SCORE:
|
||||||
|
|
||||||
## 78 - PANTALLA DE GAME OVER
|
## 78 - PANTALLA DE GAME OVER
|
||||||
PLAYER2 SCORE:
|
PLAYER2 SCORE:
|
||||||
|
|
||||||
## 79 - TEXTOS DEL JUEGO
|
## 79 - TEXTOS DEL JUEGO
|
||||||
Last stage!
|
Last stage!
|
||||||
|
|
||||||
|
## 80 - NOTIFICACIONES
|
||||||
|
Failed connecting to
|
||||||
|
|
||||||
|
## 81 - NOTIFICACIONES
|
||||||
|
Can't get
|
||||||
|
|
||||||
|
## 82 - NOTIFICACIONES
|
||||||
|
online scores
|
||||||
|
|
||||||
|
## 83 - NOTIFICACIONES
|
||||||
|
No JailerID
|
||||||
|
|
||||||
|
## 84 - NOTIFICACIONES
|
||||||
|
name was set
|
||||||
|
|
||||||
|
## 85 - NOTIFICACIONES
|
||||||
|
is logged in
|
||||||
|
|
||||||
|
## 86 - NOTIFICACIONES
|
||||||
|
Score submitted
|
||||||
|
|
||||||
|
## 87 - NOTIFICACIONES
|
||||||
|
Failed to send
|
||||||
|
|
||||||
|
## 88 - NOTIFICACIONES
|
||||||
|
score to online server
|
||||||
|
|
||||||
|
## 89 - ENTER ID
|
||||||
|
ONLINE CONFIGURATION
|
||||||
|
|
||||||
|
## 90 - ENTER ID
|
||||||
|
PLEASE ENTER AN ID
|
||||||
|
|
||||||
|
## 91 - ENTER ID
|
||||||
|
LEAVE BLANK FOR
|
||||||
|
|
||||||
|
## 92 - ENTER ID
|
||||||
|
OFFLINE MODE
|
||||||
|
|
||||||
|
## 93 - MENU OPCIONES
|
||||||
|
HISCORE TABLE
|
||||||
|
|
||||||
|
## 94 - GAMEPAD NOTIFICATION
|
||||||
|
CONNECTED
|
||||||
|
|
||||||
|
## 95 - GAMEPAD NOTIFICATION
|
||||||
|
DISCONNECTED
|
||||||
@@ -1,160 +1,287 @@
|
|||||||
## 0 - MENU DEL TITULO
|
## 0 - MENU DEL TITULO
|
||||||
JUGAR
|
JUGAR
|
||||||
|
|
||||||
## 1 - MENU DEL TITULO
|
## 1 - MENU DEL TITULO
|
||||||
OPCIONES
|
OPCIONES
|
||||||
|
|
||||||
## 2 - MENU DEL TITULO
|
## 2 - MENU DEL TITULO
|
||||||
INSTRUCCIONES
|
INSTRUCCIONES
|
||||||
|
|
||||||
## 3 - MENU DEL TITULO
|
## 3 - MENU DEL TITULO
|
||||||
SALIR
|
SALIR
|
||||||
|
|
||||||
## 4 - MENU DE OPCIONES
|
## 4 - MENU DE OPCIONES
|
||||||
VENTANA
|
VENTANA
|
||||||
|
|
||||||
## 5 - MENU DE OPCIONES
|
## 5 - MENU DE OPCIONES
|
||||||
PANTALLA COMPLETA
|
PANTALLA COMPLETA
|
||||||
|
|
||||||
## 6 - MENU DE OPCIONES
|
## 6 - MENU DE OPCIONES
|
||||||
PANTALLA COMPLETA FALSA
|
PANTALLA COMPLETA FALSA
|
||||||
|
|
||||||
## 7 - MENU DE OPCIONES
|
## 7 - MENU DE OPCIONES
|
||||||
TAMA{O DE VENTANA
|
TAMA{O DE VENTANA
|
||||||
|
|
||||||
## 8 - MENU DE OPCIONES
|
## 8 - MENU DE OPCIONES
|
||||||
IDIOMA
|
IDIOMA
|
||||||
|
|
||||||
## 9 - MENU DE OPCIONES
|
## 9 - MENU DE OPCIONES
|
||||||
[ ACEPTAR ]
|
[ ACEPTAR ]
|
||||||
|
|
||||||
## 10 - MENU DE OPCIONES
|
## 10 - MENU DE OPCIONES
|
||||||
[ CANCELAR ]
|
[ CANCELAR ]
|
||||||
|
|
||||||
## 11 - INSTRUCCIONES
|
## 11 - INSTRUCCIONES
|
||||||
OBJETIVO
|
OBJETIVO
|
||||||
|
|
||||||
## 12 - INSTRUCCIONES
|
## 12 - INSTRUCCIONES
|
||||||
TIENES QUE EXPLOTAR
|
TIENES QUE EXPLOTAR
|
||||||
|
|
||||||
## 13 - INSTRUCCIONES
|
## 13 - INSTRUCCIONES
|
||||||
TANTOS GLOBOS COMO PUEDAS
|
TANTOS GLOBOS COMO PUEDAS
|
||||||
|
|
||||||
## 14 - INSTRUCCIONES
|
## 14 - INSTRUCCIONES
|
||||||
LA DIFICULTAD SE INCREMENTA
|
LA DIFICULTAD SE INCREMENTA
|
||||||
|
|
||||||
## 15 - INSTRUCCIONES
|
## 15 - INSTRUCCIONES
|
||||||
A MEDIDA QUE VAS PUNTUANDO
|
A MEDIDA QUE VAS PUNTUANDO
|
||||||
|
|
||||||
## 16 - INSTRUCCIONES
|
## 16 - INSTRUCCIONES
|
||||||
OBJETOS
|
OBJETOS
|
||||||
|
|
||||||
## 17 - INSTRUCCIONES
|
## 17 - INSTRUCCIONES
|
||||||
1.000 PUNTOS
|
1.000 PUNTOS
|
||||||
|
|
||||||
## 18 - INSTRUCCIONES
|
## 18 - INSTRUCCIONES
|
||||||
2.500 PUNTOS
|
2.500 PUNTOS
|
||||||
|
|
||||||
## 19 - INSTRUCCIONES
|
## 19 - INSTRUCCIONES
|
||||||
5.000 PUNTOS
|
5.000 PUNTOS
|
||||||
|
|
||||||
## 20 - INSTRUCCIONES
|
## 20 - INSTRUCCIONES
|
||||||
DETIENE EL TIEMPO
|
DETIENE EL TIEMPO
|
||||||
|
|
||||||
## 21 - INSTRUCCIONES
|
## 21 - INSTRUCCIONES
|
||||||
VIDA EXTRA
|
VIDA EXTRA
|
||||||
|
|
||||||
## 22 - INSTRUCCIONES
|
## 22 - INSTRUCCIONES
|
||||||
PULSA UNA TECLA PARA VOLVER
|
PULSA UNA TECLA PARA VOLVER
|
||||||
|
|
||||||
## 23 - TITULO
|
## 23 - TITULO
|
||||||
PULSA CUALQUIER TECLA
|
PULSA CUALQUIER TECLA
|
||||||
|
|
||||||
## 24 - MENU SELECCION DE IDIOMA
|
## 24 - MENU SELECCION DE IDIOMA
|
||||||
ESPA{OL
|
ESPA{OL
|
||||||
|
|
||||||
## 25 - MENU SELECCION DE IDIOMA
|
## 25 - MENU SELECCION DE IDIOMA
|
||||||
BALOONCIA (VALENCIANO)
|
BALOONCIA (VALENCIANO)
|
||||||
|
|
||||||
## 26 - MENU SELECCION DE IDIOMA
|
## 26 - MENU SELECCION DE IDIOMA
|
||||||
ENGLISH (INGLES)
|
ENGLISH (INGLES)
|
||||||
|
|
||||||
## 27 - INTRO
|
## 27 - INTRO
|
||||||
Un dia cualquiera del a{o 2000
|
Un dia cualquiera del a{o 2000
|
||||||
|
|
||||||
## 28 - INTRO
|
## 28 - INTRO
|
||||||
Todo esta tranquilo en la UPV
|
Todo esta tranquilo en la UPV
|
||||||
|
|
||||||
## 29 - INTRO
|
## 29 - INTRO
|
||||||
Hasta que un desaprensivo...
|
Hasta que un desaprensivo...
|
||||||
|
|
||||||
## 30 - INTRO
|
## 30 - INTRO
|
||||||
HEY! VOY A SACARME UN TALLADET...
|
HEY! VOY A SACARME UN TALLADET...
|
||||||
|
|
||||||
## 31 - INTRO
|
## 31 - INTRO
|
||||||
UAAAAAAAAAAAAA!!!
|
UAAAAAAAAAAAAA!!!
|
||||||
|
|
||||||
## 32 - INTRO
|
## 32 - INTRO
|
||||||
Espera un momento...
|
Espera un momento...
|
||||||
|
|
||||||
## 33 - INTRO
|
## 33 - INTRO
|
||||||
Si no llevo suelto encima!
|
Si no llevo suelto encima!
|
||||||
|
|
||||||
## 34 - INTRO
|
## 34 - INTRO
|
||||||
MIERDA DE MAQUINA!
|
MIERDA DE MAQUINA!
|
||||||
|
|
||||||
## 35 - INTRO
|
## 35 - INTRO
|
||||||
Blop... blop... blop...
|
Blop... blop... blop...
|
||||||
|
|
||||||
## 36 - TEXTOS DEL JUEGO
|
## 36 - TEXTOS DEL JUEGO
|
||||||
Tiempo:
|
Tiempo:
|
||||||
|
|
||||||
## 37 - TEXTOS DEL JUEGO
|
## 37 - TEXTOS DEL JUEGO
|
||||||
D E M O
|
D E M O
|
||||||
|
|
||||||
## 38 - TEXTOS DEL JUEGO
|
## 38 - TEXTOS DEL JUEGO
|
||||||
fases mas!
|
fases mas!
|
||||||
## 39 -
|
|
||||||
|
|
||||||
## 40 -
|
## 39 - MENU SELECCION DE JUGADOR
|
||||||
|
Selecciona jugador
|
||||||
|
|
||||||
## 41 -
|
## 40 - MENU SELECCION DE JUGADOR
|
||||||
|
Volver
|
||||||
|
|
||||||
## 42 -
|
## 41 - MENU DE PAUSA
|
||||||
|
Menu de pausa
|
||||||
|
|
||||||
|
## 42 - TABLA DE RECORDS
|
||||||
|
Mejores puntuaciones
|
||||||
|
|
||||||
## 43 - PANTALLA DE GAME OVER
|
## 43 - PANTALLA DE GAME OVER
|
||||||
FIN DE JUEGO
|
FIN DE JUEGO
|
||||||
|
|
||||||
## 44 - PANTALLA DE GAME OVER
|
## 44 - PANTALLA DE GAME OVER
|
||||||
TU PUNTUACION:
|
TU PUNTUACION:
|
||||||
|
|
||||||
## 45 - PANTALLA DE GAME OVER
|
## 45 - PANTALLA DE GAME OVER
|
||||||
CONTINUAR?
|
CONTINUAR?
|
||||||
|
|
||||||
## 46 - MENU DE PAUSA
|
## 46 - MENU DE PAUSA
|
||||||
CONTINUAR
|
CONTINUAR
|
||||||
|
|
||||||
## 47 - MENU DE PAUSA
|
## 47 - MENU DE PAUSA
|
||||||
SALIR DEL JUEGO
|
SALIR DEL JUEGO
|
||||||
|
|
||||||
## 48 - MENU GAME OVER
|
## 48 - MENU GAME OVER
|
||||||
SI
|
SI
|
||||||
|
|
||||||
## 49 - MENU GAME OVER
|
## 49 - MENU GAME OVER
|
||||||
NO
|
NO
|
||||||
|
|
||||||
## 50 - TEXTO DE COMPLETAR EL JUEGO
|
## 50 - TEXTO DE COMPLETAR EL JUEGO
|
||||||
Felicidades!!
|
Felicidades!!
|
||||||
|
|
||||||
## 51 - MENU DEL TITULO
|
## 51 - MENU DEL TITULO
|
||||||
1 JUGADOR
|
1 JUGADOR
|
||||||
|
|
||||||
## 52 - MENU DEL TITULO
|
## 52 - MENU DEL TITULO
|
||||||
2 JUGADORES
|
2 JUGADORES
|
||||||
|
|
||||||
## 53 - MARCADOR
|
## 53 - MARCADOR
|
||||||
jugador 1
|
jugador 1
|
||||||
|
|
||||||
## 54 - MARCADOR
|
## 54 - MARCADOR
|
||||||
jugador 2
|
jugador 2
|
||||||
|
|
||||||
## 55 - MARCADOR
|
## 55 - MARCADOR
|
||||||
mult
|
mult
|
||||||
|
|
||||||
## 56 - MARCADOR
|
## 56 - MARCADOR
|
||||||
max. puntuacion
|
max. puntuacion
|
||||||
|
|
||||||
## 57 - MARCADOR
|
## 57 - MARCADOR
|
||||||
FASE
|
FASE
|
||||||
|
|
||||||
## 58 - MENU DE OPCIONES
|
## 58 - MENU DE OPCIONES
|
||||||
MODO DE VISUALIZACION
|
MODO DE VISUALIZACION
|
||||||
|
|
||||||
## 59 - MENU DE OPCIONES
|
## 59 - MENU DE OPCIONES
|
||||||
DIFICULTAD
|
DIFICULTAD
|
||||||
|
|
||||||
## 60 - MENU DE OPCIONES
|
## 60 - MENU DE OPCIONES
|
||||||
FILTRO
|
FILTRO
|
||||||
|
|
||||||
## 61 - MENU DE OPCIONES
|
## 61 - MENU DE OPCIONES
|
||||||
SINC. VERTICAL
|
SINC. VERTICAL
|
||||||
|
|
||||||
## 62 - MENU DE OPCIONES
|
## 62 - MENU DE OPCIONES
|
||||||
CONTROLES DEL JUGADOR 1
|
CONTROLES DEL JUGADOR 1
|
||||||
|
|
||||||
## 63 - MENU DE OPCIONES
|
## 63 - MENU DE OPCIONES
|
||||||
CONTROLES DEL JUGADOR 2
|
CONTROLES DEL JUGADOR 2
|
||||||
## 64 -
|
|
||||||
|
## 64 - MENU DE OPCIONES
|
||||||
|
(MODO OFFLINE)
|
||||||
|
|
||||||
## 65 -
|
## 65 -
|
||||||
|
-
|
||||||
|
|
||||||
## 66 - MENU DE OPCIONES
|
## 66 - MENU DE OPCIONES
|
||||||
FACIL
|
FACIL
|
||||||
|
|
||||||
## 67 - MENU DE OPCIONES
|
## 67 - MENU DE OPCIONES
|
||||||
NORMAL
|
NORMAL
|
||||||
|
|
||||||
## 68 - MENU DE OPCIONES
|
## 68 - MENU DE OPCIONES
|
||||||
DIFICIL
|
DIFICIL
|
||||||
|
|
||||||
## 69 - MENU DE OPCIONES
|
## 69 - MENU DE OPCIONES
|
||||||
TECLADO
|
TECLADO
|
||||||
|
|
||||||
## 70 - MENU DE OPCIONES
|
## 70 - MENU DE OPCIONES
|
||||||
MANDO
|
MANDO
|
||||||
|
|
||||||
## 71 - MENU DE OPCIONES
|
## 71 - MENU DE OPCIONES
|
||||||
LINEAL
|
LINEAL
|
||||||
|
|
||||||
## 72 - MENU DE OPCIONES
|
## 72 - MENU DE OPCIONES
|
||||||
NEAREST
|
NEAREST
|
||||||
|
|
||||||
## 73 - MENU DE OPCIONES
|
## 73 - MENU DE OPCIONES
|
||||||
ACTIVADA
|
ACTIVADA
|
||||||
|
|
||||||
## 74 - MENU DE OPCIONES
|
## 74 - MENU DE OPCIONES
|
||||||
DESACTIVADA
|
DESACTIVADA
|
||||||
|
|
||||||
## 75 - JUEGO
|
## 75 - JUEGO
|
||||||
Adelante!
|
Adelante!
|
||||||
|
|
||||||
## 76 - JUEGO
|
## 76 - JUEGO
|
||||||
1.000.000 de puntos!
|
1.000.000 de puntos!
|
||||||
|
|
||||||
## 77 - PANTALLA DE GAME OVER
|
## 77 - PANTALLA DE GAME OVER
|
||||||
PUNTUACION J1:
|
PUNTUACION J1:
|
||||||
|
|
||||||
## 78 - PANTALLA DE GAME OVER
|
## 78 - PANTALLA DE GAME OVER
|
||||||
PUNTUACION J2:
|
PUNTUACION J2:
|
||||||
|
|
||||||
## 79 - TEXTOS DEL JUEGO
|
## 79 - TEXTOS DEL JUEGO
|
||||||
Ultima fase!
|
Ultima fase!
|
||||||
|
|
||||||
|
## 80 - NOTIFICACIONES
|
||||||
|
Fallo al conectar a
|
||||||
|
|
||||||
|
## 81 - NOTIFICACIONES
|
||||||
|
No se ha podido obtener
|
||||||
|
|
||||||
|
## 82 - NOTIFICACIONES
|
||||||
|
la puntuacion online
|
||||||
|
|
||||||
|
## 83 - NOTIFICACIONES
|
||||||
|
No se ha especificado
|
||||||
|
|
||||||
|
## 84 - NOTIFICACIONES
|
||||||
|
ningun jailerID
|
||||||
|
|
||||||
|
## 85 - NOTIFICACIONES
|
||||||
|
ha iniciado la sesion
|
||||||
|
|
||||||
|
## 86 - NOTIFICACIONES
|
||||||
|
Puntos enviados:
|
||||||
|
|
||||||
|
## 87 - NOTIFICACIONES
|
||||||
|
No se ha podido
|
||||||
|
|
||||||
|
## 88 - NOTIFICACIONES
|
||||||
|
enviar la puntuacion
|
||||||
|
|
||||||
|
## 89 - ENTER ID
|
||||||
|
CONFIGURACION ONLNE
|
||||||
|
|
||||||
|
## 90 - ENTER ID
|
||||||
|
INTRODUCE UN JAILER_ID
|
||||||
|
|
||||||
|
## 91 - ENTER ID
|
||||||
|
DEJA EN BLANCO PARA
|
||||||
|
|
||||||
|
## 92 - ENTER ID
|
||||||
|
MODO SIN CONEXION
|
||||||
|
|
||||||
|
## 93 - MENU OPCIONES
|
||||||
|
TABLA DE PUNTUACIONES
|
||||||
|
|
||||||
|
## 94 - NOTIFICACION MANDO
|
||||||
|
CONECTADO
|
||||||
|
|
||||||
|
## 95 - NOTIFICACION MANDO
|
||||||
|
DESCONECTADO
|
||||||
29
data/menu/gameover.men
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
font_png=smb2.png
|
||||||
|
font_txt=smb2.txt
|
||||||
|
|
||||||
|
sound_move=menu_move.wav
|
||||||
|
sound_accept=menu_select.wav
|
||||||
|
|
||||||
|
name=GAME OVER
|
||||||
|
x=0
|
||||||
|
y=120
|
||||||
|
backgroundType=0
|
||||||
|
backgroundColor=128,64,0,0
|
||||||
|
|
||||||
|
areElementsCenteredOnX=true
|
||||||
|
isCenteredOnX=true
|
||||||
|
centerX=199
|
||||||
|
|
||||||
|
selector_color=255,122,0,255
|
||||||
|
selector_text_color=255,255,235
|
||||||
|
|
||||||
|
defaultActionWhenCancel=1
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=SI
|
||||||
|
hPaddingDown=2
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=NO
|
||||||
|
[/item]
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
font_png=smb2.png
|
font_png=smb2.png
|
||||||
font_txt=smb2.txt
|
font_txt=smb2.txt
|
||||||
|
|
||||||
sound_cancel=menu_cancel.wav
|
|
||||||
sound_accept=menu_select.wav
|
|
||||||
sound_move=menu_move.wav
|
sound_move=menu_move.wav
|
||||||
|
sound_accept=menu_select.wav
|
||||||
|
|
||||||
name=OPTIONS
|
name=OPTIONS
|
||||||
x=0
|
x=0
|
||||||
@@ -19,14 +18,15 @@ centerX=128
|
|||||||
isCenteredOnY=true
|
isCenteredOnY=true
|
||||||
centerY=96
|
centerY=96
|
||||||
|
|
||||||
selector_color=229,28,35,255
|
selector_color=255,122,0,255
|
||||||
selector_text_color=255,180,0
|
selector_text_color=127,61,0,255
|
||||||
|
|
||||||
defaultActionWhenCancel=13
|
defaultActionWhenCancel=15
|
||||||
|
|
||||||
[item]
|
[item]
|
||||||
text=DIFFICULTY
|
text=DIFFICULTY
|
||||||
hPaddingDown=7
|
hPaddingDown=6
|
||||||
|
line=true
|
||||||
[/item]
|
[/item]
|
||||||
|
|
||||||
[item]
|
[item]
|
||||||
@@ -39,7 +39,8 @@ linkedDown=true
|
|||||||
|
|
||||||
[item]
|
[item]
|
||||||
text=KEYBOARD
|
text=KEYBOARD
|
||||||
hPaddingDown=7
|
hPaddingDown=6
|
||||||
|
line=true
|
||||||
selectable=false
|
selectable=false
|
||||||
greyed=false
|
greyed=false
|
||||||
[/item]
|
[/item]
|
||||||
@@ -54,14 +55,16 @@ linkedDown=true
|
|||||||
|
|
||||||
[item]
|
[item]
|
||||||
text=GAME CONTROLLER
|
text=GAME CONTROLLER
|
||||||
hPaddingDown=7
|
hPaddingDown=6
|
||||||
|
line=true
|
||||||
selectable=false
|
selectable=false
|
||||||
greyed=false
|
greyed=false
|
||||||
[/item]
|
[/item]
|
||||||
|
|
||||||
[item]
|
[item]
|
||||||
text=LANGUAGE
|
text=LANGUAGE
|
||||||
hPaddingDown=7
|
hPaddingDown=6
|
||||||
|
line=true
|
||||||
[/item]
|
[/item]
|
||||||
|
|
||||||
[item]
|
[item]
|
||||||
@@ -74,7 +77,8 @@ linkedDown=true
|
|||||||
|
|
||||||
[item]
|
[item]
|
||||||
text=WINDOW
|
text=WINDOW
|
||||||
hPaddingDown=7
|
hPaddingDown=6
|
||||||
|
line=true
|
||||||
selectable=false
|
selectable=false
|
||||||
greyed=false
|
greyed=false
|
||||||
[/item]
|
[/item]
|
||||||
@@ -91,12 +95,13 @@ hPaddingDown=2
|
|||||||
|
|
||||||
[item]
|
[item]
|
||||||
text=VSYNC
|
text=VSYNC
|
||||||
hPaddingDown=7
|
hPaddingDown=6
|
||||||
|
line=true
|
||||||
[/item]
|
[/item]
|
||||||
|
|
||||||
[item]
|
[item]
|
||||||
text=HOW TO PLAY
|
text=HOW TO PLAY
|
||||||
hPaddingDown=7
|
hPaddingDown=10
|
||||||
[/item]
|
[/item]
|
||||||
|
|
||||||
[item]
|
[item]
|
||||||
|
|||||||
110
data/menu/options_gc.men
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
font_png=smb2.png
|
||||||
|
font_txt=smb2.txt
|
||||||
|
|
||||||
|
sound_move=menu_move.wav
|
||||||
|
sound_accept=menu_select.wav
|
||||||
|
|
||||||
|
name=OPTIONS
|
||||||
|
x=0
|
||||||
|
y=116
|
||||||
|
backgroundType=0
|
||||||
|
backgroundColor=48,48,64,192
|
||||||
|
|
||||||
|
areElementsCenteredOnX=true
|
||||||
|
|
||||||
|
isCenteredOnX=true
|
||||||
|
centerX=128
|
||||||
|
|
||||||
|
isCenteredOnY=true
|
||||||
|
centerY=96
|
||||||
|
|
||||||
|
selector_color=255,122,0,255
|
||||||
|
selector_text_color=127,61,0,255
|
||||||
|
|
||||||
|
defaultActionWhenCancel=13
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=DIFFICULTY
|
||||||
|
hPaddingDown=7
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=PLAYER 1 CONTROLS
|
||||||
|
hPaddingDown=2
|
||||||
|
selectable=false
|
||||||
|
greyed=true
|
||||||
|
linkedDown=true
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=KEYBOARD
|
||||||
|
hPaddingDown=7
|
||||||
|
selectable=false
|
||||||
|
greyed=true
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=PLAYER 2 CONTROLS
|
||||||
|
hPaddingDown=2
|
||||||
|
selectable=false
|
||||||
|
greyed=true
|
||||||
|
linkedDown=true
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=GAME CONTROLLER
|
||||||
|
hPaddingDown=7
|
||||||
|
selectable=false
|
||||||
|
greyed=false
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=LANGUAGE
|
||||||
|
hPaddingDown=7
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=DISPLAY MODE
|
||||||
|
hPaddingDown=2
|
||||||
|
selectable=false
|
||||||
|
greyed=true
|
||||||
|
linkedDown=true
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=WINDOW
|
||||||
|
hPaddingDown=7
|
||||||
|
selectable=false
|
||||||
|
greyed=true
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=WINDOW SIZE
|
||||||
|
hPaddingDown=2
|
||||||
|
selectable=false
|
||||||
|
greyed=true
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=FILTER
|
||||||
|
hPaddingDown=2
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=VSYNC
|
||||||
|
hPaddingDown=7
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=HOW TO PLAY
|
||||||
|
hPaddingDown=7
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=ACCEPT
|
||||||
|
hPaddingDown=2
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=CANCEL
|
||||||
|
[/item]
|
||||||
35
data/menu/pause.men
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
font_png=smb2.png
|
||||||
|
font_txt=smb2.txt
|
||||||
|
|
||||||
|
sound_move=menu_move.wav
|
||||||
|
sound_accept=menu_select.wav
|
||||||
|
|
||||||
|
name=PAUSE
|
||||||
|
x=0
|
||||||
|
y=80
|
||||||
|
backgroundType=1
|
||||||
|
backgroundColor=41,57,65,240
|
||||||
|
|
||||||
|
areElementsCenteredOnX=true
|
||||||
|
isCenteredOnX=true
|
||||||
|
centerX=128
|
||||||
|
|
||||||
|
selector_color=255,122,0,255
|
||||||
|
selector_text_color=255,255,255
|
||||||
|
|
||||||
|
defaultActionWhenCancel=1
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=PAUSE MENU
|
||||||
|
hPaddingDown=7
|
||||||
|
selectable=false
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=CONTINUE
|
||||||
|
hPaddingDown=2
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=LEAVE GAME
|
||||||
|
[/item]
|
||||||
40
data/menu/player_select.men
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
font_png=smb2.png
|
||||||
|
font_txt=smb2.txt
|
||||||
|
|
||||||
|
sound_move=menu_move.wav
|
||||||
|
sound_accept=menu_select.wav
|
||||||
|
|
||||||
|
name=PLAYER_SELECT
|
||||||
|
x=0
|
||||||
|
y=116
|
||||||
|
backgroundType=0
|
||||||
|
backgroundColor=48,48,64,192
|
||||||
|
|
||||||
|
areElementsCenteredOnX=true
|
||||||
|
isCenteredOnX=true
|
||||||
|
centerX=128
|
||||||
|
|
||||||
|
selector_color=255,122,0,255
|
||||||
|
selector_text_color=127,61,0,255
|
||||||
|
|
||||||
|
defaultActionWhenCancel=3
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=SELECT PLAYER
|
||||||
|
hPaddingDown=7
|
||||||
|
selectable=false
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=BAL1
|
||||||
|
hPaddingDown=2
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=AROUNDER
|
||||||
|
hPaddingDown=7
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=BACK
|
||||||
|
[/item]
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
font_png=smb2.png
|
font_png=smb2.png
|
||||||
font_txt=smb2.txt
|
font_txt=smb2.txt
|
||||||
|
|
||||||
sound_cancel=menu_cancel.wav
|
|
||||||
sound_accept=menu_select.wav
|
|
||||||
sound_move=menu_move.wav
|
sound_move=menu_move.wav
|
||||||
|
sound_accept=menu_select.wav
|
||||||
|
|
||||||
name=TITLE
|
name=TITLE
|
||||||
x=0
|
x=0
|
||||||
@@ -15,8 +14,8 @@ areElementsCenteredOnX=true
|
|||||||
isCenteredOnX=true
|
isCenteredOnX=true
|
||||||
centerX=128
|
centerX=128
|
||||||
|
|
||||||
selector_color=229,28,35,0
|
selector_color=255,122,0,255
|
||||||
selector_text_color=255,180,0
|
selector_text_color=127,61,0,255
|
||||||
|
|
||||||
defaultActionWhenCancel=3
|
defaultActionWhenCancel=3
|
||||||
|
|
||||||
|
|||||||
41
data/menu/title_gc.men
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
font_png=smb2.png
|
||||||
|
font_txt=smb2.txt
|
||||||
|
|
||||||
|
sound_move=menu_move.wav
|
||||||
|
sound_accept=menu_select.wav
|
||||||
|
|
||||||
|
name=TITLE
|
||||||
|
x=0
|
||||||
|
y=116
|
||||||
|
backgroundType=0
|
||||||
|
backgroundColor=48,48,64,192
|
||||||
|
|
||||||
|
areElementsCenteredOnX=true
|
||||||
|
isCenteredOnX=true
|
||||||
|
centerX=128
|
||||||
|
|
||||||
|
selector_color=255,122,0,255
|
||||||
|
selector_text_color=127,61,0,255
|
||||||
|
|
||||||
|
defaultActionWhenCancel=3
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=PLAY
|
||||||
|
hPaddingDown=2
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=2 PLAYERS
|
||||||
|
hPaddingDown=7
|
||||||
|
visible=false
|
||||||
|
selectable=false
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=OPTIONS
|
||||||
|
hPaddingDown=7
|
||||||
|
[/item]
|
||||||
|
|
||||||
|
[item]
|
||||||
|
text=QUIT
|
||||||
|
[/item]
|
||||||
152
data/shaders/crtpi_frag.glsl
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// Vulkan GLSL fragment shader — CRT-Pi PostFX
|
||||||
|
// Algoritmo de scanlines continuas con pesos gaussianos, bloom y máscara de fósforo.
|
||||||
|
// Basado en el shader CRT-Pi original (GLSL 3.3), portado a GLSL 4.50 con parámetros uniformes.
|
||||||
|
//
|
||||||
|
// Compile: glslc -fshader-stage=frag --target-env=vulkan1.0 crtpi_frag.glsl -o crtpi_frag.spv
|
||||||
|
// xxd -i crtpi_frag.spv > ../../source/core/rendering/sdl3gpu/crtpi_frag_spv.h
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 v_uv;
|
||||||
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform sampler2D Texture;
|
||||||
|
|
||||||
|
layout(set = 3, binding = 0) uniform CrtPiBlock {
|
||||||
|
// vec4 #0
|
||||||
|
float scanline_weight; // Ajuste gaussiano de scanlines (default 6.0)
|
||||||
|
float scanline_gap_brightness; // Brillo mínimo entre scanlines (default 0.12)
|
||||||
|
float bloom_factor; // Factor de brillo en zonas iluminadas (default 3.5)
|
||||||
|
float input_gamma; // Gamma de entrada — linealización (default 2.4)
|
||||||
|
// vec4 #1
|
||||||
|
float output_gamma; // Gamma de salida — codificación (default 2.2)
|
||||||
|
float mask_brightness; // Brillo sub-píxeles de la máscara (default 0.80)
|
||||||
|
float curvature_x; // Distorsión barrel eje X (default 0.05)
|
||||||
|
float curvature_y; // Distorsión barrel eje Y (default 0.10)
|
||||||
|
// vec4 #2
|
||||||
|
int mask_type; // 0=ninguna, 1=verde/magenta, 2=RGB fósforo
|
||||||
|
int enable_scanlines; // 0 = off, 1 = on
|
||||||
|
int enable_multisample; // 0 = off, 1 = on (antialiasing analítico de scanlines)
|
||||||
|
int enable_gamma; // 0 = off, 1 = on
|
||||||
|
// vec4 #3
|
||||||
|
int enable_curvature; // 0 = off, 1 = on
|
||||||
|
int enable_sharper; // 0 = off, 1 = on
|
||||||
|
float texture_width; // Ancho del canvas lógico en píxeles
|
||||||
|
float texture_height; // Alto del canvas lógico en píxeles
|
||||||
|
} u;
|
||||||
|
|
||||||
|
// Distorsión barrel CRT
|
||||||
|
vec2 distort(vec2 coord, vec2 screen_scale) {
|
||||||
|
vec2 curvature = vec2(u.curvature_x, u.curvature_y);
|
||||||
|
vec2 barrel_scale = 1.0 - (0.23 * curvature);
|
||||||
|
coord *= screen_scale;
|
||||||
|
coord -= vec2(0.5);
|
||||||
|
float rsq = coord.x * coord.x + coord.y * coord.y;
|
||||||
|
coord += coord * (curvature * rsq);
|
||||||
|
coord *= barrel_scale;
|
||||||
|
if (abs(coord.x) >= 0.5 || abs(coord.y) >= 0.5) {
|
||||||
|
return vec2(-1.0); // fuera de pantalla
|
||||||
|
}
|
||||||
|
coord += vec2(0.5);
|
||||||
|
coord /= screen_scale;
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcScanLineWeight(float dist) {
|
||||||
|
return max(1.0 - dist * dist * u.scanline_weight, u.scanline_gap_brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcScanLine(float dy, float filter_width) {
|
||||||
|
float weight = calcScanLineWeight(dy);
|
||||||
|
if (u.enable_multisample != 0) {
|
||||||
|
weight += calcScanLineWeight(dy - filter_width);
|
||||||
|
weight += calcScanLineWeight(dy + filter_width);
|
||||||
|
weight *= 0.3333333;
|
||||||
|
}
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 tex_size = vec2(u.texture_width, u.texture_height);
|
||||||
|
|
||||||
|
// filterWidth: equivalente al original (768.0 / TextureSize.y) / 3.0
|
||||||
|
float filter_width = (768.0 / u.texture_height) / 3.0;
|
||||||
|
|
||||||
|
vec2 texcoord = v_uv;
|
||||||
|
|
||||||
|
// Curvatura barrel opcional
|
||||||
|
if (u.enable_curvature != 0) {
|
||||||
|
texcoord = distort(texcoord, vec2(1.0, 1.0));
|
||||||
|
if (texcoord.x < 0.0) {
|
||||||
|
out_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 texcoord_in_pixels = texcoord * tex_size;
|
||||||
|
vec2 tc;
|
||||||
|
float scan_line_weight;
|
||||||
|
|
||||||
|
if (u.enable_sharper != 0) {
|
||||||
|
// Modo SHARPER: filtrado bicúbico-like con subpixel sharpen
|
||||||
|
vec2 temp_coord = floor(texcoord_in_pixels) + 0.5;
|
||||||
|
tc = temp_coord / tex_size;
|
||||||
|
vec2 deltas = texcoord_in_pixels - temp_coord;
|
||||||
|
scan_line_weight = calcScanLine(deltas.y, filter_width);
|
||||||
|
vec2 signs = sign(deltas);
|
||||||
|
deltas.x *= 2.0;
|
||||||
|
deltas = deltas * deltas;
|
||||||
|
deltas.y = deltas.y * deltas.y;
|
||||||
|
deltas.x *= 0.5;
|
||||||
|
deltas.y *= 8.0;
|
||||||
|
deltas /= tex_size;
|
||||||
|
deltas *= signs;
|
||||||
|
tc = tc + deltas;
|
||||||
|
} else {
|
||||||
|
// Modo estándar
|
||||||
|
float temp_y = floor(texcoord_in_pixels.y) + 0.5;
|
||||||
|
float y_coord = temp_y / tex_size.y;
|
||||||
|
float dy = texcoord_in_pixels.y - temp_y;
|
||||||
|
scan_line_weight = calcScanLine(dy, filter_width);
|
||||||
|
float sign_y = sign(dy);
|
||||||
|
dy = dy * dy;
|
||||||
|
dy = dy * dy;
|
||||||
|
dy *= 8.0;
|
||||||
|
dy /= tex_size.y;
|
||||||
|
dy *= sign_y;
|
||||||
|
tc = vec2(texcoord.x, y_coord + dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 colour = texture(Texture, tc).rgb;
|
||||||
|
|
||||||
|
if (u.enable_scanlines != 0) {
|
||||||
|
if (u.enable_gamma != 0) {
|
||||||
|
colour = pow(colour, vec3(u.input_gamma));
|
||||||
|
}
|
||||||
|
colour *= scan_line_weight * u.bloom_factor;
|
||||||
|
if (u.enable_gamma != 0) {
|
||||||
|
colour = pow(colour, vec3(1.0 / u.output_gamma));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Máscara de fósforo
|
||||||
|
if (u.mask_type == 1) {
|
||||||
|
float which_mask = fract(gl_FragCoord.x * 0.5);
|
||||||
|
vec3 mask = (which_mask < 0.5)
|
||||||
|
? vec3(u.mask_brightness, 1.0, u.mask_brightness)
|
||||||
|
: vec3(1.0, u.mask_brightness, 1.0);
|
||||||
|
colour *= mask;
|
||||||
|
} else if (u.mask_type == 2) {
|
||||||
|
float which_mask = fract(gl_FragCoord.x * 0.3333333);
|
||||||
|
vec3 mask = vec3(u.mask_brightness);
|
||||||
|
if (which_mask < 0.3333333)
|
||||||
|
mask.x = 1.0;
|
||||||
|
else if (which_mask < 0.6666666)
|
||||||
|
mask.y = 1.0;
|
||||||
|
else
|
||||||
|
mask.z = 1.0;
|
||||||
|
colour *= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_color = vec4(colour, 1.0);
|
||||||
|
}
|
||||||
48
data/shaders/downscale.frag
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
142
data/shaders/postfx.frag
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// Vulkan GLSL fragment shader — PostFX effects
|
||||||
|
// Used for SDL3 GPU API (SPIR-V path, Win/Linux).
|
||||||
|
// Compile: glslc postfx.frag -o postfx.frag.spv
|
||||||
|
// xxd -i postfx.frag.spv > ../../source/core/rendering/sdl3gpu/postfx_frag_spv.h
|
||||||
|
//
|
||||||
|
// PostFXUniforms must match exactly the C++ struct in sdl3gpu_shader.hpp
|
||||||
|
// (8 floats, 32 bytes, std140/scalar layout).
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 v_uv;
|
||||||
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform sampler2D scene;
|
||||||
|
|
||||||
|
layout(set = 3, binding = 0) uniform PostFXUniforms {
|
||||||
|
float vignette_strength;
|
||||||
|
float chroma_strength;
|
||||||
|
float scanline_strength;
|
||||||
|
float screen_height;
|
||||||
|
float mask_strength;
|
||||||
|
float gamma_strength;
|
||||||
|
float curvature;
|
||||||
|
float bleeding;
|
||||||
|
float pixel_scale; // physical pixels per logical pixel (vh / tex_height_)
|
||||||
|
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 — 48 bytes total (3 × 16)
|
||||||
|
} u;
|
||||||
|
|
||||||
|
// YCbCr helpers for NTSC bleeding
|
||||||
|
vec3 rgb_to_ycc(vec3 rgb) {
|
||||||
|
return vec3(
|
||||||
|
0.299*rgb.r + 0.587*rgb.g + 0.114*rgb.b,
|
||||||
|
-0.169*rgb.r - 0.331*rgb.g + 0.500*rgb.b + 0.5,
|
||||||
|
0.500*rgb.r - 0.419*rgb.g - 0.081*rgb.b + 0.5
|
||||||
|
);
|
||||||
|
}
|
||||||
|
vec3 ycc_to_rgb(vec3 ycc) {
|
||||||
|
float y = ycc.x;
|
||||||
|
float cb = ycc.y - 0.5;
|
||||||
|
float cr = ycc.z - 0.5;
|
||||||
|
return clamp(vec3(
|
||||||
|
y + 1.402*cr,
|
||||||
|
y - 0.344*cb - 0.714*cr,
|
||||||
|
y + 1.772*cb
|
||||||
|
), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = v_uv;
|
||||||
|
|
||||||
|
// Curvatura barrel CRT
|
||||||
|
if (u.curvature > 0.0) {
|
||||||
|
vec2 c = uv - 0.5;
|
||||||
|
float rsq = dot(c, c);
|
||||||
|
vec2 dist = vec2(0.05, 0.1) * u.curvature;
|
||||||
|
vec2 barrelScale = vec2(1.0) - 0.23 * dist;
|
||||||
|
c += c * (dist * rsq);
|
||||||
|
c *= barrelScale;
|
||||||
|
if (abs(c.x) >= 0.5 || abs(c.y) >= 0.5) {
|
||||||
|
out_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uv = c + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Muestra base
|
||||||
|
vec3 base = texture(scene, uv).rgb;
|
||||||
|
|
||||||
|
// Sangrado NTSC — difuminado horizontal de crominancia.
|
||||||
|
// step = 1 pixel lógico de juego en UV (corrige SS: textureSize.x = game_w * oversample).
|
||||||
|
vec3 colour;
|
||||||
|
if (u.bleeding > 0.0) {
|
||||||
|
float tw = float(textureSize(scene, 0).x);
|
||||||
|
float step = u.oversample / tw; // 1 pixel lógico en UV
|
||||||
|
vec3 ycc = rgb_to_ycc(base);
|
||||||
|
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_r1 = rgb_to_ycc(texture(scene, uv + vec2(1.0*step, 0.0)).rgb);
|
||||||
|
vec3 ycc_r2 = rgb_to_ycc(texture(scene, uv + vec2(2.0*step, 0.0)).rgb);
|
||||||
|
ycc.yz = (ycc_l2.yz + ycc_l1.yz*2.0 + ycc.yz*2.0 + ycc_r1.yz*2.0 + ycc_r2.yz) / 8.0;
|
||||||
|
colour = mix(base, ycc_to_rgb(ycc), u.bleeding);
|
||||||
|
} else {
|
||||||
|
colour = base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aberración cromática (drift animado con time para efecto NTSC real)
|
||||||
|
float ca = u.chroma_strength * 0.005 * (1.0 + 0.15 * sin(u.time * 7.3));
|
||||||
|
colour.r = texture(scene, uv + vec2(ca, 0.0)).r;
|
||||||
|
colour.b = texture(scene, uv - vec2(ca, 0.0)).b;
|
||||||
|
|
||||||
|
// Corrección gamma (linealizar antes de scanlines, codificar después)
|
||||||
|
if (u.gamma_strength > 0.0) {
|
||||||
|
vec3 lin = pow(colour, vec3(2.4));
|
||||||
|
colour = mix(colour, lin, u.gamma_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scanlines — 1 pixel físico oscuro por fila lógica.
|
||||||
|
// Modelo sustractivo: las filas de scanline se oscurecen, las demás no cambian.
|
||||||
|
// Esto evita el efecto de sobrebrillo en contenido con colores vivos.
|
||||||
|
if (u.scanline_strength > 0.0) {
|
||||||
|
float ps = max(1.0, round(u.pixel_scale));
|
||||||
|
float frac_in_row = fract(uv.y * u.screen_height);
|
||||||
|
float row_pos = floor(frac_in_row * ps);
|
||||||
|
float is_dark = step(ps - 1.0, row_pos);
|
||||||
|
float scan = mix(1.0, 0.0, is_dark);
|
||||||
|
colour *= mix(1.0, scan, u.scanline_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u.gamma_strength > 0.0) {
|
||||||
|
vec3 enc = pow(colour, vec3(1.0 / 2.2));
|
||||||
|
colour = mix(colour, enc, u.gamma_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Viñeta
|
||||||
|
vec2 d = uv - 0.5;
|
||||||
|
float vignette = 1.0 - dot(d, d) * u.vignette_strength;
|
||||||
|
colour *= clamp(vignette, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Máscara de fósforo RGB — después de scanlines (orden original):
|
||||||
|
// filas brillantes saturadas → máscara invisible, filas oscuras → RGB visible.
|
||||||
|
if (u.mask_strength > 0.0) {
|
||||||
|
float whichMask = fract(gl_FragCoord.x * 0.3333333);
|
||||||
|
vec3 mask = vec3(0.80);
|
||||||
|
if (whichMask < 0.3333333)
|
||||||
|
mask.x = 1.0;
|
||||||
|
else if (whichMask < 0.6666666)
|
||||||
|
mask.y = 1.0;
|
||||||
|
else
|
||||||
|
mask.z = 1.0;
|
||||||
|
colour = mix(colour, colour * mask, u.mask_strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parpadeo de fósforo CRT (~50 Hz)
|
||||||
|
if (u.flicker > 0.0) {
|
||||||
|
float flicker_wave = sin(u.time * 100.0) * 0.5 + 0.5;
|
||||||
|
colour *= 1.0 - u.flicker * 0.04 * flicker_wave;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_color = vec4(colour, 1.0);
|
||||||
|
}
|
||||||
24
data/shaders/postfx.vert
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
// Vulkan GLSL vertex shader — postfx full-screen triangle
|
||||||
|
// Used for SDL3 GPU API (SPIR-V path, Win/Linux).
|
||||||
|
// Compile: glslc postfx.vert -o postfx.vert.spv
|
||||||
|
// xxd -i postfx.vert.spv > ../../source/core/rendering/sdl3gpu/postfx_vert_spv.h
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 v_uv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Full-screen triangle (no vertex buffer needed)
|
||||||
|
const vec2 positions[3] = vec2[3](
|
||||||
|
vec2(-1.0, -1.0),
|
||||||
|
vec2( 3.0, -1.0),
|
||||||
|
vec2(-1.0, 3.0)
|
||||||
|
);
|
||||||
|
const vec2 uvs[3] = vec2[3](
|
||||||
|
vec2(0.0, 1.0),
|
||||||
|
vec2(2.0, 1.0),
|
||||||
|
vec2(0.0,-1.0)
|
||||||
|
);
|
||||||
|
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||||
|
v_uv = uvs[gl_VertexIndex];
|
||||||
|
}
|
||||||
15
data/shaders/upscale.frag
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
2232
gamecontrollerdb.txt
Normal file
BIN
release/icons/icon.icns
Normal file
BIN
release/icons/icon.ico
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
release/icons/icon.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
42
release/macos/Info.plist
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>es</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>coffee_crisis</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>coffee_crisis</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>icon</string>
|
||||||
|
<key>CFBundleIconName</key>
|
||||||
|
<string>icon</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>net.jailgames.coffee_crisis</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>coffee_crisis</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>2.3.2</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>2.3.2</string>
|
||||||
|
<key>CSResourcesFileMapped</key>
|
||||||
|
<true/>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.12</string>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>Copyright 2023 JailDesigner</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
<key>SUPublicDSAKeyFile</key>
|
||||||
|
<string>dsa_pub.pem</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
90
release/macos/frameworks/SDL3.xcframework/Info.plist
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AvailableLibraries</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>BinaryPath</key>
|
||||||
|
<string>SDL3.framework/Versions/A/SDL3</string>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>macos-arm64_x86_64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>SDL3.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>macos</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>BinaryPath</key>
|
||||||
|
<string>SDL3.framework/SDL3</string>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>tvos-arm64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>SDL3.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>tvos</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>BinaryPath</key>
|
||||||
|
<string>SDL3.framework/SDL3</string>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>SDL3.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>BinaryPath</key>
|
||||||
|
<string>SDL3.framework/SDL3</string>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>ios-arm64_x86_64-simulator</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>SDL3.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>ios</string>
|
||||||
|
<key>SupportedPlatformVariant</key>
|
||||||
|
<string>simulator</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>BinaryPath</key>
|
||||||
|
<string>SDL3.framework/SDL3</string>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>tvos-arm64_x86_64-simulator</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>SDL3.framework</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
<string>x86_64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>tvos</string>
|
||||||
|
<key>SupportedPlatformVariant</key>
|
||||||
|
<string>simulator</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>XFWK</string>
|
||||||
|
<key>XCFrameworkFormatVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Versions/Current/Headers
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Versions/Current/Resources
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Versions/Current/SDL3
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main include header for the SDL library, version 3.2.20
|
||||||
|
*
|
||||||
|
* It is almost always best to include just this one header instead of
|
||||||
|
* picking out individual headers included here. There are exceptions to
|
||||||
|
* this rule--SDL_main.h is special and not included here--but usually
|
||||||
|
* letting SDL.h include the kitchen sink for you is the correct approach.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_h_
|
||||||
|
#define SDL_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
#include <SDL3/SDL_assert.h>
|
||||||
|
#include <SDL3/SDL_asyncio.h>
|
||||||
|
#include <SDL3/SDL_atomic.h>
|
||||||
|
#include <SDL3/SDL_audio.h>
|
||||||
|
#include <SDL3/SDL_bits.h>
|
||||||
|
#include <SDL3/SDL_blendmode.h>
|
||||||
|
#include <SDL3/SDL_camera.h>
|
||||||
|
#include <SDL3/SDL_clipboard.h>
|
||||||
|
#include <SDL3/SDL_cpuinfo.h>
|
||||||
|
#include <SDL3/SDL_dialog.h>
|
||||||
|
#include <SDL3/SDL_endian.h>
|
||||||
|
#include <SDL3/SDL_error.h>
|
||||||
|
#include <SDL3/SDL_events.h>
|
||||||
|
#include <SDL3/SDL_filesystem.h>
|
||||||
|
#include <SDL3/SDL_gamepad.h>
|
||||||
|
#include <SDL3/SDL_gpu.h>
|
||||||
|
#include <SDL3/SDL_guid.h>
|
||||||
|
#include <SDL3/SDL_haptic.h>
|
||||||
|
#include <SDL3/SDL_hidapi.h>
|
||||||
|
#include <SDL3/SDL_hints.h>
|
||||||
|
#include <SDL3/SDL_init.h>
|
||||||
|
#include <SDL3/SDL_iostream.h>
|
||||||
|
#include <SDL3/SDL_joystick.h>
|
||||||
|
#include <SDL3/SDL_keyboard.h>
|
||||||
|
#include <SDL3/SDL_keycode.h>
|
||||||
|
#include <SDL3/SDL_loadso.h>
|
||||||
|
#include <SDL3/SDL_locale.h>
|
||||||
|
#include <SDL3/SDL_log.h>
|
||||||
|
#include <SDL3/SDL_messagebox.h>
|
||||||
|
#include <SDL3/SDL_metal.h>
|
||||||
|
#include <SDL3/SDL_misc.h>
|
||||||
|
#include <SDL3/SDL_mouse.h>
|
||||||
|
#include <SDL3/SDL_mutex.h>
|
||||||
|
#include <SDL3/SDL_pen.h>
|
||||||
|
#include <SDL3/SDL_pixels.h>
|
||||||
|
#include <SDL3/SDL_platform.h>
|
||||||
|
#include <SDL3/SDL_power.h>
|
||||||
|
#include <SDL3/SDL_process.h>
|
||||||
|
#include <SDL3/SDL_properties.h>
|
||||||
|
#include <SDL3/SDL_rect.h>
|
||||||
|
#include <SDL3/SDL_render.h>
|
||||||
|
#include <SDL3/SDL_scancode.h>
|
||||||
|
#include <SDL3/SDL_sensor.h>
|
||||||
|
#include <SDL3/SDL_storage.h>
|
||||||
|
#include <SDL3/SDL_surface.h>
|
||||||
|
#include <SDL3/SDL_system.h>
|
||||||
|
#include <SDL3/SDL_thread.h>
|
||||||
|
#include <SDL3/SDL_time.h>
|
||||||
|
#include <SDL3/SDL_timer.h>
|
||||||
|
#include <SDL3/SDL_tray.h>
|
||||||
|
#include <SDL3/SDL_touch.h>
|
||||||
|
#include <SDL3/SDL_version.h>
|
||||||
|
#include <SDL3/SDL_video.h>
|
||||||
|
#include <SDL3/SDL_oldnames.h>
|
||||||
|
|
||||||
|
#endif /* SDL_h_ */
|
||||||
@@ -0,0 +1,662 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryAssert
|
||||||
|
*
|
||||||
|
* A helpful assertion macro!
|
||||||
|
*
|
||||||
|
* SDL assertions operate like your usual `assert` macro, but with some added
|
||||||
|
* features:
|
||||||
|
*
|
||||||
|
* - It uses a trick with the `sizeof` operator, so disabled assertions
|
||||||
|
* vaporize out of the compiled code, but variables only referenced in the
|
||||||
|
* assertion won't trigger compiler warnings about being unused.
|
||||||
|
* - It is safe to use with a dangling-else: `if (x) SDL_assert(y); else
|
||||||
|
* do_something();`
|
||||||
|
* - It works the same everywhere, instead of counting on various platforms'
|
||||||
|
* compiler and C runtime to behave.
|
||||||
|
* - It provides multiple levels of assertion (SDL_assert, SDL_assert_release,
|
||||||
|
* SDL_assert_paranoid) instead of a single all-or-nothing option.
|
||||||
|
* - It offers a variety of responses when an assertion fails (retry, trigger
|
||||||
|
* the debugger, abort the program, ignore the failure once, ignore it for
|
||||||
|
* the rest of the program's run).
|
||||||
|
* - It tries to show the user a dialog by default, if possible, but the app
|
||||||
|
* can provide a callback to handle assertion failures however they like.
|
||||||
|
* - It lets failed assertions be retried. Perhaps you had a network failure
|
||||||
|
* and just want to retry the test after plugging your network cable back
|
||||||
|
* in? You can.
|
||||||
|
* - It lets the user ignore an assertion failure, if there's a harmless
|
||||||
|
* problem that one can continue past.
|
||||||
|
* - It lets the user mark an assertion as ignored for the rest of the
|
||||||
|
* program's run; if there's a harmless problem that keeps popping up.
|
||||||
|
* - It provides statistics and data on all failed assertions to the app.
|
||||||
|
* - It allows the default assertion handler to be controlled with environment
|
||||||
|
* variables, in case an automated script needs to control it.
|
||||||
|
* - It can be used as an aid to Clang's static analysis; it will treat SDL
|
||||||
|
* assertions as universally true (under the assumption that you are serious
|
||||||
|
* about the asserted claims and that your debug builds will detect when
|
||||||
|
* these claims were wrong). This can help the analyzer avoid false
|
||||||
|
* positives.
|
||||||
|
*
|
||||||
|
* To use it: compile a debug build and just sprinkle around tests to check
|
||||||
|
* your code!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_assert_h_
|
||||||
|
#define SDL_assert_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_begin_code.h>
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The level of assertion aggressiveness.
|
||||||
|
*
|
||||||
|
* This value changes depending on compiler options and other preprocessor
|
||||||
|
* defines.
|
||||||
|
*
|
||||||
|
* It is currently one of the following values, but future SDL releases might
|
||||||
|
* add more:
|
||||||
|
*
|
||||||
|
* - 0: All SDL assertion macros are disabled.
|
||||||
|
* - 1: Release settings: SDL_assert disabled, SDL_assert_release enabled.
|
||||||
|
* - 2: Debug settings: SDL_assert and SDL_assert_release enabled.
|
||||||
|
* - 3: Paranoid settings: All SDL assertion macros enabled, including
|
||||||
|
* SDL_assert_paranoid.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_ASSERT_LEVEL SomeNumberBasedOnVariousFactors
|
||||||
|
|
||||||
|
#elif !defined(SDL_ASSERT_LEVEL)
|
||||||
|
#ifdef SDL_DEFAULT_ASSERT_LEVEL
|
||||||
|
#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL
|
||||||
|
#elif defined(_DEBUG) || defined(DEBUG) || \
|
||||||
|
(defined(__GNUC__) && !defined(__OPTIMIZE__))
|
||||||
|
#define SDL_ASSERT_LEVEL 2
|
||||||
|
#else
|
||||||
|
#define SDL_ASSERT_LEVEL 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to tell an attached debugger to pause.
|
||||||
|
*
|
||||||
|
* This allows an app to programmatically halt ("break") the debugger as if it
|
||||||
|
* had hit a breakpoint, allowing the developer to examine program state, etc.
|
||||||
|
*
|
||||||
|
* This is a macro--not a function--so that the debugger breaks on the source
|
||||||
|
* code line that used SDL_TriggerBreakpoint and not in some random guts of
|
||||||
|
* SDL. SDL_assert uses this macro for the same reason.
|
||||||
|
*
|
||||||
|
* If the program is not running under a debugger, SDL_TriggerBreakpoint will
|
||||||
|
* likely terminate the app, possibly without warning. If the current platform
|
||||||
|
* isn't supported, this macro is left undefined.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this macro from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner
|
||||||
|
|
||||||
|
#elif defined(_MSC_VER) && _MSC_VER >= 1310
|
||||||
|
/* Don't include intrin.h here because it contains C++ code */
|
||||||
|
extern void __cdecl __debugbreak(void);
|
||||||
|
#define SDL_TriggerBreakpoint() __debugbreak()
|
||||||
|
#elif defined(_MSC_VER) && defined(_M_IX86)
|
||||||
|
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
|
||||||
|
#elif defined(ANDROID)
|
||||||
|
#include <assert.h>
|
||||||
|
#define SDL_TriggerBreakpoint() assert(0)
|
||||||
|
#elif SDL_HAS_BUILTIN(__builtin_debugtrap)
|
||||||
|
#define SDL_TriggerBreakpoint() __builtin_debugtrap()
|
||||||
|
#elif SDL_HAS_BUILTIN(__builtin_trap)
|
||||||
|
#define SDL_TriggerBreakpoint() __builtin_trap()
|
||||||
|
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
|
||||||
|
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
|
||||||
|
#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv)
|
||||||
|
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" )
|
||||||
|
#elif ( defined(SDL_PLATFORM_APPLE) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */
|
||||||
|
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" )
|
||||||
|
#elif defined(SDL_PLATFORM_APPLE) && defined(__arm__)
|
||||||
|
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" )
|
||||||
|
#elif defined(_WIN32) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__)) )
|
||||||
|
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #0xF000\n\t" )
|
||||||
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define SDL_TriggerBreakpoint() __builtin_trap() /* older gcc may not support SDL_HAS_BUILTIN(__builtin_trap) above */
|
||||||
|
#elif defined(__386__) && defined(__WATCOMC__)
|
||||||
|
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
|
||||||
|
#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__)
|
||||||
|
#include <signal.h>
|
||||||
|
#define SDL_TriggerBreakpoint() raise(SIGTRAP)
|
||||||
|
#else
|
||||||
|
/* SDL_TriggerBreakpoint is intentionally left undefined on unknown platforms. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro that reports the current function being compiled.
|
||||||
|
*
|
||||||
|
* If SDL can't figure how the compiler reports this, it will use "???".
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_FUNCTION __FUNCTION__
|
||||||
|
|
||||||
|
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */
|
||||||
|
# define SDL_FUNCTION __func__
|
||||||
|
#elif ((defined(__GNUC__) && (__GNUC__ >= 2)) || defined(_MSC_VER) || defined (__WATCOMC__))
|
||||||
|
# define SDL_FUNCTION __FUNCTION__
|
||||||
|
#else
|
||||||
|
# define SDL_FUNCTION "???"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro that reports the current file being compiled.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_FILE __FILE__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro that reports the current line number of the file being compiled.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_LINE __LINE__
|
||||||
|
|
||||||
|
/*
|
||||||
|
sizeof (x) makes the compiler still parse the expression even without
|
||||||
|
assertions enabled, so the code is always checked at compile time, but
|
||||||
|
doesn't actually generate code for it, so there are no side effects or
|
||||||
|
expensive checks at run time, just the constant size of what x WOULD be,
|
||||||
|
which presumably gets optimized out as unused.
|
||||||
|
This also solves the problem of...
|
||||||
|
|
||||||
|
int somevalue = blah();
|
||||||
|
SDL_assert(somevalue == 1);
|
||||||
|
|
||||||
|
...which would cause compiles to complain that somevalue is unused if we
|
||||||
|
disable assertions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro for wrapping code in `do {} while (0);` without compiler warnings.
|
||||||
|
*
|
||||||
|
* Visual Studio with really aggressive warnings enabled needs this to avoid
|
||||||
|
* compiler complaints.
|
||||||
|
*
|
||||||
|
* the `do {} while (0);` trick is useful for wrapping code in a macro that
|
||||||
|
* may or may not be a single statement, to avoid various C language
|
||||||
|
* accidents.
|
||||||
|
*
|
||||||
|
* To use:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* do { SomethingOnce(); } while (SDL_NULL_WHILE_LOOP_CONDITION (0));
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_NULL_WHILE_LOOP_CONDITION (0)
|
||||||
|
|
||||||
|
#elif defined(_MSC_VER) /* Avoid /W4 warnings. */
|
||||||
|
/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking
|
||||||
|
this condition isn't constant. And looks like an owl's face! */
|
||||||
|
#define SDL_NULL_WHILE_LOOP_CONDITION (0,0)
|
||||||
|
#else
|
||||||
|
#define SDL_NULL_WHILE_LOOP_CONDITION (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The macro used when an assertion is disabled.
|
||||||
|
*
|
||||||
|
* This isn't for direct use by apps, but this is the code that is inserted
|
||||||
|
* when an SDL_assert is disabled (perhaps in a release build).
|
||||||
|
*
|
||||||
|
* The code does nothing, but wraps `condition` in a sizeof operator, which
|
||||||
|
* generates no code and has no side effects, but avoid compiler warnings
|
||||||
|
* about unused variables.
|
||||||
|
*
|
||||||
|
* \param condition the condition to assert (but not actually run here).
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_disabled_assert(condition) \
|
||||||
|
do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible outcomes from a triggered assertion.
|
||||||
|
*
|
||||||
|
* When an enabled assertion triggers, it may call the assertion handler
|
||||||
|
* (possibly one provided by the app via SDL_SetAssertionHandler), which will
|
||||||
|
* return one of these values, possibly after asking the user.
|
||||||
|
*
|
||||||
|
* Then SDL will respond based on this outcome (loop around to retry the
|
||||||
|
* condition, try to break in a debugger, kill the program, or ignore the
|
||||||
|
* problem).
|
||||||
|
*
|
||||||
|
* \since This enum is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef enum SDL_AssertState
|
||||||
|
{
|
||||||
|
SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */
|
||||||
|
SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */
|
||||||
|
SDL_ASSERTION_ABORT, /**< Terminate the program. */
|
||||||
|
SDL_ASSERTION_IGNORE, /**< Ignore the assert. */
|
||||||
|
SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */
|
||||||
|
} SDL_AssertState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about an assertion failure.
|
||||||
|
*
|
||||||
|
* This structure is filled in with information about a triggered assertion,
|
||||||
|
* used by the assertion handler, then added to the assertion report. This is
|
||||||
|
* returned as a linked list from SDL_GetAssertionReport().
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef struct SDL_AssertData
|
||||||
|
{
|
||||||
|
bool always_ignore; /**< true if app should always continue when assertion is triggered. */
|
||||||
|
unsigned int trigger_count; /**< Number of times this assertion has been triggered. */
|
||||||
|
const char *condition; /**< A string of this assert's test code. */
|
||||||
|
const char *filename; /**< The source file where this assert lives. */
|
||||||
|
int linenum; /**< The line in `filename` where this assert lives. */
|
||||||
|
const char *function; /**< The name of the function where this assert lives. */
|
||||||
|
const struct SDL_AssertData *next; /**< next item in the linked list. */
|
||||||
|
} SDL_AssertData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Never call this directly.
|
||||||
|
*
|
||||||
|
* Use the SDL_assert macros instead.
|
||||||
|
*
|
||||||
|
* \param data assert data structure.
|
||||||
|
* \param func function name.
|
||||||
|
* \param file file name.
|
||||||
|
* \param line line number.
|
||||||
|
* \returns assert state.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *data,
|
||||||
|
const char *func,
|
||||||
|
const char *file, int line) SDL_ANALYZER_NORETURN;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The macro used when an assertion triggers a breakpoint.
|
||||||
|
*
|
||||||
|
* This isn't for direct use by apps; use SDL_assert or SDL_TriggerBreakpoint
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_AssertBreakpoint() SDL_TriggerBreakpoint()
|
||||||
|
|
||||||
|
#elif !defined(SDL_AssertBreakpoint)
|
||||||
|
# if defined(ANDROID) && defined(assert)
|
||||||
|
/* Define this as empty in case assert() is defined as SDL_assert */
|
||||||
|
# define SDL_AssertBreakpoint()
|
||||||
|
# else
|
||||||
|
# define SDL_AssertBreakpoint() SDL_TriggerBreakpoint()
|
||||||
|
# endif
|
||||||
|
#endif /* !SDL_AssertBreakpoint */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The macro used when an assertion is enabled.
|
||||||
|
*
|
||||||
|
* This isn't for direct use by apps, but this is the code that is inserted
|
||||||
|
* when an SDL_assert is enabled.
|
||||||
|
*
|
||||||
|
* The `do {} while(0)` avoids dangling else problems:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* if (x) SDL_assert(y); else blah();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ... without the do/while, the "else" could attach to this macro's "if". We
|
||||||
|
* try to handle just the minimum we need here in a macro...the loop, the
|
||||||
|
* static vars, and break points. The heavy lifting is handled in
|
||||||
|
* SDL_ReportAssertion().
|
||||||
|
*
|
||||||
|
* \param condition the condition to assert.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_enabled_assert(condition) \
|
||||||
|
do { \
|
||||||
|
while ( !(condition) ) { \
|
||||||
|
static struct SDL_AssertData sdl_assert_data = { false, 0, #condition, NULL, 0, NULL, NULL }; \
|
||||||
|
const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
|
||||||
|
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
|
||||||
|
continue; /* go again. */ \
|
||||||
|
} else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \
|
||||||
|
SDL_AssertBreakpoint(); \
|
||||||
|
} \
|
||||||
|
break; /* not retrying. */ \
|
||||||
|
} \
|
||||||
|
} while (SDL_NULL_WHILE_LOOP_CONDITION)
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assertion test that is normally performed only in debug builds.
|
||||||
|
*
|
||||||
|
* This macro is enabled when the SDL_ASSERT_LEVEL is >= 2, otherwise it is
|
||||||
|
* disabled. This is meant to only do these tests in debug builds, so they can
|
||||||
|
* tend to be more expensive, and they are meant to bring everything to a halt
|
||||||
|
* when they fail, with the programmer there to assess the problem.
|
||||||
|
*
|
||||||
|
* In short: you can sprinkle these around liberally and assume they will
|
||||||
|
* evaporate out of the build when building for end-users.
|
||||||
|
*
|
||||||
|
* When assertions are disabled, this wraps `condition` in a `sizeof`
|
||||||
|
* operator, which means any function calls and side effects will not run, but
|
||||||
|
* the compiler will not complain about any otherwise-unused variables that
|
||||||
|
* are only referenced in the assertion.
|
||||||
|
*
|
||||||
|
* One can set the environment variable "SDL_ASSERT" to one of several strings
|
||||||
|
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
|
||||||
|
* behavior, which may be desirable for automation purposes. If your platform
|
||||||
|
* requires GUI interfaces to happen on the main thread but you're debugging
|
||||||
|
* an assertion in a background thread, it might be desirable to set this to
|
||||||
|
* "break" so that your debugger takes control as soon as assert is triggered,
|
||||||
|
* instead of risking a bad UI interaction (deadlock, etc) in the application.
|
||||||
|
*
|
||||||
|
* \param condition boolean value to test.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this macro from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_assert(condition) if (assertion_enabled && (condition)) { trigger_assertion; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assertion test that is performed even in release builds.
|
||||||
|
*
|
||||||
|
* This macro is enabled when the SDL_ASSERT_LEVEL is >= 1, otherwise it is
|
||||||
|
* disabled. This is meant to be for tests that are cheap to make and
|
||||||
|
* extremely unlikely to fail; generally it is frowned upon to have an
|
||||||
|
* assertion failure in a release build, so these assertions generally need to
|
||||||
|
* be of more than life-and-death importance if there's a chance they might
|
||||||
|
* trigger. You should almost always consider handling these cases more
|
||||||
|
* gracefully than an assert allows.
|
||||||
|
*
|
||||||
|
* When assertions are disabled, this wraps `condition` in a `sizeof`
|
||||||
|
* operator, which means any function calls and side effects will not run, but
|
||||||
|
* the compiler will not complain about any otherwise-unused variables that
|
||||||
|
* are only referenced in the assertion.
|
||||||
|
*
|
||||||
|
* One can set the environment variable "SDL_ASSERT" to one of several strings
|
||||||
|
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
|
||||||
|
* behavior, which may be desirable for automation purposes. If your platform
|
||||||
|
* requires GUI interfaces to happen on the main thread but you're debugging
|
||||||
|
* an assertion in a background thread, it might be desirable to set this to
|
||||||
|
* "break" so that your debugger takes control as soon as assert is triggered,
|
||||||
|
* instead of risking a bad UI interaction (deadlock, etc) in the application.
|
||||||
|
* *
|
||||||
|
*
|
||||||
|
* \param condition boolean value to test.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this macro from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_assert_release(condition) SDL_disabled_assert(condition)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assertion test that is performed only when built with paranoid settings.
|
||||||
|
*
|
||||||
|
* This macro is enabled when the SDL_ASSERT_LEVEL is >= 3, otherwise it is
|
||||||
|
* disabled. This is a higher level than both release and debug, so these
|
||||||
|
* tests are meant to be expensive and only run when specifically looking for
|
||||||
|
* extremely unexpected failure cases in a special build.
|
||||||
|
*
|
||||||
|
* When assertions are disabled, this wraps `condition` in a `sizeof`
|
||||||
|
* operator, which means any function calls and side effects will not run, but
|
||||||
|
* the compiler will not complain about any otherwise-unused variables that
|
||||||
|
* are only referenced in the assertion.
|
||||||
|
*
|
||||||
|
* One can set the environment variable "SDL_ASSERT" to one of several strings
|
||||||
|
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
|
||||||
|
* behavior, which may be desirable for automation purposes. If your platform
|
||||||
|
* requires GUI interfaces to happen on the main thread but you're debugging
|
||||||
|
* an assertion in a background thread, it might be desirable to set this to
|
||||||
|
* "break" so that your debugger takes control as soon as assert is triggered,
|
||||||
|
* instead of risking a bad UI interaction (deadlock, etc) in the application.
|
||||||
|
*
|
||||||
|
* \param condition boolean value to test.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this macro from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
|
||||||
|
|
||||||
|
/* Enable various levels of assertions. */
|
||||||
|
#elif SDL_ASSERT_LEVEL == 0 /* assertions disabled */
|
||||||
|
# define SDL_assert(condition) SDL_disabled_assert(condition)
|
||||||
|
# define SDL_assert_release(condition) SDL_disabled_assert(condition)
|
||||||
|
# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
|
||||||
|
#elif SDL_ASSERT_LEVEL == 1 /* release settings. */
|
||||||
|
# define SDL_assert(condition) SDL_disabled_assert(condition)
|
||||||
|
# define SDL_assert_release(condition) SDL_enabled_assert(condition)
|
||||||
|
# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
|
||||||
|
#elif SDL_ASSERT_LEVEL == 2 /* debug settings. */
|
||||||
|
# define SDL_assert(condition) SDL_enabled_assert(condition)
|
||||||
|
# define SDL_assert_release(condition) SDL_enabled_assert(condition)
|
||||||
|
# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
|
||||||
|
#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */
|
||||||
|
# define SDL_assert(condition) SDL_enabled_assert(condition)
|
||||||
|
# define SDL_assert_release(condition) SDL_enabled_assert(condition)
|
||||||
|
# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition)
|
||||||
|
#else
|
||||||
|
# error Unknown assertion level.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assertion test that is always performed.
|
||||||
|
*
|
||||||
|
* This macro is always enabled no matter what SDL_ASSERT_LEVEL is set to. You
|
||||||
|
* almost never want to use this, as it could trigger on an end-user's system,
|
||||||
|
* crashing your program.
|
||||||
|
*
|
||||||
|
* One can set the environment variable "SDL_ASSERT" to one of several strings
|
||||||
|
* ("abort", "break", "retry", "ignore", "always_ignore") to force a default
|
||||||
|
* behavior, which may be desirable for automation purposes. If your platform
|
||||||
|
* requires GUI interfaces to happen on the main thread but you're debugging
|
||||||
|
* an assertion in a background thread, it might be desirable to set this to
|
||||||
|
* "break" so that your debugger takes control as soon as assert is triggered,
|
||||||
|
* instead of risking a bad UI interaction (deadlock, etc) in the application.
|
||||||
|
*
|
||||||
|
* \param condition boolean value to test.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this macro from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_assert_always(condition) SDL_enabled_assert(condition)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback that fires when an SDL assertion fails.
|
||||||
|
*
|
||||||
|
* \param data a pointer to the SDL_AssertData structure corresponding to the
|
||||||
|
* current assertion.
|
||||||
|
* \param userdata what was passed as `userdata` to SDL_SetAssertionHandler().
|
||||||
|
* \returns an SDL_AssertState value indicating how to handle the failure.
|
||||||
|
*
|
||||||
|
* \threadsafety This callback may be called from any thread that triggers an
|
||||||
|
* assert at any time.
|
||||||
|
*
|
||||||
|
* \since This datatype is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)(
|
||||||
|
const SDL_AssertData *data, void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an application-defined assertion handler.
|
||||||
|
*
|
||||||
|
* This function allows an application to show its own assertion UI and/or
|
||||||
|
* force the response to an assertion failure. If the application doesn't
|
||||||
|
* provide this, SDL will try to do the right thing, popping up a
|
||||||
|
* system-specific GUI dialog, and probably minimizing any fullscreen windows.
|
||||||
|
*
|
||||||
|
* This callback may fire from any thread, but it runs wrapped in a mutex, so
|
||||||
|
* it will only fire from one thread at a time.
|
||||||
|
*
|
||||||
|
* This callback is NOT reset to SDL's internal handler upon SDL_Quit()!
|
||||||
|
*
|
||||||
|
* \param handler the SDL_AssertionHandler function to call when an assertion
|
||||||
|
* fails or NULL for the default handler.
|
||||||
|
* \param userdata a pointer that is passed to `handler`.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetAssertionHandler
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_SetAssertionHandler(
|
||||||
|
SDL_AssertionHandler handler,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default assertion handler.
|
||||||
|
*
|
||||||
|
* This returns the function pointer that is called by default when an
|
||||||
|
* assertion is triggered. This is an internal function provided by SDL, that
|
||||||
|
* is used for assertions when SDL_SetAssertionHandler() hasn't been used to
|
||||||
|
* provide a different function.
|
||||||
|
*
|
||||||
|
* \returns the default SDL_AssertionHandler that is called when an assert
|
||||||
|
* triggers.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetAssertionHandler
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current assertion handler.
|
||||||
|
*
|
||||||
|
* This returns the function pointer that is called when an assertion is
|
||||||
|
* triggered. This is either the value last passed to
|
||||||
|
* SDL_SetAssertionHandler(), or if no application-specified function is set,
|
||||||
|
* is equivalent to calling SDL_GetDefaultAssertionHandler().
|
||||||
|
*
|
||||||
|
* The parameter `puserdata` is a pointer to a void*, which will store the
|
||||||
|
* "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value
|
||||||
|
* will always be NULL for the default handler. If you don't care about this
|
||||||
|
* data, it is safe to pass a NULL pointer to this function to ignore it.
|
||||||
|
*
|
||||||
|
* \param puserdata pointer which is filled with the "userdata" pointer that
|
||||||
|
* was passed to SDL_SetAssertionHandler().
|
||||||
|
* \returns the SDL_AssertionHandler that is called when an assert triggers.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetAssertionHandler
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all assertion failures.
|
||||||
|
*
|
||||||
|
* This function gets all assertions triggered since the last call to
|
||||||
|
* SDL_ResetAssertionReport(), or the start of the program.
|
||||||
|
*
|
||||||
|
* The proper way to examine this data looks something like this:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* const SDL_AssertData *item = SDL_GetAssertionReport();
|
||||||
|
* while (item) {
|
||||||
|
* printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n",
|
||||||
|
* item->condition, item->function, item->filename,
|
||||||
|
* item->linenum, item->trigger_count,
|
||||||
|
* item->always_ignore ? "yes" : "no");
|
||||||
|
* item = item->next;
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* \returns a list of all failed assertions or NULL if the list is empty. This
|
||||||
|
* memory should not be modified or freed by the application. This
|
||||||
|
* pointer remains valid until the next call to SDL_Quit() or
|
||||||
|
* SDL_ResetAssertionReport().
|
||||||
|
*
|
||||||
|
* \threadsafety This function is not thread safe. Other threads calling
|
||||||
|
* SDL_ResetAssertionReport() simultaneously, may render the
|
||||||
|
* returned pointer invalid.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_ResetAssertionReport
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the list of all assertion failures.
|
||||||
|
*
|
||||||
|
* This function will clear the list of all assertions triggered up to that
|
||||||
|
* point. Immediately following this call, SDL_GetAssertionReport will return
|
||||||
|
* no items. In addition, any previously-triggered assertions will be reset to
|
||||||
|
* a trigger_count of zero, and their always_ignore state will be false.
|
||||||
|
*
|
||||||
|
* \threadsafety This function is not thread safe. Other threads triggering an
|
||||||
|
* assertion, or simultaneously calling this function may cause
|
||||||
|
* memory leaks or crashes.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetAssertionReport
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_ResetAssertionReport(void);
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <SDL3/SDL_close_code.h>
|
||||||
|
|
||||||
|
#endif /* SDL_assert_h_ */
|
||||||
@@ -0,0 +1,546 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* WIKI CATEGORY: AsyncIO */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryAsyncIO
|
||||||
|
*
|
||||||
|
* SDL offers a way to perform I/O asynchronously. This allows an app to read
|
||||||
|
* or write files without waiting for data to actually transfer; the functions
|
||||||
|
* that request I/O never block while the request is fulfilled.
|
||||||
|
*
|
||||||
|
* Instead, the data moves in the background and the app can check for results
|
||||||
|
* at their leisure.
|
||||||
|
*
|
||||||
|
* This is more complicated than just reading and writing files in a
|
||||||
|
* synchronous way, but it can allow for more efficiency, and never having
|
||||||
|
* framerate drops as the hard drive catches up, etc.
|
||||||
|
*
|
||||||
|
* The general usage pattern for async I/O is:
|
||||||
|
*
|
||||||
|
* - Create one or more SDL_AsyncIOQueue objects.
|
||||||
|
* - Open files with SDL_AsyncIOFromFile.
|
||||||
|
* - Start I/O tasks to the files with SDL_ReadAsyncIO or SDL_WriteAsyncIO,
|
||||||
|
* putting those tasks into one of the queues.
|
||||||
|
* - Later on, use SDL_GetAsyncIOResult on a queue to see if any task is
|
||||||
|
* finished without blocking. Tasks might finish in any order with success
|
||||||
|
* or failure.
|
||||||
|
* - When all your tasks are done, close the file with SDL_CloseAsyncIO. This
|
||||||
|
* also generates a task, since it might flush data to disk!
|
||||||
|
*
|
||||||
|
* This all works, without blocking, in a single thread, but one can also wait
|
||||||
|
* on a queue in a background thread, sleeping until new results have arrived:
|
||||||
|
*
|
||||||
|
* - Call SDL_WaitAsyncIOResult from one or more threads to efficiently block
|
||||||
|
* until new tasks complete.
|
||||||
|
* - When shutting down, call SDL_SignalAsyncIOQueue to unblock any sleeping
|
||||||
|
* threads despite there being no new tasks completed.
|
||||||
|
*
|
||||||
|
* And, of course, to match the synchronous SDL_LoadFile, we offer
|
||||||
|
* SDL_LoadFileAsync as a convenience function. This will handle allocating a
|
||||||
|
* buffer, slurping in the file data, and null-terminating it; you still check
|
||||||
|
* for results later.
|
||||||
|
*
|
||||||
|
* Behind the scenes, SDL will use newer, efficient APIs on platforms that
|
||||||
|
* support them: Linux's io_uring and Windows 11's IoRing, for example. If
|
||||||
|
* those technologies aren't available, SDL will offload the work to a thread
|
||||||
|
* pool that will manage otherwise-synchronous loads without blocking the app.
|
||||||
|
*
|
||||||
|
* ## Best Practices
|
||||||
|
*
|
||||||
|
* Simple non-blocking I/O--for an app that just wants to pick up data
|
||||||
|
* whenever it's ready without losing framerate waiting on disks to spin--can
|
||||||
|
* use whatever pattern works well for the program. In this case, simply call
|
||||||
|
* SDL_ReadAsyncIO, or maybe SDL_LoadFileAsync, as needed. Once a frame, call
|
||||||
|
* SDL_GetAsyncIOResult to check for any completed tasks and deal with the
|
||||||
|
* data as it arrives.
|
||||||
|
*
|
||||||
|
* If two separate pieces of the same program need their own I/O, it is legal
|
||||||
|
* for each to create their own queue. This will prevent either piece from
|
||||||
|
* accidentally consuming the other's completed tasks. Each queue does require
|
||||||
|
* some amount of resources, but it is not an overwhelming cost. Do not make a
|
||||||
|
* queue for each task, however. It is better to put many tasks into a single
|
||||||
|
* queue. They will be reported in order of completion, not in the order they
|
||||||
|
* were submitted, so it doesn't generally matter what order tasks are
|
||||||
|
* started.
|
||||||
|
*
|
||||||
|
* One async I/O queue can be shared by multiple threads, or one thread can
|
||||||
|
* have more than one queue, but the most efficient way--if ruthless
|
||||||
|
* efficiency is the goal--is to have one queue per thread, with multiple
|
||||||
|
* threads working in parallel, and attempt to keep each queue loaded with
|
||||||
|
* tasks that are both started by and consumed by the same thread. On modern
|
||||||
|
* platforms that can use newer interfaces, this can keep data flowing as
|
||||||
|
* efficiently as possible all the way from storage hardware to the app, with
|
||||||
|
* no contention between threads for access to the same queue.
|
||||||
|
*
|
||||||
|
* Written data is not guaranteed to make it to physical media by the time a
|
||||||
|
* closing task is completed, unless SDL_CloseAsyncIO is called with its
|
||||||
|
* `flush` parameter set to true, which is to say that a successful result
|
||||||
|
* here can still result in lost data during an unfortunately-timed power
|
||||||
|
* outage if not flushed. However, flushing will take longer and may be
|
||||||
|
* unnecessary, depending on the app's needs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_asyncio_h_
|
||||||
|
#define SDL_asyncio_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_begin_code.h>
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The asynchronous I/O operation structure.
|
||||||
|
*
|
||||||
|
* This operates as an opaque handle. One can then request read or write
|
||||||
|
* operations on it.
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_AsyncIOFromFile
|
||||||
|
*/
|
||||||
|
typedef struct SDL_AsyncIO SDL_AsyncIO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of asynchronous I/O tasks.
|
||||||
|
*
|
||||||
|
* \since This enum is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef enum SDL_AsyncIOTaskType
|
||||||
|
{
|
||||||
|
SDL_ASYNCIO_TASK_READ, /**< A read operation. */
|
||||||
|
SDL_ASYNCIO_TASK_WRITE, /**< A write operation. */
|
||||||
|
SDL_ASYNCIO_TASK_CLOSE /**< A close operation. */
|
||||||
|
} SDL_AsyncIOTaskType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible outcomes of an asynchronous I/O task.
|
||||||
|
*
|
||||||
|
* \since This enum is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef enum SDL_AsyncIOResult
|
||||||
|
{
|
||||||
|
SDL_ASYNCIO_COMPLETE, /**< request was completed without error */
|
||||||
|
SDL_ASYNCIO_FAILURE, /**< request failed for some reason; check SDL_GetError()! */
|
||||||
|
SDL_ASYNCIO_CANCELED /**< request was canceled before completing. */
|
||||||
|
} SDL_AsyncIOResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a completed asynchronous I/O request.
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef struct SDL_AsyncIOOutcome
|
||||||
|
{
|
||||||
|
SDL_AsyncIO *asyncio; /**< what generated this task. This pointer will be invalid if it was closed! */
|
||||||
|
SDL_AsyncIOTaskType type; /**< What sort of task was this? Read, write, etc? */
|
||||||
|
SDL_AsyncIOResult result; /**< the result of the work (success, failure, cancellation). */
|
||||||
|
void *buffer; /**< buffer where data was read/written. */
|
||||||
|
Uint64 offset; /**< offset in the SDL_AsyncIO where data was read/written. */
|
||||||
|
Uint64 bytes_requested; /**< number of bytes the task was to read/write. */
|
||||||
|
Uint64 bytes_transferred; /**< actual number of bytes that were read/written. */
|
||||||
|
void *userdata; /**< pointer provided by the app when starting the task */
|
||||||
|
} SDL_AsyncIOOutcome;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A queue of completed asynchronous I/O tasks.
|
||||||
|
*
|
||||||
|
* When starting an asynchronous operation, you specify a queue for the new
|
||||||
|
* task. A queue can be asked later if any tasks in it have completed,
|
||||||
|
* allowing an app to manage multiple pending tasks in one place, in whatever
|
||||||
|
* order they complete.
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CreateAsyncIOQueue
|
||||||
|
* \sa SDL_ReadAsyncIO
|
||||||
|
* \sa SDL_WriteAsyncIO
|
||||||
|
* \sa SDL_GetAsyncIOResult
|
||||||
|
* \sa SDL_WaitAsyncIOResult
|
||||||
|
*/
|
||||||
|
typedef struct SDL_AsyncIOQueue SDL_AsyncIOQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to create a new SDL_AsyncIO object for reading from
|
||||||
|
* and/or writing to a named file.
|
||||||
|
*
|
||||||
|
* The `mode` string understands the following values:
|
||||||
|
*
|
||||||
|
* - "r": Open a file for reading only. It must exist.
|
||||||
|
* - "w": Open a file for writing only. It will create missing files or
|
||||||
|
* truncate existing ones.
|
||||||
|
* - "r+": Open a file for update both reading and writing. The file must
|
||||||
|
* exist.
|
||||||
|
* - "w+": Create an empty file for both reading and writing. If a file with
|
||||||
|
* the same name already exists its content is erased and the file is
|
||||||
|
* treated as a new empty file.
|
||||||
|
*
|
||||||
|
* There is no "b" mode, as there is only "binary" style I/O, and no "a" mode
|
||||||
|
* for appending, since you specify the position when starting a task.
|
||||||
|
*
|
||||||
|
* This function supports Unicode filenames, but they must be encoded in UTF-8
|
||||||
|
* format, regardless of the underlying operating system.
|
||||||
|
*
|
||||||
|
* This call is _not_ asynchronous; it will open the file before returning,
|
||||||
|
* under the assumption that doing so is generally a fast operation. Future
|
||||||
|
* reads and writes to the opened file will be async, however.
|
||||||
|
*
|
||||||
|
* \param file a UTF-8 string representing the filename to open.
|
||||||
|
* \param mode an ASCII string representing the mode to be used for opening
|
||||||
|
* the file.
|
||||||
|
* \returns a pointer to the SDL_AsyncIO structure that is created or NULL on
|
||||||
|
* failure; call SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CloseAsyncIO
|
||||||
|
* \sa SDL_ReadAsyncIO
|
||||||
|
* \sa SDL_WriteAsyncIO
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_AsyncIO * SDLCALL SDL_AsyncIOFromFile(const char *file, const char *mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to get the size of the data stream in an SDL_AsyncIO.
|
||||||
|
*
|
||||||
|
* This call is _not_ asynchronous; it assumes that obtaining this info is a
|
||||||
|
* non-blocking operation in most reasonable cases.
|
||||||
|
*
|
||||||
|
* \param asyncio the SDL_AsyncIO to get the size of the data stream from.
|
||||||
|
* \returns the size of the data stream in the SDL_IOStream on success or a
|
||||||
|
* negative error code on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC Sint64 SDLCALL SDL_GetAsyncIOSize(SDL_AsyncIO *asyncio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start an async read.
|
||||||
|
*
|
||||||
|
* This function reads up to `size` bytes from `offset` position in the data
|
||||||
|
* source to the area pointed at by `ptr`. This function may read less bytes
|
||||||
|
* than requested.
|
||||||
|
*
|
||||||
|
* This function returns as quickly as possible; it does not wait for the read
|
||||||
|
* to complete. On a successful return, this work will continue in the
|
||||||
|
* background. If the work begins, even failure is asynchronous: a failing
|
||||||
|
* return value from this function only means the work couldn't start at all.
|
||||||
|
*
|
||||||
|
* `ptr` must remain available until the work is done, and may be accessed by
|
||||||
|
* the system at any time until then. Do not allocate it on the stack, as this
|
||||||
|
* might take longer than the life of the calling function to complete!
|
||||||
|
*
|
||||||
|
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
|
||||||
|
* to it when it completes its work.
|
||||||
|
*
|
||||||
|
* \param asyncio a pointer to an SDL_AsyncIO structure.
|
||||||
|
* \param ptr a pointer to a buffer to read data into.
|
||||||
|
* \param offset the position to start reading in the data source.
|
||||||
|
* \param size the number of bytes to read from the data source.
|
||||||
|
* \param queue a queue to add the new SDL_AsyncIO to.
|
||||||
|
* \param userdata an app-defined pointer that will be provided with the task
|
||||||
|
* results.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_WriteAsyncIO
|
||||||
|
* \sa SDL_CreateAsyncIOQueue
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_ReadAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start an async write.
|
||||||
|
*
|
||||||
|
* This function writes `size` bytes from `offset` position in the data source
|
||||||
|
* to the area pointed at by `ptr`.
|
||||||
|
*
|
||||||
|
* This function returns as quickly as possible; it does not wait for the
|
||||||
|
* write to complete. On a successful return, this work will continue in the
|
||||||
|
* background. If the work begins, even failure is asynchronous: a failing
|
||||||
|
* return value from this function only means the work couldn't start at all.
|
||||||
|
*
|
||||||
|
* `ptr` must remain available until the work is done, and may be accessed by
|
||||||
|
* the system at any time until then. Do not allocate it on the stack, as this
|
||||||
|
* might take longer than the life of the calling function to complete!
|
||||||
|
*
|
||||||
|
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
|
||||||
|
* to it when it completes its work.
|
||||||
|
*
|
||||||
|
* \param asyncio a pointer to an SDL_AsyncIO structure.
|
||||||
|
* \param ptr a pointer to a buffer to write data from.
|
||||||
|
* \param offset the position to start writing to the data source.
|
||||||
|
* \param size the number of bytes to write to the data source.
|
||||||
|
* \param queue a queue to add the new SDL_AsyncIO to.
|
||||||
|
* \param userdata an app-defined pointer that will be provided with the task
|
||||||
|
* results.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_ReadAsyncIO
|
||||||
|
* \sa SDL_CreateAsyncIOQueue
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_WriteAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close and free any allocated resources for an async I/O object.
|
||||||
|
*
|
||||||
|
* Closing a file is _also_ an asynchronous task! If a write failure were to
|
||||||
|
* happen during the closing process, for example, the task results will
|
||||||
|
* report it as usual.
|
||||||
|
*
|
||||||
|
* Closing a file that has been written to does not guarantee the data has
|
||||||
|
* made it to physical media; it may remain in the operating system's file
|
||||||
|
* cache, for later writing to disk. This means that a successfully-closed
|
||||||
|
* file can be lost if the system crashes or loses power in this small window.
|
||||||
|
* To prevent this, call this function with the `flush` parameter set to true.
|
||||||
|
* This will make the operation take longer, and perhaps increase system load
|
||||||
|
* in general, but a successful result guarantees that the data has made it to
|
||||||
|
* physical storage. Don't use this for temporary files, caches, and
|
||||||
|
* unimportant data, and definitely use it for crucial irreplaceable files,
|
||||||
|
* like game saves.
|
||||||
|
*
|
||||||
|
* This function guarantees that the close will happen after any other pending
|
||||||
|
* tasks to `asyncio`, so it's safe to open a file, start several operations,
|
||||||
|
* close the file immediately, then check for all results later. This function
|
||||||
|
* will not block until the tasks have completed.
|
||||||
|
*
|
||||||
|
* Once this function returns true, `asyncio` is no longer valid, regardless
|
||||||
|
* of any future outcomes. Any completed tasks might still contain this
|
||||||
|
* pointer in their SDL_AsyncIOOutcome data, in case the app was using this
|
||||||
|
* value to track information, but it should not be used again.
|
||||||
|
*
|
||||||
|
* If this function returns false, the close wasn't started at all, and it's
|
||||||
|
* safe to attempt to close again later.
|
||||||
|
*
|
||||||
|
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
|
||||||
|
* to it when it completes its work.
|
||||||
|
*
|
||||||
|
* \param asyncio a pointer to an SDL_AsyncIO structure to close.
|
||||||
|
* \param flush true if data should sync to disk before the task completes.
|
||||||
|
* \param queue a queue to add the new SDL_AsyncIO to.
|
||||||
|
* \param userdata an app-defined pointer that will be provided with the task
|
||||||
|
* results.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread, but two
|
||||||
|
* threads should not attempt to close the same object.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_CloseAsyncIO(SDL_AsyncIO *asyncio, bool flush, SDL_AsyncIOQueue *queue, void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a task queue for tracking multiple I/O operations.
|
||||||
|
*
|
||||||
|
* Async I/O operations are assigned to a queue when started. The queue can be
|
||||||
|
* checked for completed tasks thereafter.
|
||||||
|
*
|
||||||
|
* \returns a new task queue object or NULL if there was an error; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_DestroyAsyncIOQueue
|
||||||
|
* \sa SDL_GetAsyncIOResult
|
||||||
|
* \sa SDL_WaitAsyncIOResult
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_AsyncIOQueue * SDLCALL SDL_CreateAsyncIOQueue(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a previously-created async I/O task queue.
|
||||||
|
*
|
||||||
|
* If there are still tasks pending for this queue, this call will block until
|
||||||
|
* those tasks are finished. All those tasks will be deallocated. Their
|
||||||
|
* results will be lost to the app.
|
||||||
|
*
|
||||||
|
* Any pending reads from SDL_LoadFileAsync() that are still in this queue
|
||||||
|
* will have their buffers deallocated by this function, to prevent a memory
|
||||||
|
* leak.
|
||||||
|
*
|
||||||
|
* Once this function is called, the queue is no longer valid and should not
|
||||||
|
* be used, including by other threads that might access it while destruction
|
||||||
|
* is blocking on pending tasks.
|
||||||
|
*
|
||||||
|
* Do not destroy a queue that still has threads waiting on it through
|
||||||
|
* SDL_WaitAsyncIOResult(). You can call SDL_SignalAsyncIOQueue() first to
|
||||||
|
* unblock those threads, and take measures (such as SDL_WaitThread()) to make
|
||||||
|
* sure they have finished their wait and won't wait on the queue again.
|
||||||
|
*
|
||||||
|
* \param queue the task queue to destroy.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread, so long as
|
||||||
|
* no other thread is waiting on the queue with
|
||||||
|
* SDL_WaitAsyncIOResult.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_DestroyAsyncIOQueue(SDL_AsyncIOQueue *queue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query an async I/O task queue for completed tasks.
|
||||||
|
*
|
||||||
|
* If a task assigned to this queue has finished, this will return true and
|
||||||
|
* fill in `outcome` with the details of the task. If no task in the queue has
|
||||||
|
* finished, this function will return false. This function does not block.
|
||||||
|
*
|
||||||
|
* If a task has completed, this function will free its resources and the task
|
||||||
|
* pointer will no longer be valid. The task will be removed from the queue.
|
||||||
|
*
|
||||||
|
* It is safe for multiple threads to call this function on the same queue at
|
||||||
|
* once; a completed task will only go to one of the threads.
|
||||||
|
*
|
||||||
|
* \param queue the async I/O task queue to query.
|
||||||
|
* \param outcome details of a finished task will be written here. May not be
|
||||||
|
* NULL.
|
||||||
|
* \returns true if a task has completed, false otherwise.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_WaitAsyncIOResult
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_GetAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block until an async I/O task queue has a completed task.
|
||||||
|
*
|
||||||
|
* This function puts the calling thread to sleep until there a task assigned
|
||||||
|
* to the queue that has finished.
|
||||||
|
*
|
||||||
|
* If a task assigned to the queue has finished, this will return true and
|
||||||
|
* fill in `outcome` with the details of the task. If no task in the queue has
|
||||||
|
* finished, this function will return false.
|
||||||
|
*
|
||||||
|
* If a task has completed, this function will free its resources and the task
|
||||||
|
* pointer will no longer be valid. The task will be removed from the queue.
|
||||||
|
*
|
||||||
|
* It is safe for multiple threads to call this function on the same queue at
|
||||||
|
* once; a completed task will only go to one of the threads.
|
||||||
|
*
|
||||||
|
* Note that by the nature of various platforms, more than one waiting thread
|
||||||
|
* may wake to handle a single task, but only one will obtain it, so
|
||||||
|
* `timeoutMS` is a _maximum_ wait time, and this function may return false
|
||||||
|
* sooner.
|
||||||
|
*
|
||||||
|
* This function may return false if there was a system error, the OS
|
||||||
|
* inadvertently awoke multiple threads, or if SDL_SignalAsyncIOQueue() was
|
||||||
|
* called to wake up all waiting threads without a finished task.
|
||||||
|
*
|
||||||
|
* A timeout can be used to specify a maximum wait time, but rather than
|
||||||
|
* polling, it is possible to have a timeout of -1 to wait forever, and use
|
||||||
|
* SDL_SignalAsyncIOQueue() to wake up the waiting threads later.
|
||||||
|
*
|
||||||
|
* \param queue the async I/O task queue to wait on.
|
||||||
|
* \param outcome details of a finished task will be written here. May not be
|
||||||
|
* NULL.
|
||||||
|
* \param timeoutMS the maximum time to wait, in milliseconds, or -1 to wait
|
||||||
|
* indefinitely.
|
||||||
|
* \returns true if task has completed, false otherwise.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SignalAsyncIOQueue
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_WaitAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome, Sint32 timeoutMS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wake up any threads that are blocking in SDL_WaitAsyncIOResult().
|
||||||
|
*
|
||||||
|
* This will unblock any threads that are sleeping in a call to
|
||||||
|
* SDL_WaitAsyncIOResult for the specified queue, and cause them to return
|
||||||
|
* from that function.
|
||||||
|
*
|
||||||
|
* This can be useful when destroying a queue to make sure nothing is touching
|
||||||
|
* it indefinitely. In this case, once this call completes, the caller should
|
||||||
|
* take measures to make sure any previously-blocked threads have returned
|
||||||
|
* from their wait and will not touch the queue again (perhaps by setting a
|
||||||
|
* flag to tell the threads to terminate and then using SDL_WaitThread() to
|
||||||
|
* make sure they've done so).
|
||||||
|
*
|
||||||
|
* \param queue the async I/O task queue to signal.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_WaitAsyncIOResult
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_SignalAsyncIOQueue(SDL_AsyncIOQueue *queue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all the data from a file path, asynchronously.
|
||||||
|
*
|
||||||
|
* This function returns as quickly as possible; it does not wait for the read
|
||||||
|
* to complete. On a successful return, this work will continue in the
|
||||||
|
* background. If the work begins, even failure is asynchronous: a failing
|
||||||
|
* return value from this function only means the work couldn't start at all.
|
||||||
|
*
|
||||||
|
* The data is allocated with a zero byte at the end (null terminated) for
|
||||||
|
* convenience. This extra byte is not included in SDL_AsyncIOOutcome's
|
||||||
|
* bytes_transferred value.
|
||||||
|
*
|
||||||
|
* This function will allocate the buffer to contain the file. It must be
|
||||||
|
* deallocated by calling SDL_free() on SDL_AsyncIOOutcome's buffer field
|
||||||
|
* after completion.
|
||||||
|
*
|
||||||
|
* An SDL_AsyncIOQueue must be specified. The newly-created task will be added
|
||||||
|
* to it when it completes its work.
|
||||||
|
*
|
||||||
|
* \param file the path to read all available data from.
|
||||||
|
* \param queue a queue to add the new SDL_AsyncIO to.
|
||||||
|
* \param userdata an app-defined pointer that will be provided with the task
|
||||||
|
* results.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_LoadFile_IO
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_LoadFileAsync(const char *file, SDL_AsyncIOQueue *queue, void *userdata);
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <SDL3/SDL_close_code.h>
|
||||||
|
|
||||||
|
#endif /* SDL_asyncio_h_ */
|
||||||
@@ -0,0 +1,664 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryAtomic
|
||||||
|
*
|
||||||
|
* Atomic operations.
|
||||||
|
*
|
||||||
|
* IMPORTANT: If you are not an expert in concurrent lockless programming, you
|
||||||
|
* should not be using any functions in this file. You should be protecting
|
||||||
|
* your data structures with full mutexes instead.
|
||||||
|
*
|
||||||
|
* ***Seriously, here be dragons!***
|
||||||
|
*
|
||||||
|
* You can find out a little more about lockless programming and the subtle
|
||||||
|
* issues that can arise here:
|
||||||
|
* https://learn.microsoft.com/en-us/windows/win32/dxtecharts/lockless-programming
|
||||||
|
*
|
||||||
|
* There's also lots of good information here:
|
||||||
|
*
|
||||||
|
* - https://www.1024cores.net/home/lock-free-algorithms
|
||||||
|
* - https://preshing.com/
|
||||||
|
*
|
||||||
|
* These operations may or may not actually be implemented using processor
|
||||||
|
* specific atomic operations. When possible they are implemented as true
|
||||||
|
* processor specific atomic operations. When that is not possible the are
|
||||||
|
* implemented using locks that *do* use the available atomic operations.
|
||||||
|
*
|
||||||
|
* All of the atomic operations that modify memory are full memory barriers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_atomic_h_
|
||||||
|
#define SDL_atomic_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
#include <SDL3/SDL_platform_defines.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_begin_code.h>
|
||||||
|
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An atomic spinlock.
|
||||||
|
*
|
||||||
|
* The atomic locks are efficient spinlocks using CPU instructions, but are
|
||||||
|
* vulnerable to starvation and can spin forever if a thread holding a lock
|
||||||
|
* has been terminated. For this reason you should minimize the code executed
|
||||||
|
* inside an atomic lock and never do expensive things like API or system
|
||||||
|
* calls while holding them.
|
||||||
|
*
|
||||||
|
* They are also vulnerable to starvation if the thread holding the lock is
|
||||||
|
* lower priority than other threads and doesn't get scheduled. In general you
|
||||||
|
* should use mutexes instead, since they have better performance and
|
||||||
|
* contention behavior.
|
||||||
|
*
|
||||||
|
* The atomic locks are not safe to lock recursively.
|
||||||
|
*
|
||||||
|
* Porting Note: The spin lock functions and type are required and can not be
|
||||||
|
* emulated because they are used in the atomic emulation code.
|
||||||
|
*/
|
||||||
|
typedef int SDL_SpinLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to lock a spin lock by setting it to a non-zero value.
|
||||||
|
*
|
||||||
|
* ***Please note that spinlocks are dangerous if you don't know what you're
|
||||||
|
* doing. Please be careful using any sort of spinlock!***
|
||||||
|
*
|
||||||
|
* \param lock a pointer to a lock variable.
|
||||||
|
* \returns true if the lock succeeded, false if the lock is already held.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_LockSpinlock
|
||||||
|
* \sa SDL_UnlockSpinlock
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockSpinlock(SDL_SpinLock *lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock a spin lock by setting it to a non-zero value.
|
||||||
|
*
|
||||||
|
* ***Please note that spinlocks are dangerous if you don't know what you're
|
||||||
|
* doing. Please be careful using any sort of spinlock!***
|
||||||
|
*
|
||||||
|
* \param lock a pointer to a lock variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_TryLockSpinlock
|
||||||
|
* \sa SDL_UnlockSpinlock
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_LockSpinlock(SDL_SpinLock *lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock a spin lock by setting it to 0.
|
||||||
|
*
|
||||||
|
* Always returns immediately.
|
||||||
|
*
|
||||||
|
* ***Please note that spinlocks are dangerous if you don't know what you're
|
||||||
|
* doing. Please be careful using any sort of spinlock!***
|
||||||
|
*
|
||||||
|
* \param lock a pointer to a lock variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_LockSpinlock
|
||||||
|
* \sa SDL_TryLockSpinlock
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_UnlockSpinlock(SDL_SpinLock *lock);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a compiler barrier.
|
||||||
|
*
|
||||||
|
* A compiler barrier prevents the compiler from reordering reads and writes
|
||||||
|
* to globally visible variables across the call.
|
||||||
|
*
|
||||||
|
* This macro only prevents the compiler from reordering reads and writes, it
|
||||||
|
* does not prevent the CPU from reordering reads and writes. However, all of
|
||||||
|
* the atomic operations that modify memory are full memory barriers.
|
||||||
|
*
|
||||||
|
* \threadsafety Obviously this macro is safe to use from any thread at any
|
||||||
|
* time, but if you find yourself needing this, you are probably
|
||||||
|
* dealing with some very sensitive code; be careful!
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_CompilerBarrier() DoCompilerSpecificReadWriteBarrier()
|
||||||
|
|
||||||
|
#elif defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__)
|
||||||
|
void _ReadWriteBarrier(void);
|
||||||
|
#pragma intrinsic(_ReadWriteBarrier)
|
||||||
|
#define SDL_CompilerBarrier() _ReadWriteBarrier()
|
||||||
|
#elif (defined(__GNUC__) && !defined(SDL_PLATFORM_EMSCRIPTEN)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
|
||||||
|
/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
|
||||||
|
#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory")
|
||||||
|
#elif defined(__WATCOMC__)
|
||||||
|
extern __inline void SDL_CompilerBarrier(void);
|
||||||
|
#pragma aux SDL_CompilerBarrier = "" parm [] modify exact [];
|
||||||
|
#else
|
||||||
|
#define SDL_CompilerBarrier() \
|
||||||
|
{ SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a memory release barrier (function version).
|
||||||
|
*
|
||||||
|
* Please refer to SDL_MemoryBarrierRelease for details. This is a function
|
||||||
|
* version, which might be useful if you need to use this functionality from a
|
||||||
|
* scripting language, etc. Also, some of the macro versions call this
|
||||||
|
* function behind the scenes, where more heavy lifting can happen inside of
|
||||||
|
* SDL. Generally, though, an app written in C/C++/etc should use the macro
|
||||||
|
* version, as it will be more efficient.
|
||||||
|
*
|
||||||
|
* \threadsafety Obviously this function is safe to use from any thread at any
|
||||||
|
* time, but if you find yourself needing this, you are probably
|
||||||
|
* dealing with some very sensitive code; be careful!
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_MemoryBarrierRelease
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a memory acquire barrier (function version).
|
||||||
|
*
|
||||||
|
* Please refer to SDL_MemoryBarrierRelease for details. This is a function
|
||||||
|
* version, which might be useful if you need to use this functionality from a
|
||||||
|
* scripting language, etc. Also, some of the macro versions call this
|
||||||
|
* function behind the scenes, where more heavy lifting can happen inside of
|
||||||
|
* SDL. Generally, though, an app written in C/C++/etc should use the macro
|
||||||
|
* version, as it will be more efficient.
|
||||||
|
*
|
||||||
|
* \threadsafety Obviously this function is safe to use from any thread at any
|
||||||
|
* time, but if you find yourself needing this, you are probably
|
||||||
|
* dealing with some very sensitive code; be careful!
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_MemoryBarrierAcquire
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a memory release barrier (macro version).
|
||||||
|
*
|
||||||
|
* Memory barriers are designed to prevent reads and writes from being
|
||||||
|
* reordered by the compiler and being seen out of order on multi-core CPUs.
|
||||||
|
*
|
||||||
|
* A typical pattern would be for thread A to write some data and a flag, and
|
||||||
|
* for thread B to read the flag and get the data. In this case you would
|
||||||
|
* insert a release barrier between writing the data and the flag,
|
||||||
|
* guaranteeing that the data write completes no later than the flag is
|
||||||
|
* written, and you would insert an acquire barrier between reading the flag
|
||||||
|
* and reading the data, to ensure that all the reads associated with the flag
|
||||||
|
* have completed.
|
||||||
|
*
|
||||||
|
* In this pattern you should always see a release barrier paired with an
|
||||||
|
* acquire barrier and you should gate the data reads/writes with a single
|
||||||
|
* flag variable.
|
||||||
|
*
|
||||||
|
* For more information on these semantics, take a look at the blog post:
|
||||||
|
* http://preshing.com/20120913/acquire-and-release-semantics
|
||||||
|
*
|
||||||
|
* This is the macro version of this functionality; if possible, SDL will use
|
||||||
|
* compiler intrinsics or inline assembly, but some platforms might need to
|
||||||
|
* call the function version of this, SDL_MemoryBarrierReleaseFunction to do
|
||||||
|
* the heavy lifting. Apps that can use the macro should favor it over the
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* \threadsafety Obviously this macro is safe to use from any thread at any
|
||||||
|
* time, but if you find yourself needing this, you are probably
|
||||||
|
* dealing with some very sensitive code; be careful!
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_MemoryBarrierAcquire
|
||||||
|
* \sa SDL_MemoryBarrierReleaseFunction
|
||||||
|
*/
|
||||||
|
#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a memory acquire barrier (macro version).
|
||||||
|
*
|
||||||
|
* Please see SDL_MemoryBarrierRelease for the details on what memory barriers
|
||||||
|
* are and when to use them.
|
||||||
|
*
|
||||||
|
* This is the macro version of this functionality; if possible, SDL will use
|
||||||
|
* compiler intrinsics or inline assembly, but some platforms might need to
|
||||||
|
* call the function version of this, SDL_MemoryBarrierAcquireFunction, to do
|
||||||
|
* the heavy lifting. Apps that can use the macro should favor it over the
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* \threadsafety Obviously this macro is safe to use from any thread at any
|
||||||
|
* time, but if you find yourself needing this, you are probably
|
||||||
|
* dealing with some very sensitive code; be careful!
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_MemoryBarrierRelease
|
||||||
|
* \sa SDL_MemoryBarrierAcquireFunction
|
||||||
|
*/
|
||||||
|
#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
|
||||||
|
|
||||||
|
#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
|
||||||
|
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory")
|
||||||
|
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory")
|
||||||
|
#elif defined(__GNUC__) && defined(__aarch64__)
|
||||||
|
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
|
||||||
|
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
|
||||||
|
#elif defined(__GNUC__) && defined(__arm__)
|
||||||
|
#if 0 /* defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID) */
|
||||||
|
/* Information from:
|
||||||
|
https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19
|
||||||
|
|
||||||
|
The Linux kernel provides a helper function which provides the right code for a memory barrier,
|
||||||
|
hard-coded at address 0xffff0fa0
|
||||||
|
*/
|
||||||
|
typedef void (*SDL_KernelMemoryBarrierFunc)();
|
||||||
|
#define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
|
||||||
|
#define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
|
||||||
|
#else
|
||||||
|
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__)
|
||||||
|
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
|
||||||
|
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
|
||||||
|
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
|
||||||
|
#ifdef __thumb__
|
||||||
|
/* The mcr instruction isn't available in thumb mode, use real functions */
|
||||||
|
#define SDL_MEMORY_BARRIER_USES_FUNCTION
|
||||||
|
#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
|
||||||
|
#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
|
||||||
|
#else
|
||||||
|
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
|
||||||
|
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
|
||||||
|
#endif /* __thumb__ */
|
||||||
|
#else
|
||||||
|
#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory")
|
||||||
|
#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory")
|
||||||
|
#endif /* SDL_PLATFORM_LINUX || SDL_PLATFORM_ANDROID */
|
||||||
|
#endif /* __GNUC__ && __arm__ */
|
||||||
|
#else
|
||||||
|
#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
|
||||||
|
/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */
|
||||||
|
#include <mbarrier.h>
|
||||||
|
#define SDL_MemoryBarrierRelease() __machine_rel_barrier()
|
||||||
|
#define SDL_MemoryBarrierAcquire() __machine_acq_barrier()
|
||||||
|
#else
|
||||||
|
/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
|
||||||
|
#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier()
|
||||||
|
#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to insert a CPU-specific "pause" instruction into the program.
|
||||||
|
*
|
||||||
|
* This can be useful in busy-wait loops, as it serves as a hint to the CPU as
|
||||||
|
* to the program's intent; some CPUs can use this to do more efficient
|
||||||
|
* processing. On some platforms, this doesn't do anything, so using this
|
||||||
|
* macro might just be a harmless no-op.
|
||||||
|
*
|
||||||
|
* Note that if you are busy-waiting, there are often more-efficient
|
||||||
|
* approaches with other synchronization primitives: mutexes, semaphores,
|
||||||
|
* condition variables, etc.
|
||||||
|
*
|
||||||
|
* \threadsafety This macro is safe to use from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_CPUPauseInstruction() DoACPUPauseInACompilerAndArchitectureSpecificWay
|
||||||
|
|
||||||
|
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
|
||||||
|
#define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
|
||||||
|
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__)
|
||||||
|
#define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory")
|
||||||
|
#elif (defined(__powerpc__) || defined(__powerpc64__))
|
||||||
|
#define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27");
|
||||||
|
#elif (defined(__riscv) && __riscv_xlen == 64)
|
||||||
|
#define SDL_CPUPauseInstruction() __asm__ __volatile__(".insn i 0x0F, 0, x0, x0, 0x010");
|
||||||
|
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||||
|
#define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
|
||||||
|
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||||
|
#define SDL_CPUPauseInstruction() __yield()
|
||||||
|
#elif defined(__WATCOMC__) && defined(__386__)
|
||||||
|
extern __inline void SDL_CPUPauseInstruction(void);
|
||||||
|
#pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause"
|
||||||
|
#else
|
||||||
|
#define SDL_CPUPauseInstruction()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type representing an atomic integer value.
|
||||||
|
*
|
||||||
|
* This can be used to manage a value that is synchronized across multiple
|
||||||
|
* CPUs without a race condition; when an app sets a value with
|
||||||
|
* SDL_SetAtomicInt all other threads, regardless of the CPU it is running on,
|
||||||
|
* will see that value when retrieved with SDL_GetAtomicInt, regardless of CPU
|
||||||
|
* caches, etc.
|
||||||
|
*
|
||||||
|
* This is also useful for atomic compare-and-swap operations: a thread can
|
||||||
|
* change the value as long as its current value matches expectations. When
|
||||||
|
* done in a loop, one can guarantee data consistency across threads without a
|
||||||
|
* lock (but the usual warnings apply: if you don't know what you're doing, or
|
||||||
|
* you don't do it carefully, you can confidently cause any number of
|
||||||
|
* disasters with this, so in most cases, you _should_ use a mutex instead of
|
||||||
|
* this!).
|
||||||
|
*
|
||||||
|
* This is a struct so people don't accidentally use numeric operations on it
|
||||||
|
* directly. You have to use SDL atomic functions.
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CompareAndSwapAtomicInt
|
||||||
|
* \sa SDL_GetAtomicInt
|
||||||
|
* \sa SDL_SetAtomicInt
|
||||||
|
* \sa SDL_AddAtomicInt
|
||||||
|
*/
|
||||||
|
typedef struct SDL_AtomicInt { int value; } SDL_AtomicInt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an atomic variable to a new value if it is currently an old value.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicInt variable to be modified.
|
||||||
|
* \param oldval the old value.
|
||||||
|
* \param newval the new value.
|
||||||
|
* \returns true if the atomic variable was set, false otherwise.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetAtomicInt
|
||||||
|
* \sa SDL_SetAtomicInt
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an atomic variable to a value.
|
||||||
|
*
|
||||||
|
* This function also acts as a full memory barrier.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicInt variable to be modified.
|
||||||
|
* \param v the desired value.
|
||||||
|
* \returns the previous value of the atomic variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetAtomicInt
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_SetAtomicInt(SDL_AtomicInt *a, int v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of an atomic variable.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicInt variable.
|
||||||
|
* \returns the current value of an atomic variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetAtomicInt
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_GetAtomicInt(SDL_AtomicInt *a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to an atomic variable.
|
||||||
|
*
|
||||||
|
* This function also acts as a full memory barrier.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicInt variable to be modified.
|
||||||
|
* \param v the desired value to add.
|
||||||
|
* \returns the previous value of the atomic variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_AtomicDecRef
|
||||||
|
* \sa SDL_AtomicIncRef
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicInt(SDL_AtomicInt *a, int v);
|
||||||
|
|
||||||
|
#ifndef SDL_AtomicIncRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment an atomic variable used as a reference count.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this macro is for, you shouldn't use it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicInt to increment.
|
||||||
|
* \returns the previous value of the atomic variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this macro from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_AtomicDecRef
|
||||||
|
*/
|
||||||
|
#define SDL_AtomicIncRef(a) SDL_AddAtomicInt(a, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SDL_AtomicDecRef
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement an atomic variable used as a reference count.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this macro is for, you shouldn't use it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicInt to decrement.
|
||||||
|
* \returns true if the variable reached zero after decrementing, false
|
||||||
|
* otherwise.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this macro from any thread.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_AtomicIncRef
|
||||||
|
*/
|
||||||
|
#define SDL_AtomicDecRef(a) (SDL_AddAtomicInt(a, -1) == 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type representing an atomic unsigned 32-bit value.
|
||||||
|
*
|
||||||
|
* This can be used to manage a value that is synchronized across multiple
|
||||||
|
* CPUs without a race condition; when an app sets a value with
|
||||||
|
* SDL_SetAtomicU32 all other threads, regardless of the CPU it is running on,
|
||||||
|
* will see that value when retrieved with SDL_GetAtomicU32, regardless of CPU
|
||||||
|
* caches, etc.
|
||||||
|
*
|
||||||
|
* This is also useful for atomic compare-and-swap operations: a thread can
|
||||||
|
* change the value as long as its current value matches expectations. When
|
||||||
|
* done in a loop, one can guarantee data consistency across threads without a
|
||||||
|
* lock (but the usual warnings apply: if you don't know what you're doing, or
|
||||||
|
* you don't do it carefully, you can confidently cause any number of
|
||||||
|
* disasters with this, so in most cases, you _should_ use a mutex instead of
|
||||||
|
* this!).
|
||||||
|
*
|
||||||
|
* This is a struct so people don't accidentally use numeric operations on it
|
||||||
|
* directly. You have to use SDL atomic functions.
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CompareAndSwapAtomicU32
|
||||||
|
* \sa SDL_GetAtomicU32
|
||||||
|
* \sa SDL_SetAtomicU32
|
||||||
|
*/
|
||||||
|
typedef struct SDL_AtomicU32 { Uint32 value; } SDL_AtomicU32;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an atomic variable to a new value if it is currently an old value.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicU32 variable to be modified.
|
||||||
|
* \param oldval the old value.
|
||||||
|
* \param newval the new value.
|
||||||
|
* \returns true if the atomic variable was set, false otherwise.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetAtomicU32
|
||||||
|
* \sa SDL_SetAtomicU32
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an atomic variable to a value.
|
||||||
|
*
|
||||||
|
* This function also acts as a full memory barrier.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicU32 variable to be modified.
|
||||||
|
* \param v the desired value.
|
||||||
|
* \returns the previous value of the atomic variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetAtomicU32
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of an atomic variable.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to an SDL_AtomicU32 variable.
|
||||||
|
* \returns the current value of an atomic variable.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetAtomicU32
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32(SDL_AtomicU32 *a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a pointer to a new value if it is currently an old value.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to a pointer.
|
||||||
|
* \param oldval the old pointer value.
|
||||||
|
* \param newval the new pointer value.
|
||||||
|
* \returns true if the pointer was set, false otherwise.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CompareAndSwapAtomicInt
|
||||||
|
* \sa SDL_GetAtomicPointer
|
||||||
|
* \sa SDL_SetAtomicPointer
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a pointer to a value atomically.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to a pointer.
|
||||||
|
* \param v the desired pointer value.
|
||||||
|
* \returns the previous value of the pointer.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CompareAndSwapAtomicPointer
|
||||||
|
* \sa SDL_GetAtomicPointer
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void * SDLCALL SDL_SetAtomicPointer(void **a, void *v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of a pointer atomically.
|
||||||
|
*
|
||||||
|
* ***Note: If you don't know what this function is for, you shouldn't use
|
||||||
|
* it!***
|
||||||
|
*
|
||||||
|
* \param a a pointer to a pointer.
|
||||||
|
* \returns the current value of a pointer.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_CompareAndSwapAtomicPointer
|
||||||
|
* \sa SDL_SetAtomicPointer
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void * SDLCALL SDL_GetAtomicPointer(void **a);
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <SDL3/SDL_close_code.h>
|
||||||
|
|
||||||
|
#endif /* SDL_atomic_h_ */
|
||||||
@@ -0,0 +1,486 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* WIKI CATEGORY: BeginCode */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryBeginCode
|
||||||
|
*
|
||||||
|
* `SDL_begin_code.h` sets things up for C dynamic library function
|
||||||
|
* definitions, static inlined functions, and structures aligned at 4-byte
|
||||||
|
* alignment. If you don't like ugly C preprocessor code, don't look at this
|
||||||
|
* file. :)
|
||||||
|
*
|
||||||
|
* SDL's headers use this; applications generally should not include this
|
||||||
|
* header directly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This shouldn't be nested -- included it around code only. */
|
||||||
|
#ifdef SDL_begin_code_h
|
||||||
|
#error Nested inclusion of SDL_begin_code.h
|
||||||
|
#endif
|
||||||
|
#define SDL_begin_code_h
|
||||||
|
|
||||||
|
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a symbol as deprecated.
|
||||||
|
*
|
||||||
|
* A function is marked deprecated by adding this macro to its declaration:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* extern SDL_DEPRECATED int ThisFunctionWasABadIdea(void);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Compilers with deprecation support can give a warning when a deprecated
|
||||||
|
* function is used. This symbol may be used in SDL's headers, but apps are
|
||||||
|
* welcome to use it for their own interfaces as well.
|
||||||
|
*
|
||||||
|
* SDL, on occasion, might deprecate a function for various reasons. However,
|
||||||
|
* SDL never removes symbols before major versions, so deprecated interfaces
|
||||||
|
* in SDL3 will remain available until SDL4, where it would be expected an app
|
||||||
|
* would have to take steps to migrate anyhow.
|
||||||
|
*
|
||||||
|
* On compilers without a deprecation mechanism, this is defined to nothing,
|
||||||
|
* and using a deprecated function will not generate a warning.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_DEPRECATED __attribute__((deprecated))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a symbol as a public API.
|
||||||
|
*
|
||||||
|
* SDL uses this macro for all its public functions. On some targets, it is
|
||||||
|
* used to signal to the compiler that this function needs to be exported from
|
||||||
|
* a shared library, but it might have other side effects.
|
||||||
|
*
|
||||||
|
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||||
|
* welcome to use it for their own interfaces as well.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_DECLSPEC __attribute__ ((visibility("default")))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to set a function's calling conventions.
|
||||||
|
*
|
||||||
|
* SDL uses this macro for all its public functions, and any callbacks it
|
||||||
|
* defines. This macro guarantees that calling conventions match between SDL
|
||||||
|
* and the app, even if the two were built with different compilers or
|
||||||
|
* optimization settings.
|
||||||
|
*
|
||||||
|
* When writing a callback function, it is very important for it to be
|
||||||
|
* correctly tagged with SDLCALL, as mismatched calling conventions can cause
|
||||||
|
* strange behaviors and can be difficult to diagnose. Plus, on many
|
||||||
|
* platforms, SDLCALL is defined to nothing, so compilers won't be able to
|
||||||
|
* warn that the tag is missing.
|
||||||
|
*
|
||||||
|
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||||
|
* welcome to use it for their own interfaces as well.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDLCALL __cdecl
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to request a function be inlined.
|
||||||
|
*
|
||||||
|
* This is a hint to the compiler to inline a function. The compiler is free
|
||||||
|
* to ignore this request. On compilers without inline support, this is
|
||||||
|
* defined to nothing.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_INLINE __inline
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to demand a function be inlined.
|
||||||
|
*
|
||||||
|
* This is a command to the compiler to inline a function. SDL uses this macro
|
||||||
|
* in its public headers for a handful of simple functions. On compilers
|
||||||
|
* without forceinline support, this is defined to `static SDL_INLINE`, which
|
||||||
|
* is often good enough.
|
||||||
|
*
|
||||||
|
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||||
|
* welcome to use it for their own interfaces as well.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_FORCE_INLINE __forceinline
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a function as never-returning.
|
||||||
|
*
|
||||||
|
* This is a hint to the compiler that a function does not return. An example
|
||||||
|
* of a function like this is the C runtime's exit() function.
|
||||||
|
*
|
||||||
|
* This hint can lead to code optimizations, and help analyzers understand
|
||||||
|
* code flow better. On compilers without noreturn support, this is defined to
|
||||||
|
* nothing.
|
||||||
|
*
|
||||||
|
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||||
|
* welcome to use it for their own interfaces as well.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_NORETURN __attribute__((noreturn))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a function as never-returning (for analysis purposes).
|
||||||
|
*
|
||||||
|
* This is almost identical to SDL_NORETURN, except functions marked with this
|
||||||
|
* _can_ actually return. The difference is that this isn't used for code
|
||||||
|
* generation, but rather static analyzers use this information to assume
|
||||||
|
* truths about program state and available code paths. Specifically, this tag
|
||||||
|
* is useful for writing an assertion mechanism. Indeed, SDL_assert uses this
|
||||||
|
* tag behind the scenes. Generally, apps that don't understand the specific
|
||||||
|
* use-case for this tag should avoid using it directly.
|
||||||
|
*
|
||||||
|
* On compilers without analyzer_noreturn support, this is defined to nothing.
|
||||||
|
*
|
||||||
|
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||||
|
* welcome to use it for their own interfaces as well.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to signal that a case statement without a `break` is intentional.
|
||||||
|
*
|
||||||
|
* C compilers have gotten more aggressive about warning when a switch's
|
||||||
|
* `case` block does not end with a `break` or other flow control statement,
|
||||||
|
* flowing into the next case's code, as this is a common accident that leads
|
||||||
|
* to strange bugs. But sometimes falling through to the next case is the
|
||||||
|
* correct and desired behavior. This symbol lets an app communicate this
|
||||||
|
* intention to the compiler, so it doesn't generate a warning.
|
||||||
|
*
|
||||||
|
* It is used like this:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* switch (x) {
|
||||||
|
* case 1:
|
||||||
|
* DoSomethingOnlyForOne();
|
||||||
|
* SDL_FALLTHROUGH; // tell the compiler this was intentional.
|
||||||
|
* case 2:
|
||||||
|
* DoSomethingForOneAndTwo();
|
||||||
|
* break;
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_FALLTHROUGH [[fallthrough]]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a function's return value as critical.
|
||||||
|
*
|
||||||
|
* This is a hint to the compiler that a function's return value should not be
|
||||||
|
* ignored.
|
||||||
|
*
|
||||||
|
* If an NODISCARD function's return value is thrown away (the function is
|
||||||
|
* called as if it returns `void`), the compiler will issue a warning.
|
||||||
|
*
|
||||||
|
* While it's generally good practice to check return values for errors, often
|
||||||
|
* times legitimate programs do not for good reasons. Be careful about what
|
||||||
|
* functions are tagged as NODISCARD. It operates best when used on a function
|
||||||
|
* that's failure is surprising and catastrophic; a good example would be a
|
||||||
|
* program that checks the return values of all its file write function calls
|
||||||
|
* but not the call to close the file, which it assumes incorrectly never
|
||||||
|
* fails.
|
||||||
|
*
|
||||||
|
* Function callers that want to throw away a NODISCARD return value can call
|
||||||
|
* the function with a `(void)` cast, which informs the compiler the act is
|
||||||
|
* intentional.
|
||||||
|
*
|
||||||
|
* On compilers without nodiscard support, this is defined to nothing.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_NODISCARD [[nodiscard]]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a function as an allocator.
|
||||||
|
*
|
||||||
|
* This is a hint to the compiler that a function is an allocator, like
|
||||||
|
* malloc(), with certain rules. A description of how GCC treats this hint is
|
||||||
|
* here:
|
||||||
|
*
|
||||||
|
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
|
||||||
|
*
|
||||||
|
* On compilers without allocator tag support, this is defined to nothing.
|
||||||
|
*
|
||||||
|
* Most apps don't need to, and should not, use this directly.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a function as returning a certain allocation.
|
||||||
|
*
|
||||||
|
* This is a hint to the compiler that a function allocates and returns a
|
||||||
|
* specific amount of memory based on one of its arguments. For example, the C
|
||||||
|
* runtime's malloc() function could use this macro with an argument of 1
|
||||||
|
* (first argument to malloc is the size of the allocation).
|
||||||
|
*
|
||||||
|
* On compilers without alloc_size support, this is defined to nothing.
|
||||||
|
*
|
||||||
|
* Most apps don't need to, and should not, use this directly.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A macro to tag a pointer variable, to help with pointer aliasing.
|
||||||
|
*
|
||||||
|
* A good explanation of the restrict keyword is here:
|
||||||
|
*
|
||||||
|
* https://en.wikipedia.org/wiki/Restrict
|
||||||
|
*
|
||||||
|
* On compilers without restrict support, this is defined to nothing.
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_RESTRICT __restrict__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the compiler supports a given builtin functionality.
|
||||||
|
*
|
||||||
|
* This allows preprocessor checks for things that otherwise might fail to
|
||||||
|
* compile.
|
||||||
|
*
|
||||||
|
* Supported by virtually all clang versions and more-recent GCCs. Use this
|
||||||
|
* instead of checking the clang version if possible.
|
||||||
|
*
|
||||||
|
* On compilers without has_builtin support, this is defined to 0 (always
|
||||||
|
* false).
|
||||||
|
*
|
||||||
|
* \since This macro is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
#define SDL_HAS_BUILTIN(x) __has_builtin(x)
|
||||||
|
|
||||||
|
/* end of wiki documentation section. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SDL_HAS_BUILTIN
|
||||||
|
#ifdef __has_builtin
|
||||||
|
#define SDL_HAS_BUILTIN(x) __has_builtin(x)
|
||||||
|
#else
|
||||||
|
#define SDL_HAS_BUILTIN(x) 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SDL_DEPRECATED
|
||||||
|
# if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
|
||||||
|
# define SDL_DEPRECATED __attribute__((deprecated))
|
||||||
|
# elif defined(_MSC_VER)
|
||||||
|
# define SDL_DEPRECATED __declspec(deprecated)
|
||||||
|
# else
|
||||||
|
# define SDL_DEPRECATED
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SDL_UNUSED
|
||||||
|
# ifdef __GNUC__
|
||||||
|
# define SDL_UNUSED __attribute__((unused))
|
||||||
|
# else
|
||||||
|
# define SDL_UNUSED
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some compilers use a special export keyword */
|
||||||
|
#ifndef SDL_DECLSPEC
|
||||||
|
# if defined(SDL_PLATFORM_WINDOWS)
|
||||||
|
# ifdef DLL_EXPORT
|
||||||
|
# define SDL_DECLSPEC __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define SDL_DECLSPEC
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if defined(__GNUC__) && __GNUC__ >= 4
|
||||||
|
# define SDL_DECLSPEC __attribute__ ((visibility("default")))
|
||||||
|
# else
|
||||||
|
# define SDL_DECLSPEC
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* By default SDL uses the C calling convention */
|
||||||
|
#ifndef SDLCALL
|
||||||
|
#if defined(SDL_PLATFORM_WINDOWS) && !defined(__GNUC__)
|
||||||
|
#define SDLCALL __cdecl
|
||||||
|
#else
|
||||||
|
#define SDLCALL
|
||||||
|
#endif
|
||||||
|
#endif /* SDLCALL */
|
||||||
|
|
||||||
|
/* Force structure packing at 4 byte alignment.
|
||||||
|
This is necessary if the header is included in code which has structure
|
||||||
|
packing set to an alternate value, say for loading structures from disk.
|
||||||
|
The packing is reset to the previous value in SDL_close_code.h
|
||||||
|
*/
|
||||||
|
#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4103)
|
||||||
|
#endif
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic ignored "-Wpragma-pack"
|
||||||
|
#endif
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma nopackwarning
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN64
|
||||||
|
/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
|
||||||
|
#pragma pack(push,8)
|
||||||
|
#else
|
||||||
|
#pragma pack(push,4)
|
||||||
|
#endif
|
||||||
|
#endif /* Compiler needs structure packing set */
|
||||||
|
|
||||||
|
#ifndef SDL_INLINE
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define SDL_INLINE __inline__
|
||||||
|
#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
|
||||||
|
defined(__DMC__) || defined(__SC__) || \
|
||||||
|
defined(__WATCOMC__) || defined(__LCC__) || \
|
||||||
|
defined(__DECC) || defined(__CC_ARM)
|
||||||
|
#define SDL_INLINE __inline
|
||||||
|
#ifndef __inline__
|
||||||
|
#define __inline__ __inline
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define SDL_INLINE inline
|
||||||
|
#ifndef __inline__
|
||||||
|
#define __inline__ inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif /* SDL_INLINE not defined */
|
||||||
|
|
||||||
|
#ifndef SDL_FORCE_INLINE
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define SDL_FORCE_INLINE __forceinline
|
||||||
|
#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
|
||||||
|
#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
|
||||||
|
#else
|
||||||
|
#define SDL_FORCE_INLINE static SDL_INLINE
|
||||||
|
#endif
|
||||||
|
#endif /* SDL_FORCE_INLINE not defined */
|
||||||
|
|
||||||
|
#ifndef SDL_NORETURN
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define SDL_NORETURN __attribute__((noreturn))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define SDL_NORETURN __declspec(noreturn)
|
||||||
|
#else
|
||||||
|
#define SDL_NORETURN
|
||||||
|
#endif
|
||||||
|
#endif /* SDL_NORETURN not defined */
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#if __has_feature(attribute_analyzer_noreturn)
|
||||||
|
#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SDL_ANALYZER_NORETURN
|
||||||
|
#define SDL_ANALYZER_NORETURN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Apparently this is needed by several Windows compilers */
|
||||||
|
#ifndef __MACH__
|
||||||
|
#ifndef NULL
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define NULL 0
|
||||||
|
#else
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
#endif /* NULL */
|
||||||
|
#endif /* ! macOS - breaks precompiled headers */
|
||||||
|
|
||||||
|
#ifndef SDL_FALLTHROUGH
|
||||||
|
#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
|
||||||
|
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L)
|
||||||
|
#define SDL_FALLTHROUGH [[fallthrough]]
|
||||||
|
#else
|
||||||
|
#if defined(__has_attribute) && !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
|
||||||
|
#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__)
|
||||||
|
#else
|
||||||
|
#define SDL_HAS_FALLTHROUGH 0
|
||||||
|
#endif /* __has_attribute */
|
||||||
|
#if SDL_HAS_FALLTHROUGH && \
|
||||||
|
((defined(__GNUC__) && __GNUC__ >= 7) || \
|
||||||
|
(defined(__clang_major__) && __clang_major__ >= 10))
|
||||||
|
#define SDL_FALLTHROUGH __attribute__((__fallthrough__))
|
||||||
|
#else
|
||||||
|
#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */
|
||||||
|
#endif /* SDL_HAS_FALLTHROUGH */
|
||||||
|
#undef SDL_HAS_FALLTHROUGH
|
||||||
|
#endif /* C++17 or C2x */
|
||||||
|
#endif /* SDL_FALLTHROUGH not defined */
|
||||||
|
|
||||||
|
#ifndef SDL_NODISCARD
|
||||||
|
#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
|
||||||
|
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
|
||||||
|
#define SDL_NODISCARD [[nodiscard]]
|
||||||
|
#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
|
||||||
|
#define SDL_NODISCARD __attribute__((warn_unused_result))
|
||||||
|
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
|
||||||
|
#define SDL_NODISCARD _Check_return_
|
||||||
|
#else
|
||||||
|
#define SDL_NODISCARD
|
||||||
|
#endif /* C++17 or C23 */
|
||||||
|
#endif /* SDL_NODISCARD not defined */
|
||||||
|
|
||||||
|
#ifndef SDL_MALLOC
|
||||||
|
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
||||||
|
#define SDL_MALLOC __attribute__((malloc))
|
||||||
|
/** FIXME
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
|
||||||
|
**/
|
||||||
|
#else
|
||||||
|
#define SDL_MALLOC
|
||||||
|
#endif
|
||||||
|
#endif /* SDL_MALLOC not defined */
|
||||||
|
|
||||||
|
#ifndef SDL_ALLOC_SIZE
|
||||||
|
#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||||
|
#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define SDL_ALLOC_SIZE(p)
|
||||||
|
#else
|
||||||
|
#define SDL_ALLOC_SIZE(p)
|
||||||
|
#endif
|
||||||
|
#endif /* SDL_ALLOC_SIZE not defined */
|
||||||
|
|
||||||
|
#ifndef SDL_ALLOC_SIZE2
|
||||||
|
#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||||
|
#define SDL_ALLOC_SIZE2(p1, p2) __attribute__((alloc_size(p1, p2)))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define SDL_ALLOC_SIZE2(p1, p2)
|
||||||
|
#else
|
||||||
|
#define SDL_ALLOC_SIZE2(p1, p2)
|
||||||
|
#endif
|
||||||
|
#endif /* SDL_ALLOC_SIZE2 not defined */
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryBits
|
||||||
|
*
|
||||||
|
* Functions for fiddling with bits and bitmasks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_bits_h_
|
||||||
|
#define SDL_bits_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_begin_code.h>
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__WATCOMC__) && defined(__386__)
|
||||||
|
extern __inline int _SDL_bsr_watcom(Uint32);
|
||||||
|
#pragma aux _SDL_bsr_watcom = \
|
||||||
|
"bsr eax, eax" \
|
||||||
|
parm [eax] nomemory \
|
||||||
|
value [eax] \
|
||||||
|
modify exact [eax] nomemory;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the index of the most significant (set) bit in a 32-bit number.
|
||||||
|
*
|
||||||
|
* Result is undefined when called with 0. This operation can also be stated
|
||||||
|
* as "count leading zeroes" and "log base 2".
|
||||||
|
*
|
||||||
|
* Note that this is a forced-inline function in a header, and not a public
|
||||||
|
* API function available in the SDL library (which is to say, the code is
|
||||||
|
* embedded in the calling program and the linker and dynamic loader will not
|
||||||
|
* be able to find this function inside SDL itself).
|
||||||
|
*
|
||||||
|
* \param x the 32-bit value to examine.
|
||||||
|
* \returns the index of the most significant bit, or -1 if the value is 0.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x)
|
||||||
|
{
|
||||||
|
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||||
|
/* Count Leading Zeroes builtin in GCC.
|
||||||
|
* http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html
|
||||||
|
*/
|
||||||
|
if (x == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 31 - __builtin_clz(x);
|
||||||
|
#elif defined(__WATCOMC__) && defined(__386__)
|
||||||
|
if (x == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return _SDL_bsr_watcom(x);
|
||||||
|
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||||
|
unsigned long index;
|
||||||
|
if (_BitScanReverse(&index, x)) {
|
||||||
|
return (int)index;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
/* Based off of Bit Twiddling Hacks by Sean Eron Anderson
|
||||||
|
* <seander@cs.stanford.edu>, released in the public domain.
|
||||||
|
* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
|
||||||
|
*/
|
||||||
|
const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
|
||||||
|
const int S[] = {1, 2, 4, 8, 16};
|
||||||
|
|
||||||
|
int msbIndex = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (x == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 4; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (x & b[i])
|
||||||
|
{
|
||||||
|
x >>= S[i];
|
||||||
|
msbIndex |= S[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msbIndex;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a unsigned 32-bit value has exactly one bit set.
|
||||||
|
*
|
||||||
|
* If there are no bits set (`x` is zero), or more than one bit set, this
|
||||||
|
* returns false. If any one bit is exclusively set, this returns true.
|
||||||
|
*
|
||||||
|
* Note that this is a forced-inline function in a header, and not a public
|
||||||
|
* API function available in the SDL library (which is to say, the code is
|
||||||
|
* embedded in the calling program and the linker and dynamic loader will not
|
||||||
|
* be able to find this function inside SDL itself).
|
||||||
|
*
|
||||||
|
* \param x the 32-bit value to examine.
|
||||||
|
* \returns true if exactly one bit is set in `x`, false otherwise.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
SDL_FORCE_INLINE bool SDL_HasExactlyOneBitSet32(Uint32 x)
|
||||||
|
{
|
||||||
|
if (x && !(x & (x - 1))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <SDL3/SDL_close_code.h>
|
||||||
|
|
||||||
|
#endif /* SDL_bits_h_ */
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryBlendmode
|
||||||
|
*
|
||||||
|
* Blend modes decide how two colors will mix together. There are both
|
||||||
|
* standard modes for basic needs and a means to create custom modes,
|
||||||
|
* dictating what sort of math to do on what color components.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_blendmode_h_
|
||||||
|
#define SDL_blendmode_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_begin_code.h>
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of blend modes used in drawing operations.
|
||||||
|
*
|
||||||
|
* These predefined blend modes are supported everywhere.
|
||||||
|
*
|
||||||
|
* Additional values may be obtained from SDL_ComposeCustomBlendMode.
|
||||||
|
*
|
||||||
|
* \since This datatype is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_ComposeCustomBlendMode
|
||||||
|
*/
|
||||||
|
typedef Uint32 SDL_BlendMode;
|
||||||
|
|
||||||
|
#define SDL_BLENDMODE_NONE 0x00000000u /**< no blending: dstRGBA = srcRGBA */
|
||||||
|
#define SDL_BLENDMODE_BLEND 0x00000001u /**< alpha blending: dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)), dstA = srcA + (dstA * (1-srcA)) */
|
||||||
|
#define SDL_BLENDMODE_BLEND_PREMULTIPLIED 0x00000010u /**< pre-multiplied alpha blending: dstRGBA = srcRGBA + (dstRGBA * (1-srcA)) */
|
||||||
|
#define SDL_BLENDMODE_ADD 0x00000002u /**< additive blending: dstRGB = (srcRGB * srcA) + dstRGB, dstA = dstA */
|
||||||
|
#define SDL_BLENDMODE_ADD_PREMULTIPLIED 0x00000020u /**< pre-multiplied additive blending: dstRGB = srcRGB + dstRGB, dstA = dstA */
|
||||||
|
#define SDL_BLENDMODE_MOD 0x00000004u /**< color modulate: dstRGB = srcRGB * dstRGB, dstA = dstA */
|
||||||
|
#define SDL_BLENDMODE_MUL 0x00000008u /**< color multiply: dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)), dstA = dstA */
|
||||||
|
#define SDL_BLENDMODE_INVALID 0x7FFFFFFFu
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The blend operation used when combining source and destination pixel
|
||||||
|
* components.
|
||||||
|
*
|
||||||
|
* \since This enum is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef enum SDL_BlendOperation
|
||||||
|
{
|
||||||
|
SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */
|
||||||
|
SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< src - dst : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||||
|
SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< dst - src : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||||
|
SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||||
|
SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||||
|
} SDL_BlendOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The normalized factor used to multiply pixel components.
|
||||||
|
*
|
||||||
|
* The blend factors are multiplied with the pixels from a drawing operation
|
||||||
|
* (src) and the pixels from the render target (dst) before the blend
|
||||||
|
* operation. The comma-separated factors listed above are always applied in
|
||||||
|
* the component order red, green, blue, and alpha.
|
||||||
|
*
|
||||||
|
* \since This enum is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef enum SDL_BlendFactor
|
||||||
|
{
|
||||||
|
SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */
|
||||||
|
SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */
|
||||||
|
SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */
|
||||||
|
SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */
|
||||||
|
SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */
|
||||||
|
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */
|
||||||
|
SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */
|
||||||
|
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */
|
||||||
|
SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */
|
||||||
|
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */
|
||||||
|
} SDL_BlendFactor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compose a custom blend mode for renderers.
|
||||||
|
*
|
||||||
|
* The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept
|
||||||
|
* the SDL_BlendMode returned by this function if the renderer supports it.
|
||||||
|
*
|
||||||
|
* A blend mode controls how the pixels from a drawing operation (source) get
|
||||||
|
* combined with the pixels from the render target (destination). First, the
|
||||||
|
* components of the source and destination pixels get multiplied with their
|
||||||
|
* blend factors. Then, the blend operation takes the two products and
|
||||||
|
* calculates the result that will get stored in the render target.
|
||||||
|
*
|
||||||
|
* Expressed in pseudocode, it would look like this:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor);
|
||||||
|
* dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Where the functions `colorOperation(src, dst)` and `alphaOperation(src,
|
||||||
|
* dst)` can return one of the following:
|
||||||
|
*
|
||||||
|
* - `src + dst`
|
||||||
|
* - `src - dst`
|
||||||
|
* - `dst - src`
|
||||||
|
* - `min(src, dst)`
|
||||||
|
* - `max(src, dst)`
|
||||||
|
*
|
||||||
|
* The red, green, and blue components are always multiplied with the first,
|
||||||
|
* second, and third components of the SDL_BlendFactor, respectively. The
|
||||||
|
* fourth component is not used.
|
||||||
|
*
|
||||||
|
* The alpha component is always multiplied with the fourth component of the
|
||||||
|
* SDL_BlendFactor. The other components are not used in the alpha
|
||||||
|
* calculation.
|
||||||
|
*
|
||||||
|
* Support for these blend modes varies for each renderer. To check if a
|
||||||
|
* specific SDL_BlendMode is supported, create a renderer and pass it to
|
||||||
|
* either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will
|
||||||
|
* return with an error if the blend mode is not supported.
|
||||||
|
*
|
||||||
|
* This list describes the support of custom blend modes for each renderer.
|
||||||
|
* All renderers support the four blend modes listed in the SDL_BlendMode
|
||||||
|
* enumeration.
|
||||||
|
*
|
||||||
|
* - **direct3d**: Supports all operations with all factors. However, some
|
||||||
|
* factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and
|
||||||
|
* `SDL_BLENDOPERATION_MAXIMUM`.
|
||||||
|
* - **direct3d11**: Same as Direct3D 9.
|
||||||
|
* - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all
|
||||||
|
* factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly here.
|
||||||
|
* - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`,
|
||||||
|
* `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT`
|
||||||
|
* operations with all factors.
|
||||||
|
* - **psp**: No custom blend mode support.
|
||||||
|
* - **software**: No custom blend mode support.
|
||||||
|
*
|
||||||
|
* Some renderers do not provide an alpha component for the default render
|
||||||
|
* target. The `SDL_BLENDFACTOR_DST_ALPHA` and
|
||||||
|
* `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this
|
||||||
|
* case.
|
||||||
|
*
|
||||||
|
* \param srcColorFactor the SDL_BlendFactor applied to the red, green, and
|
||||||
|
* blue components of the source pixels.
|
||||||
|
* \param dstColorFactor the SDL_BlendFactor applied to the red, green, and
|
||||||
|
* blue components of the destination pixels.
|
||||||
|
* \param colorOperation the SDL_BlendOperation used to combine the red,
|
||||||
|
* green, and blue components of the source and
|
||||||
|
* destination pixels.
|
||||||
|
* \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of
|
||||||
|
* the source pixels.
|
||||||
|
* \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of
|
||||||
|
* the destination pixels.
|
||||||
|
* \param alphaOperation the SDL_BlendOperation used to combine the alpha
|
||||||
|
* component of the source and destination pixels.
|
||||||
|
* \returns an SDL_BlendMode that represents the chosen factors and
|
||||||
|
* operations.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetRenderDrawBlendMode
|
||||||
|
* \sa SDL_GetRenderDrawBlendMode
|
||||||
|
* \sa SDL_SetTextureBlendMode
|
||||||
|
* \sa SDL_GetTextureBlendMode
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor,
|
||||||
|
SDL_BlendFactor dstColorFactor,
|
||||||
|
SDL_BlendOperation colorOperation,
|
||||||
|
SDL_BlendFactor srcAlphaFactor,
|
||||||
|
SDL_BlendFactor dstAlphaFactor,
|
||||||
|
SDL_BlendOperation alphaOperation);
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <SDL3/SDL_close_code.h>
|
||||||
|
|
||||||
|
#endif /* SDL_blendmode_h_ */
|
||||||
@@ -0,0 +1,519 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryCamera
|
||||||
|
*
|
||||||
|
* Video capture for the SDL library.
|
||||||
|
*
|
||||||
|
* This API lets apps read input from video sources, like webcams. Camera
|
||||||
|
* devices can be enumerated, queried, and opened. Once opened, it will
|
||||||
|
* provide SDL_Surface objects as new frames of video come in. These surfaces
|
||||||
|
* can be uploaded to an SDL_Texture or processed as pixels in memory.
|
||||||
|
*
|
||||||
|
* Several platforms will alert the user if an app tries to access a camera,
|
||||||
|
* and some will present a UI asking the user if your application should be
|
||||||
|
* allowed to obtain images at all, which they can deny. A successfully opened
|
||||||
|
* camera will not provide images until permission is granted. Applications,
|
||||||
|
* after opening a camera device, can see if they were granted access by
|
||||||
|
* either polling with the SDL_GetCameraPermissionState() function, or waiting
|
||||||
|
* for an SDL_EVENT_CAMERA_DEVICE_APPROVED or SDL_EVENT_CAMERA_DEVICE_DENIED
|
||||||
|
* event. Platforms that don't have any user approval process will report
|
||||||
|
* approval immediately.
|
||||||
|
*
|
||||||
|
* Note that SDL cameras only provide video as individual frames; they will
|
||||||
|
* not provide full-motion video encoded in a movie file format, although an
|
||||||
|
* app is free to encode the acquired frames into any format it likes. It also
|
||||||
|
* does not provide audio from the camera hardware through this API; not only
|
||||||
|
* do many webcams not have microphones at all, many people--from streamers to
|
||||||
|
* people on Zoom calls--will want to use a separate microphone regardless of
|
||||||
|
* the camera. In any case, recorded audio will be available through SDL's
|
||||||
|
* audio API no matter what hardware provides the microphone.
|
||||||
|
*
|
||||||
|
* ## Camera gotchas
|
||||||
|
*
|
||||||
|
* Consumer-level camera hardware tends to take a little while to warm up,
|
||||||
|
* once the device has been opened. Generally most camera apps have some sort
|
||||||
|
* of UI to take a picture (a button to snap a pic while a preview is showing,
|
||||||
|
* some sort of multi-second countdown for the user to pose, like a photo
|
||||||
|
* booth), which puts control in the users' hands, or they are intended to
|
||||||
|
* stay on for long times (Pokemon Go, etc).
|
||||||
|
*
|
||||||
|
* It's not uncommon that a newly-opened camera will provide a couple of
|
||||||
|
* completely black frames, maybe followed by some under-exposed images. If
|
||||||
|
* taking a single frame automatically, or recording video from a camera's
|
||||||
|
* input without the user initiating it from a preview, it could be wise to
|
||||||
|
* drop the first several frames (if not the first several _seconds_ worth of
|
||||||
|
* frames!) before using images from a camera.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_camera_h_
|
||||||
|
#define SDL_camera_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
#include <SDL3/SDL_error.h>
|
||||||
|
#include <SDL3/SDL_pixels.h>
|
||||||
|
#include <SDL3/SDL_properties.h>
|
||||||
|
#include <SDL3/SDL_surface.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_begin_code.h>
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a unique ID for a camera device for the time it is connected to the
|
||||||
|
* system, and is never reused for the lifetime of the application.
|
||||||
|
*
|
||||||
|
* If the device is disconnected and reconnected, it will get a new ID.
|
||||||
|
*
|
||||||
|
* The value 0 is an invalid ID.
|
||||||
|
*
|
||||||
|
* \since This datatype is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameras
|
||||||
|
*/
|
||||||
|
typedef Uint32 SDL_CameraID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The opaque structure used to identify an opened SDL camera.
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
typedef struct SDL_Camera SDL_Camera;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The details of an output format for a camera device.
|
||||||
|
*
|
||||||
|
* Cameras often support multiple formats; each one will be encapsulated in
|
||||||
|
* this struct.
|
||||||
|
*
|
||||||
|
* \since This struct is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameraSupportedFormats
|
||||||
|
* \sa SDL_GetCameraFormat
|
||||||
|
*/
|
||||||
|
typedef struct SDL_CameraSpec
|
||||||
|
{
|
||||||
|
SDL_PixelFormat format; /**< Frame format */
|
||||||
|
SDL_Colorspace colorspace; /**< Frame colorspace */
|
||||||
|
int width; /**< Frame width */
|
||||||
|
int height; /**< Frame height */
|
||||||
|
int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||||
|
int framerate_denominator; /**< Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||||
|
} SDL_CameraSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position of camera in relation to system device.
|
||||||
|
*
|
||||||
|
* \since This enum is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameraPosition
|
||||||
|
*/
|
||||||
|
typedef enum SDL_CameraPosition
|
||||||
|
{
|
||||||
|
SDL_CAMERA_POSITION_UNKNOWN,
|
||||||
|
SDL_CAMERA_POSITION_FRONT_FACING,
|
||||||
|
SDL_CAMERA_POSITION_BACK_FACING
|
||||||
|
} SDL_CameraPosition;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to get the number of built-in camera drivers.
|
||||||
|
*
|
||||||
|
* This function returns a hardcoded number. This never returns a negative
|
||||||
|
* value; if there are no drivers compiled into this build of SDL, this
|
||||||
|
* function returns zero. The presence of a driver in this list does not mean
|
||||||
|
* it will function, it just means SDL is capable of interacting with that
|
||||||
|
* interface. For example, a build of SDL might have v4l2 support, but if
|
||||||
|
* there's no kernel support available, SDL's v4l2 driver would fail if used.
|
||||||
|
*
|
||||||
|
* By default, SDL tries all drivers, in its preferred order, until one is
|
||||||
|
* found to be usable.
|
||||||
|
*
|
||||||
|
* \returns the number of built-in camera drivers.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameraDriver
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_GetNumCameraDrivers(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to get the name of a built in camera driver.
|
||||||
|
*
|
||||||
|
* The list of camera drivers is given in the order that they are normally
|
||||||
|
* initialized by default; the drivers that seem more reasonable to choose
|
||||||
|
* first (as far as the SDL developers believe) are earlier in the list.
|
||||||
|
*
|
||||||
|
* The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
|
||||||
|
* "coremedia" or "android". These never have Unicode characters, and are not
|
||||||
|
* meant to be proper names.
|
||||||
|
*
|
||||||
|
* \param index the index of the camera driver; the value ranges from 0 to
|
||||||
|
* SDL_GetNumCameraDrivers() - 1.
|
||||||
|
* \returns the name of the camera driver at the requested index, or NULL if
|
||||||
|
* an invalid index was specified.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetNumCameraDrivers
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraDriver(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the current camera driver.
|
||||||
|
*
|
||||||
|
* The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
|
||||||
|
* "coremedia" or "android". These never have Unicode characters, and are not
|
||||||
|
* meant to be proper names.
|
||||||
|
*
|
||||||
|
* \returns the name of the current camera driver or NULL if no driver has
|
||||||
|
* been initialized.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCurrentCameraDriver(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of currently connected camera devices.
|
||||||
|
*
|
||||||
|
* \param count a pointer filled in with the number of cameras returned, may
|
||||||
|
* be NULL.
|
||||||
|
* \returns a 0 terminated array of camera instance IDs or NULL on failure;
|
||||||
|
* call SDL_GetError() for more information. This should be freed
|
||||||
|
* with SDL_free() when it is no longer needed.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_OpenCamera
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_CameraID * SDLCALL SDL_GetCameras(int *count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of native formats/sizes a camera supports.
|
||||||
|
*
|
||||||
|
* This returns a list of all formats and frame sizes that a specific camera
|
||||||
|
* can offer. This is useful if your app can accept a variety of image formats
|
||||||
|
* and sizes and so want to find the optimal spec that doesn't require
|
||||||
|
* conversion.
|
||||||
|
*
|
||||||
|
* This function isn't strictly required; if you call SDL_OpenCamera with a
|
||||||
|
* NULL spec, SDL will choose a native format for you, and if you instead
|
||||||
|
* specify a desired format, it will transparently convert to the requested
|
||||||
|
* format on your behalf.
|
||||||
|
*
|
||||||
|
* If `count` is not NULL, it will be filled with the number of elements in
|
||||||
|
* the returned array.
|
||||||
|
*
|
||||||
|
* Note that it's legal for a camera to supply an empty list. This is what
|
||||||
|
* will happen on Emscripten builds, since that platform won't tell _anything_
|
||||||
|
* about available cameras until you've opened one, and won't even tell if
|
||||||
|
* there _is_ a camera until the user has given you permission to check
|
||||||
|
* through a scary warning popup.
|
||||||
|
*
|
||||||
|
* \param instance_id the camera device instance ID.
|
||||||
|
* \param count a pointer filled in with the number of elements in the list,
|
||||||
|
* may be NULL.
|
||||||
|
* \returns a NULL terminated array of pointers to SDL_CameraSpec or NULL on
|
||||||
|
* failure; call SDL_GetError() for more information. This is a
|
||||||
|
* single allocation that should be freed with SDL_free() when it is
|
||||||
|
* no longer needed.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameras
|
||||||
|
* \sa SDL_OpenCamera
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_CameraSpec ** SDLCALL SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int *count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the human-readable device name for a camera.
|
||||||
|
*
|
||||||
|
* \param instance_id the camera device instance ID.
|
||||||
|
* \returns a human-readable device name or NULL on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameras
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraName(SDL_CameraID instance_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the position of the camera in relation to the system.
|
||||||
|
*
|
||||||
|
* Most platforms will report UNKNOWN, but mobile devices, like phones, can
|
||||||
|
* often make a distinction between cameras on the front of the device (that
|
||||||
|
* points towards the user, for taking "selfies") and cameras on the back (for
|
||||||
|
* filming in the direction the user is facing).
|
||||||
|
*
|
||||||
|
* \param instance_id the camera device instance ID.
|
||||||
|
* \returns the position of the camera on the system hardware.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameras
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_CameraPosition SDLCALL SDL_GetCameraPosition(SDL_CameraID instance_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a video recording device (a "camera").
|
||||||
|
*
|
||||||
|
* You can open the device with any reasonable spec, and if the hardware can't
|
||||||
|
* directly support it, it will convert data seamlessly to the requested
|
||||||
|
* format. This might incur overhead, including scaling of image data.
|
||||||
|
*
|
||||||
|
* If you would rather accept whatever format the device offers, you can pass
|
||||||
|
* a NULL spec here and it will choose one for you (and you can use
|
||||||
|
* SDL_Surface's conversion/scaling functions directly if necessary).
|
||||||
|
*
|
||||||
|
* You can call SDL_GetCameraFormat() to get the actual data format if passing
|
||||||
|
* a NULL spec here. You can see the exact specs a device can support without
|
||||||
|
* conversion with SDL_GetCameraSupportedFormats().
|
||||||
|
*
|
||||||
|
* SDL will not attempt to emulate framerate; it will try to set the hardware
|
||||||
|
* to the rate closest to the requested speed, but it won't attempt to limit
|
||||||
|
* or duplicate frames artificially; call SDL_GetCameraFormat() to see the
|
||||||
|
* actual framerate of the opened the device, and check your timestamps if
|
||||||
|
* this is crucial to your app!
|
||||||
|
*
|
||||||
|
* Note that the camera is not usable until the user approves its use! On some
|
||||||
|
* platforms, the operating system will prompt the user to permit access to
|
||||||
|
* the camera, and they can choose Yes or No at that point. Until they do, the
|
||||||
|
* camera will not be usable. The app should either wait for an
|
||||||
|
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
|
||||||
|
* or poll SDL_GetCameraPermissionState() occasionally until it returns
|
||||||
|
* non-zero. On platforms that don't require explicit user approval (and
|
||||||
|
* perhaps in places where the user previously permitted access), the approval
|
||||||
|
* event might come immediately, but it might come seconds, minutes, or hours
|
||||||
|
* later!
|
||||||
|
*
|
||||||
|
* \param instance_id the camera device instance ID.
|
||||||
|
* \param spec the desired format for data the device will provide. Can be
|
||||||
|
* NULL.
|
||||||
|
* \returns an SDL_Camera object or NULL on failure; call SDL_GetError() for
|
||||||
|
* more information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameras
|
||||||
|
* \sa SDL_GetCameraFormat
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_Camera * SDLCALL SDL_OpenCamera(SDL_CameraID instance_id, const SDL_CameraSpec *spec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query if camera access has been approved by the user.
|
||||||
|
*
|
||||||
|
* Cameras will not function between when the device is opened by the app and
|
||||||
|
* when the user permits access to the hardware. On some platforms, this
|
||||||
|
* presents as a popup dialog where the user has to explicitly approve access;
|
||||||
|
* on others the approval might be implicit and not alert the user at all.
|
||||||
|
*
|
||||||
|
* This function can be used to check the status of that approval. It will
|
||||||
|
* return 0 if still waiting for user response, 1 if the camera is approved
|
||||||
|
* for use, and -1 if the user denied access.
|
||||||
|
*
|
||||||
|
* Instead of polling with this function, you can wait for a
|
||||||
|
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event
|
||||||
|
* in the standard SDL event loop, which is guaranteed to be sent once when
|
||||||
|
* permission to use the camera is decided.
|
||||||
|
*
|
||||||
|
* If a camera is declined, there's nothing to be done but call
|
||||||
|
* SDL_CloseCamera() to dispose of it.
|
||||||
|
*
|
||||||
|
* \param camera the opened camera device to query.
|
||||||
|
* \returns -1 if user denied access to the camera, 1 if user approved access,
|
||||||
|
* 0 if no decision has been made yet.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_OpenCamera
|
||||||
|
* \sa SDL_CloseCamera
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC int SDLCALL SDL_GetCameraPermissionState(SDL_Camera *camera);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the instance ID of an opened camera.
|
||||||
|
*
|
||||||
|
* \param camera an SDL_Camera to query.
|
||||||
|
* \returns the instance ID of the specified camera on success or 0 on
|
||||||
|
* failure; call SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_OpenCamera
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_CameraID SDLCALL SDL_GetCameraID(SDL_Camera *camera);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the properties associated with an opened camera.
|
||||||
|
*
|
||||||
|
* \param camera the SDL_Camera obtained from SDL_OpenCamera().
|
||||||
|
* \returns a valid property ID on success or 0 on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetCameraProperties(SDL_Camera *camera);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the spec that a camera is using when generating images.
|
||||||
|
*
|
||||||
|
* Note that this might not be the native format of the hardware, as SDL might
|
||||||
|
* be converting to this format behind the scenes.
|
||||||
|
*
|
||||||
|
* If the system is waiting for the user to approve access to the camera, as
|
||||||
|
* some platforms require, this will return false, but this isn't necessarily
|
||||||
|
* a fatal error; you should either wait for an
|
||||||
|
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
|
||||||
|
* or poll SDL_GetCameraPermissionState() occasionally until it returns
|
||||||
|
* non-zero.
|
||||||
|
*
|
||||||
|
* \param camera opened camera device.
|
||||||
|
* \param spec the SDL_CameraSpec to be initialized by this function.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_OpenCamera
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_GetCameraFormat(SDL_Camera *camera, SDL_CameraSpec *spec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire a frame.
|
||||||
|
*
|
||||||
|
* The frame is a memory pointer to the image data, whose size and format are
|
||||||
|
* given by the spec requested when opening the device.
|
||||||
|
*
|
||||||
|
* This is a non blocking API. If there is a frame available, a non-NULL
|
||||||
|
* surface is returned, and timestampNS will be filled with a non-zero value.
|
||||||
|
*
|
||||||
|
* Note that an error case can also return NULL, but a NULL by itself is
|
||||||
|
* normal and just signifies that a new frame is not yet available. Note that
|
||||||
|
* even if a camera device fails outright (a USB camera is unplugged while in
|
||||||
|
* use, etc), SDL will send an event separately to notify the app, but
|
||||||
|
* continue to provide blank frames at ongoing intervals until
|
||||||
|
* SDL_CloseCamera() is called, so real failure here is almost always an out
|
||||||
|
* of memory condition.
|
||||||
|
*
|
||||||
|
* After use, the frame should be released with SDL_ReleaseCameraFrame(). If
|
||||||
|
* you don't do this, the system may stop providing more video!
|
||||||
|
*
|
||||||
|
* Do not call SDL_DestroySurface() on the returned surface! It must be given
|
||||||
|
* back to the camera subsystem with SDL_ReleaseCameraFrame!
|
||||||
|
*
|
||||||
|
* If the system is waiting for the user to approve access to the camera, as
|
||||||
|
* some platforms require, this will return NULL (no frames available); you
|
||||||
|
* should either wait for an SDL_EVENT_CAMERA_DEVICE_APPROVED (or
|
||||||
|
* SDL_EVENT_CAMERA_DEVICE_DENIED) event, or poll
|
||||||
|
* SDL_GetCameraPermissionState() occasionally until it returns non-zero.
|
||||||
|
*
|
||||||
|
* \param camera opened camera device.
|
||||||
|
* \param timestampNS a pointer filled in with the frame's timestamp, or 0 on
|
||||||
|
* error. Can be NULL.
|
||||||
|
* \returns a new frame of video on success, NULL if none is currently
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_ReleaseCameraFrame
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_AcquireCameraFrame(SDL_Camera *camera, Uint64 *timestampNS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release a frame of video acquired from a camera.
|
||||||
|
*
|
||||||
|
* Let the back-end re-use the internal buffer for camera.
|
||||||
|
*
|
||||||
|
* This function _must_ be called only on surface objects returned by
|
||||||
|
* SDL_AcquireCameraFrame(). This function should be called as quickly as
|
||||||
|
* possible after acquisition, as SDL keeps a small FIFO queue of surfaces for
|
||||||
|
* video frames; if surfaces aren't released in a timely manner, SDL may drop
|
||||||
|
* upcoming video frames from the camera.
|
||||||
|
*
|
||||||
|
* If the app needs to keep the surface for a significant time, they should
|
||||||
|
* make a copy of it and release the original.
|
||||||
|
*
|
||||||
|
* The app should not use the surface again after calling this function;
|
||||||
|
* assume the surface is freed and the pointer is invalid.
|
||||||
|
*
|
||||||
|
* \param camera opened camera device.
|
||||||
|
* \param frame the video frame surface to release.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_AcquireCameraFrame
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_ReleaseCameraFrame(SDL_Camera *camera, SDL_Surface *frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to shut down camera processing and close the camera
|
||||||
|
* device.
|
||||||
|
*
|
||||||
|
* \param camera opened camera device.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread, but no
|
||||||
|
* thread may reference `device` once this function is called.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_OpenCamera
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_CloseCamera(SDL_Camera *camera);
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <SDL3/SDL_close_code.h>
|
||||||
|
|
||||||
|
#endif /* SDL_camera_h_ */
|
||||||
@@ -0,0 +1,331 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # CategoryClipboard
|
||||||
|
*
|
||||||
|
* SDL provides access to the system clipboard, both for reading information
|
||||||
|
* from other processes and publishing information of its own.
|
||||||
|
*
|
||||||
|
* This is not just text! SDL apps can access and publish data by mimetype.
|
||||||
|
*
|
||||||
|
* ## Basic use (text)
|
||||||
|
*
|
||||||
|
* Obtaining and publishing simple text to the system clipboard is as easy as
|
||||||
|
* calling SDL_GetClipboardText() and SDL_SetClipboardText(), respectively.
|
||||||
|
* These deal with C strings in UTF-8 encoding. Data transmission and encoding
|
||||||
|
* conversion is completely managed by SDL.
|
||||||
|
*
|
||||||
|
* ## Clipboard callbacks (data other than text)
|
||||||
|
*
|
||||||
|
* Things get more complicated when the clipboard contains something other
|
||||||
|
* than text. Not only can the system clipboard contain data of any type, in
|
||||||
|
* some cases it can contain the same data in different formats! For example,
|
||||||
|
* an image painting app might let the user copy a graphic to the clipboard,
|
||||||
|
* and offers it in .BMP, .JPG, or .PNG format for other apps to consume.
|
||||||
|
*
|
||||||
|
* Obtaining clipboard data ("pasting") like this is a matter of calling
|
||||||
|
* SDL_GetClipboardData() and telling it the mimetype of the data you want.
|
||||||
|
* But how does one know if that format is available? SDL_HasClipboardData()
|
||||||
|
* can report if a specific mimetype is offered, and
|
||||||
|
* SDL_GetClipboardMimeTypes() can provide the entire list of mimetypes
|
||||||
|
* available, so the app can decide what to do with the data and what formats
|
||||||
|
* it can support.
|
||||||
|
*
|
||||||
|
* Setting the clipboard ("copying") to arbitrary data is done with
|
||||||
|
* SDL_SetClipboardData. The app does not provide the data in this call, but
|
||||||
|
* rather the mimetypes it is willing to provide and a callback function.
|
||||||
|
* During the callback, the app will generate the data. This allows massive
|
||||||
|
* data sets to be provided to the clipboard, without any data being copied
|
||||||
|
* before it is explicitly requested. More specifically, it allows an app to
|
||||||
|
* offer data in multiple formats without providing a copy of all of them
|
||||||
|
* upfront. If the app has an image that it could provide in PNG or JPG
|
||||||
|
* format, it doesn't have to encode it to either of those unless and until
|
||||||
|
* something tries to paste it.
|
||||||
|
*
|
||||||
|
* ## Primary Selection
|
||||||
|
*
|
||||||
|
* The X11 and Wayland video targets have a concept of the "primary selection"
|
||||||
|
* in addition to the usual clipboard. This is generally highlighted (but not
|
||||||
|
* explicitly copied) text from various apps. SDL offers APIs for this through
|
||||||
|
* SDL_GetPrimarySelectionText() and SDL_SetPrimarySelectionText(). SDL offers
|
||||||
|
* these APIs on platforms without this concept, too, but only so far that it
|
||||||
|
* will keep a copy of a string that the app sets for later retrieval; the
|
||||||
|
* operating system will not ever attempt to change the string externally if
|
||||||
|
* it doesn't support a primary selection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL_clipboard_h_
|
||||||
|
#define SDL_clipboard_h_
|
||||||
|
|
||||||
|
#include <SDL3/SDL_stdinc.h>
|
||||||
|
#include <SDL3/SDL_error.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_begin_code.h>
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Function prototypes */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put UTF-8 text into the clipboard.
|
||||||
|
*
|
||||||
|
* \param text the text to store in the clipboard.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetClipboardText
|
||||||
|
* \sa SDL_HasClipboardText
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get UTF-8 text from the clipboard.
|
||||||
|
*
|
||||||
|
* This function returns an empty string if there is not enough memory left
|
||||||
|
* for a copy of the clipboard's content.
|
||||||
|
*
|
||||||
|
* \returns the clipboard text on success or an empty string on failure; call
|
||||||
|
* SDL_GetError() for more information. This should be freed with
|
||||||
|
* SDL_free() when it is no longer needed.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_HasClipboardText
|
||||||
|
* \sa SDL_SetClipboardText
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC char * SDLCALL SDL_GetClipboardText(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query whether the clipboard exists and contains a non-empty text string.
|
||||||
|
*
|
||||||
|
* \returns true if the clipboard has text, or false if it does not.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetClipboardText
|
||||||
|
* \sa SDL_SetClipboardText
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardText(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put UTF-8 text into the primary selection.
|
||||||
|
*
|
||||||
|
* \param text the text to store in the primary selection.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetPrimarySelectionText
|
||||||
|
* \sa SDL_HasPrimarySelectionText
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get UTF-8 text from the primary selection.
|
||||||
|
*
|
||||||
|
* This function returns an empty string if there is not enough memory left
|
||||||
|
* for a copy of the primary selection's content.
|
||||||
|
*
|
||||||
|
* \returns the primary selection text on success or an empty string on
|
||||||
|
* failure; call SDL_GetError() for more information. This should be
|
||||||
|
* freed with SDL_free() when it is no longer needed.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_HasPrimarySelectionText
|
||||||
|
* \sa SDL_SetPrimarySelectionText
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC char * SDLCALL SDL_GetPrimarySelectionText(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query whether the primary selection exists and contains a non-empty text
|
||||||
|
* string.
|
||||||
|
*
|
||||||
|
* \returns true if the primary selection has text, or false if it does not.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetPrimarySelectionText
|
||||||
|
* \sa SDL_SetPrimarySelectionText
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function that will be called when data for the specified mime-type
|
||||||
|
* is requested by the OS.
|
||||||
|
*
|
||||||
|
* The callback function is called with NULL as the mime_type when the
|
||||||
|
* clipboard is cleared or new data is set. The clipboard is automatically
|
||||||
|
* cleared in SDL_Quit().
|
||||||
|
*
|
||||||
|
* \param userdata a pointer to the provided user data.
|
||||||
|
* \param mime_type the requested mime-type.
|
||||||
|
* \param size a pointer filled in with the length of the returned data.
|
||||||
|
* \returns a pointer to the data for the provided mime-type. Returning NULL
|
||||||
|
* or setting the length to 0 will cause no data to be sent to the
|
||||||
|
* "receiver". It is up to the receiver to handle this. Essentially
|
||||||
|
* returning no data is more or less undefined behavior and may cause
|
||||||
|
* breakage in receiving applications. The returned data will not be
|
||||||
|
* freed, so it needs to be retained and dealt with internally.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetClipboardData
|
||||||
|
*/
|
||||||
|
typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function that will be called when the clipboard is cleared, or when new
|
||||||
|
* data is set.
|
||||||
|
*
|
||||||
|
* \param userdata a pointer to the provided user data.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetClipboardData
|
||||||
|
*/
|
||||||
|
typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offer clipboard data to the OS.
|
||||||
|
*
|
||||||
|
* Tell the operating system that the application is offering clipboard data
|
||||||
|
* for each of the provided mime-types. Once another application requests the
|
||||||
|
* data the callback function will be called, allowing it to generate and
|
||||||
|
* respond with the data for the requested mime-type.
|
||||||
|
*
|
||||||
|
* The size of text data does not include any terminator, and the text does
|
||||||
|
* not need to be null-terminated (e.g., you can directly copy a portion of a
|
||||||
|
* document).
|
||||||
|
*
|
||||||
|
* \param callback a function pointer to the function that provides the
|
||||||
|
* clipboard data.
|
||||||
|
* \param cleanup a function pointer to the function that cleans up the
|
||||||
|
* clipboard data.
|
||||||
|
* \param userdata an opaque pointer that will be forwarded to the callbacks.
|
||||||
|
* \param mime_types a list of mime-types that are being offered. SDL copies the given list.
|
||||||
|
* \param num_mime_types the number of mime-types in the mime_types list.
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_ClearClipboardData
|
||||||
|
* \sa SDL_GetClipboardData
|
||||||
|
* \sa SDL_HasClipboardData
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char **mime_types, size_t num_mime_types);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the clipboard data.
|
||||||
|
*
|
||||||
|
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetClipboardData
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data from the clipboard for a given mime type.
|
||||||
|
*
|
||||||
|
* The size of text data does not include the terminator, but the text is
|
||||||
|
* guaranteed to be null-terminated.
|
||||||
|
*
|
||||||
|
* \param mime_type the mime type to read from the clipboard.
|
||||||
|
* \param size a pointer filled in with the length of the returned data.
|
||||||
|
* \returns the retrieved data buffer or NULL on failure; call SDL_GetError()
|
||||||
|
* for more information. This should be freed with SDL_free() when it
|
||||||
|
* is no longer needed.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_HasClipboardData
|
||||||
|
* \sa SDL_SetClipboardData
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, size_t *size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query whether there is data in the clipboard for the provided mime type.
|
||||||
|
*
|
||||||
|
* \param mime_type the mime type to check for data.
|
||||||
|
* \returns true if data exists in the clipboard for the provided mime type,
|
||||||
|
* false if it does not.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetClipboardData
|
||||||
|
* \sa SDL_GetClipboardData
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the list of mime types available in the clipboard.
|
||||||
|
*
|
||||||
|
* \param num_mime_types a pointer filled with the number of mime types, may
|
||||||
|
* be NULL.
|
||||||
|
* \returns a null-terminated array of strings with mime types, or NULL on
|
||||||
|
* failure; call SDL_GetError() for more information. This should be
|
||||||
|
* freed with SDL_free() when it is no longer needed.
|
||||||
|
*
|
||||||
|
* \threadsafety This function should only be called on the main thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetClipboardData
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC char ** SDLCALL SDL_GetClipboardMimeTypes(size_t *num_mime_types);
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <SDL3/SDL_close_code.h>
|
||||||
|
|
||||||
|
#endif /* SDL_clipboard_h_ */
|
||||||