Compare commits
203 Commits
dd13a2bd7c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 10a3e2fedd | |||
| 25a36d5064 | |||
| 8706b2c7fb | |||
| d493ebf4f0 | |||
| 3e795998d1 | |||
| c694781f38 | |||
| 1a2298963d | |||
| 4c1ed1cf9b | |||
| f80d0a656e | |||
| 4429cd92c1 | |||
| 4ac34b8583 | |||
| cf7ea6cc9c | |||
| f5da35bfb2 | |||
| c0accd25e2 | |||
| ad8ad7e756 | |||
| 673587230e | |||
| 8538a1047f | |||
| e150097edc | |||
| 5f0d1f9577 | |||
| 6d8d02f0e4 | |||
| 5f7fb8625d | |||
| ce2fcefd71 | |||
| 6f31751d42 | |||
| 43de2c0b35 | |||
| 1ca9d0c01b | |||
| 90d5e6c3cc | |||
| a653dad7b0 | |||
| cf1f97a84f | |||
| 93fe17c3b2 | |||
| 3c2a5c9b37 | |||
| 270cd1d487 | |||
| 58512840a4 | |||
| 2f3161d701 | |||
| 99cc803f21 | |||
| d42b1753d0 | |||
| a1d17ccf99 | |||
| 3ca744ee46 | |||
| 302b86ddb4 | |||
| 81daf725d5 | |||
| d80c673882 | |||
| 4ac123abb0 | |||
| cb22ff321f | |||
| c35889a840 | |||
| c610065fe0 | |||
| d2be113c4e | |||
| 052bb063df | |||
| 9d974438b3 | |||
| b9fe376f2a | |||
| 0c05f6d5b6 | |||
| 39125ee57c | |||
| 7ebeeebaaf | |||
| c6c7b63f6d | |||
| 7959baeed9 | |||
| 5d1c6c6d99 | |||
| 145d1e3fc0 | |||
| 4679255d60 | |||
| 3cfb65320c | |||
| 636e4d932a | |||
| 9979f31b4a | |||
| 6190b35349 | |||
| fd4136a882 | |||
| 5362c5b022 | |||
| 357b5d5977 | |||
| f50ad68f10 | |||
| 155a7d038d | |||
| 4b732c189c | |||
| 1c3d59d678 | |||
| 1acbe1d097 | |||
| 245524c021 | |||
| b4624a9223 | |||
| 28e3e1ee0a | |||
| e250ca048f | |||
| 5bf96b9aba | |||
| ac6f521288 | |||
| 5a5c06efd1 | |||
| ef1a514c9b | |||
| ce54b10abb | |||
| 40538eaa28 | |||
| 88d814f371 | |||
| b933ceee63 | |||
| 75ccddbaa1 | |||
| fde77affdf | |||
| 52a387463d | |||
| 5a0fc9330d | |||
| 66661036a4 | |||
| bb132aade2 | |||
| d4e09e1e88 | |||
| 866f464d37 | |||
| da9f3c1e02 | |||
| 9b8fdf289f | |||
| bf12c1664a | |||
| d7836eedd7 | |||
| 4bac816e37 | |||
| 67f9103b96 | |||
| 8ddee66304 | |||
| 4fb6a9999f | |||
| 794dcf83f6 | |||
| 9fe73ed8e4 | |||
| e99b2abd7d | |||
| b128b285ed | |||
| c8bf9640cf | |||
| 2b4523d644 | |||
| 16306f2325 | |||
| d7c3ea7f69 | |||
| 413c3c30a6 | |||
| df6e7e5155 | |||
| 46974ef2eb | |||
| 50ccb2ccc2 | |||
| 9b966a260c | |||
| 49ea56f5e2 | |||
| 300edc90b5 | |||
| 5ff33ca6ca | |||
| 6dc6d8fc24 | |||
| 8d94ed516c | |||
| ba0b0930b0 | |||
| 29e76b1ddd | |||
| 54ceaa3042 | |||
| dcc223d287 | |||
| 7187412a45 | |||
| ff7aef827c | |||
| 6ff7ccf69a | |||
| e347e04d33 | |||
| 7946ea54a6 | |||
| 79033346c0 | |||
| 62b73d6f41 | |||
| 218ddabb5e | |||
| 427f40632a | |||
| a29b4d4379 | |||
| d851cdd2fe | |||
| 3354d00814 | |||
| 7bd7ba84e0 | |||
| 6ad34eaf57 | |||
| b4f2251508 | |||
| 473a52f986 | |||
| bcdd48d622 | |||
| 6985569573 | |||
| 5db43e674d | |||
| 34baa3c97d | |||
| bddb790fe2 | |||
| 6fae12ba02 | |||
| 4e083a8cdb | |||
| cbe4315701 | |||
| 49d561b583 | |||
| 6e56a6fd79 | |||
| 267d9647e0 | |||
| 13b3702d00 | |||
| 4500845dcd | |||
| a4abc02f88 | |||
| a0fb6934b0 | |||
| 19645445b2 | |||
| efe8628a3c | |||
| c98cb0d29f | |||
| c16fc1bae5 | |||
| fa0af1179a | |||
| d1e4a5eb07 | |||
| e18d1b186a | |||
| d056a5e336 | |||
| b9e26aa755 | |||
| b2afef2226 | |||
| c400aa96c0 | |||
| 8818954dcd | |||
| b92e5df98b | |||
| 83871273ec | |||
| 0459b39366 | |||
| 5bb0ff19bc | |||
| a867b3cf4d | |||
| 8a6ce8e66d | |||
| a40f04a739 | |||
| 0c670fd344 | |||
| 35f4bf690c | |||
| abeaf47f96 | |||
| 6498c35628 | |||
| d1c6af02db | |||
| 5edef17d84 | |||
| e4532fcef2 | |||
| 7a8d66c29d | |||
| 54292c9f8f | |||
| 3897553704 | |||
| 308f5c20fb | |||
| 987dcd0205 | |||
| d56f23544c | |||
| c79a846b29 | |||
| ad39d55e79 | |||
| 853ef426f0 | |||
| cadf7de3d8 | |||
| ec65ff9acb | |||
| d077374883 | |||
| 40a2b2cc00 | |||
| b3f3f151da | |||
| 3fdd61655a | |||
| 504727b95f | |||
| ff5446fcdf | |||
| 545eb70082 | |||
| 232a23a5dd | |||
| c9a29e26dd | |||
| 2977869ab5 | |||
| 6a223b68ba | |||
| 3fafff026b | |||
| 159528adc9 | |||
| 6c8f231b34 | |||
| c5d6d77ebf | |||
| 5e73327b2f | |||
| 720d286dcf |
@@ -1,6 +1,7 @@
|
||||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
IndentAccessModifiers: true
|
||||
NamespaceIndentation: All
|
||||
IndentAccessModifiers: false
|
||||
ColumnLimit: 0 # Sin límite de longitud de línea
|
||||
BreakBeforeBraces: Attach # Llaves en la misma línea
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
source/external/**
|
||||
@@ -1,12 +0,0 @@
|
||||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
IndentAccessModifiers: true
|
||||
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: false
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
37
.clang-tidy
@@ -1,28 +1,25 @@
|
||||
Checks: >
|
||||
readability-*,
|
||||
modernize-*,
|
||||
performance-*,
|
||||
bugprone-unchecked-optional-access,
|
||||
bugprone-sizeof-expression,
|
||||
bugprone-suspicious-missing-comma,
|
||||
bugprone-suspicious-index,
|
||||
bugprone-undefined-memory-manipulation,
|
||||
bugprone-use-after-move,
|
||||
bugprone-out-of-bound-access,
|
||||
-readability-identifier-length,
|
||||
-readability-magic-numbers,
|
||||
-bugprone-narrowing-conversions,
|
||||
-performance-enum-size,
|
||||
-performance-inefficient-string-concatenation,
|
||||
-bugprone-integer-division,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
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 incluir archivos de tu código fuente
|
||||
HeaderFilterRegex: '^source/(sections|ui)/.*'
|
||||
# Solo incluir archivos de tu código fuente (external tiene su propio .clang-tidy)
|
||||
# Excluye los headers SPIR-V generados en rendering/sdl3gpu/
|
||||
HeaderFilterRegex: 'source/(?!external/|rendering/sdl3gpu/.*_spv\.h).*'
|
||||
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 }
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
Checks: >
|
||||
readability-identifier-naming,
|
||||
readability-*,
|
||||
modernize-*,
|
||||
clang-analyzer-*,
|
||||
-readability-identifier-length,
|
||||
-readability-magic-numbers
|
||||
|
||||
WarningsAsErrors: '*'
|
||||
|
||||
HeaderFilterRegex: '.*'
|
||||
FormatStyle: file
|
||||
|
||||
CheckOptions:
|
||||
# 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 }
|
||||
|
||||
# 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 }
|
||||
|
||||
# Constantes estáticas dentro de clases en UPPER_CASE (sin sufijo)
|
||||
- { key: readability-identifier-naming.StaticConstantCase, 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 }
|
||||
12
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
.vscode
|
||||
.claude
|
||||
.claude/
|
||||
.cache/
|
||||
build/
|
||||
data/config/config.txt
|
||||
*.DS_Store
|
||||
@@ -17,4 +17,10 @@ coffee_crisis*
|
||||
debug.txt
|
||||
cppcheck-result*
|
||||
desktop.ini
|
||||
ccae_release/
|
||||
dist/
|
||||
release/windows/coffee.res
|
||||
resources.pack
|
||||
|
||||
# Herramienta pack_resources (todas las plataformas)
|
||||
tools/pack_resources/pack_resources
|
||||
tools/pack_resources/pack_resources.exe
|
||||
|
||||
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build/compile_commands.json"
|
||||
}
|
||||
200
CHANGELOG.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# CHANGELOG
|
||||
|
||||
Historial de canvis i novetats de Coffee Crisis Arcade Edition.
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-03
|
||||
|
||||
- **Nova intro cinematogràfica**: les tarjetes s'llancen des dels costats de la pantalla amb zoom, rotació i rebot, simulant tirar cartes sobre una mesa. Les anteriors ixen despedides girant quan arriba la següent. Sombra amb efecte de perspectiva 2D→3D.
|
||||
- **Efectes sonors i visuals en la intro**: shake de pantalla i sons configurables a cada impacte de tarjeta.
|
||||
- **Migració a SDL3 GPU API**: postfx i crtpi migrats a SDL3GPU (Vulkan/Metal/D3D12).
|
||||
- **Migració de configuració a YAML**: eliminat el format antic, ara tot en YAML.
|
||||
- **Afegides opcions al Service Menu**.
|
||||
- **HUD de FPS retocat**, presets per defecte ajustats, finestra a 2x i shader off per defecte.
|
||||
- **Corregit bug d'input**: revertit un canvi que causava bucle infinit en F3 (pantalla completa) i F12 (service menu) en totes les escenes excepte Game.
|
||||
- Neteja de codi: eliminades referencies a OpenGL, fitxers GLSL sobrants, normalitzada la carpeta release i el caption de la finestra.
|
||||
|
||||
---
|
||||
|
||||
## 2025-10-25
|
||||
|
||||
- **Migració a delta_time pur** en credits, instructions i hiscore_table. Eliminat un bug que feia que els credits no acabaren mai si no passaves a mà.
|
||||
- **Corregida deformació subpixel** de textures en instructions i hiscore_table.
|
||||
- **Detecció de fitxers de puntuació corruptes**.
|
||||
- **Efecte de pulsos** afegit al scoreboard.
|
||||
- Al posar nom, el carrusel apareix directament en el caràcter d'acabar si ja havies posat nom abans.
|
||||
- Integrat jail_audio en la càrrega de resources.pack.
|
||||
- Pasaeta de linter en múltiples fitxers.
|
||||
- Nou icon per al joc.
|
||||
- Corregida la versió release de macOS per a funcionar correctament amb resources.pack.
|
||||
|
||||
---
|
||||
|
||||
## 2025-08-21
|
||||
|
||||
- **Integració amb resources.pack**: textures, animacions, textos, dades de la demo i jail_audio integrats amb ResourceHelper.
|
||||
- Actualitzat Makefile per a Windows, Linux i macOS.
|
||||
- Neteja de temporals al acabar.
|
||||
|
||||
---
|
||||
|
||||
## 2025-08-17
|
||||
|
||||
- **Afegit fade RANDOM_SQUARE2** amb timings canviats a mil·lisegons.
|
||||
- **Outline parametritzat** per als textos dels items.
|
||||
- **Colors de camiseta parametritzats** per defecte i quan pillen café.
|
||||
- Creat `defaults.h` amb els valors per defecte de Param.
|
||||
- Afegit `param_red.txt` amb guardes en setParams.
|
||||
- Fix: items que es quedaven engantxats a la part de dalt.
|
||||
- Fix: en el modo demo, assignava cafés al jugador que no jugava.
|
||||
- Fix: bug en l'estat pre del fade.
|
||||
- Fix: globos apareixien un frame mal situats al crear-se des d'un pare.
|
||||
- Afegit suport per a mapejar botons tipus trigger.
|
||||
|
||||
---
|
||||
|
||||
## 2025-08-10
|
||||
|
||||
- **Service Menu complet**: animació d'apertura/tancament, callback per a posar pausa en el joc, refresc visual al canviar mandos.
|
||||
- **Mandos en calent**: es poden connectar i desconnectar mandos durant el joc, amb notificació visual.
|
||||
- **PauseManager** afegit al joc.
|
||||
- **Càrrega de recursos on_demand**.
|
||||
- Afegit `shutdown.h` i `system_utils.h`.
|
||||
- Fix: el nom apareixia duplicat en la tabla de records.
|
||||
- Fix: Game no es desregistrava de ServiceMenu al destruir-se.
|
||||
- Precàrrega de textures del jugador amb variants de paleta.
|
||||
- Actualitzats frameworks per a macOS.
|
||||
|
||||
---
|
||||
|
||||
## 2025-03-25
|
||||
|
||||
- **Nova secció Intro** amb escenes seqüencials, animacions de tarjetes i text narratiu.
|
||||
- **Shaders respecten l'escalat sencer** i SDL_RenderSetLogicalSize en pantalla completa.
|
||||
- **Tecla per canviar l'integer scale** (F-key).
|
||||
- Afegit intro03.png i intro04.png.
|
||||
- Renomenat InputType a InputActions.
|
||||
- Actualitzat gamecontrollerdb.txt amb mappings de la recreativa.
|
||||
- Fix: al fer reset des de Game, en Intro no sonava la música.
|
||||
- Fix: al acabar la partida i vore els records, torna al títol.
|
||||
- Fix: amb l'àudio mutat, el fade per al soroll de boles el tornava a deixar activat.
|
||||
|
||||
---
|
||||
|
||||
## 2025-02-07
|
||||
|
||||
- **EnterName millorat**: si has omplit tots els slots, apretar una volta mes fixa el nom.
|
||||
- **Control de repetició per als eixos del joystick**.
|
||||
- **La tabla de puntuació** mostra amb altre color la puntuació acabada d'afegir i les aconseguides amb 1CC.
|
||||
- Nova font per a la intro.
|
||||
- Afegit efecte d'eixida a les instruccions.
|
||||
- Afegit disparador per a l'aparició de l'enemic nou.
|
||||
- Duplicada la font 04b_25 per a versió gris i versió negra.
|
||||
|
||||
---
|
||||
|
||||
## 2025-01-05
|
||||
|
||||
- **Optimitzat el circuit de render** en pantalla.
|
||||
- **Atenuat de pantalla restaurat**: Fade feia dos SDL_SetRenderDrawBlendMode sense restaurar.
|
||||
- Fix: es podia polsar per a jugar mentre feia el fade cap a la demo.
|
||||
- Fix: error en la seqüència final de retrocedir en el temps.
|
||||
- Calibrats els polsos al gust.
|
||||
- Afegida una lluna i un sol al fondo.
|
||||
- La powerball ja no es pot destruir fins que no ha fet un rebot.
|
||||
- Modificada la cadència de foc sense autofire.
|
||||
- Afegit botó per a activar o desactivar el ratolí.
|
||||
|
||||
---
|
||||
|
||||
## 2024-12-31
|
||||
|
||||
- **Enemic nou** complet: gràfics, comportament, àudio i veus.
|
||||
- **Fade out sincronitzat** de vídeo i àudio en el títol i el joc.
|
||||
- **Roidets de col·lisió** per als globos en certs moments.
|
||||
- La finestra ja es pot fer tan gran com permeta la pantalla (zoom dinàmic).
|
||||
- Afegides veus al jugador i efectes de so al rebotar quan mor.
|
||||
- Afegit delay opcional al flash de Screen.
|
||||
- Afegit botó per activar o desactivar l'autofire.
|
||||
- Fix: mode demo desactivava els sons permanentment.
|
||||
- Actualitzat jail_audio.
|
||||
|
||||
---
|
||||
|
||||
## 2024-12-05
|
||||
|
||||
- **Secció Credits acabada** a 320x240 (i per extensió, a qualsevol resolució).
|
||||
- **Zoom afegit a la classe Sprite** i al subtítol ARCADE EDITION.
|
||||
- Duplicats fitxers de shaders per a resolucions verticals de 256 i 240.
|
||||
- Afegit globalInputs::update() a totes les seccions.
|
||||
- Fix: faltava corregir el flash de destroyAllBalloons().
|
||||
- Fix: si saltes el logo, talla el so a meitat sonar.
|
||||
- Canvi d'idioma amb una tecla (i reinicia).
|
||||
|
||||
---
|
||||
|
||||
## 2024-11-27
|
||||
|
||||
- **Secció Credits**: disseny, música, globos amb play_area definida, opció de canviar la paleta al text.
|
||||
- Afegides traduccions dels credits.
|
||||
|
||||
---
|
||||
|
||||
## 2024-11-20
|
||||
|
||||
- **Nova animació de mort del personatge**: rebots, llengua fora, ulls en X, gràfics de caure derrotat per al segon jugador.
|
||||
- **Powerball redissenyada**: nous gràfics, nou comportament, ja no mata directament.
|
||||
- **Globos fills** ja no ixen centrats al pare (evita apilar-se).
|
||||
- Arreglos en el nom al obtindre la màxima puntuació.
|
||||
- Acabat BalloonManager.
|
||||
- CMakeLists.txt crea l'executable en l'arrel del projecte.
|
||||
- Nova font de text gran amb el doble de definició.
|
||||
- Fix: paleta verda del primer jugador ajustada a l'original.
|
||||
|
||||
---
|
||||
|
||||
## 2024-11-03
|
||||
|
||||
- **Teclat com a control independent**: ja pot jugar un jugador amb teclat i altre amb mando, o assignar el teclat a qualsevol jugador.
|
||||
- **Implementat el final del joc** i l'Attract Mode.
|
||||
- **Nou motor per a textos en pantalla** (game_text amb textures precarregades).
|
||||
- **Noves animacions** per a deixar de disparar.
|
||||
- Al redefinir botons, ja no pots repetir botó.
|
||||
- Fix: l'animació de morir s'actualitzava dos voltes per frame.
|
||||
- Fix: l'efecte de flash tenia un valor massa xicotet.
|
||||
|
||||
---
|
||||
|
||||
## 2024-10-28
|
||||
|
||||
- **Classe PathSprite completada**: el game_text gasta PathSprites en lloc de SmartSprites.
|
||||
- **Time stopper redissenyat**.
|
||||
- La partida sempre comença igual (createTwoBigBalloons).
|
||||
- Revisades les classes Balloon i Bullet.
|
||||
- Millorada l'aparició dels game_text.
|
||||
- Fix: la paleta dels jugadors no s'iniciava correctament.
|
||||
|
||||
---
|
||||
|
||||
## 2024-10-20
|
||||
|
||||
- **Classe Resource creada**: precàrrega de tots els recursos (textures, música, sons, animacions).
|
||||
- **Paletes de color** per a textures GIF amb shared_ptr.
|
||||
- Precàrrega i assignació de paletes.
|
||||
- Implementat comptador per a posar el nom al acabar la partida.
|
||||
- Classe Notifier independitzada de Screen amb codis identificadors.
|
||||
- Afegit codi per a apagar el sistema al eixir del joc.
|
||||
- Fix: globos verds tenien setters mal assignats i velocitat incorrecta.
|
||||
- Fix: no guardar el fitxer de puntuacions en el mode demo.
|
||||
|
||||
---
|
||||
|
||||
## 2024-10-14
|
||||
|
||||
- **Versió inicial**: clon del repositori de Coffee Crisis, adaptat per a Arcade Edition.
|
||||
- Pasaeta de include-what-you-use i cppcheck.
|
||||
- Estandarització de noms segons convencions (CamelCase, camelBack, snake_case).
|
||||
- Herències de les classes Sprite corregides.
|
||||
- Canvi a C++ modern amb smart pointers per a la càrrega de surfaces des de GIF.
|
||||
- Eliminats últims defines i passats a enum class.
|
||||
117
CLAUDE.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Coffee Crisis Arcade Edition is a 2-player cooperative arcade shooter built with C++20 and SDL3. Players defend coffee against giant balloons. The game targets Windows, Linux, macOS (Intel/Apple Silicon), Raspberry Pi, and Anbernic handhelds.
|
||||
|
||||
## Build Commands
|
||||
|
||||
The project uses both CMake and a top-level Makefile. The Makefile is the primary build interface.
|
||||
|
||||
### CMake (generates compile_commands.json for IDE/linter support)
|
||||
```bash
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Debug # configure
|
||||
cmake --build build # build
|
||||
```
|
||||
|
||||
### Makefile (delegates to CMake)
|
||||
```bash
|
||||
make # build Release via cmake
|
||||
make debug # build Debug via cmake
|
||||
make release # create release package (auto-detects OS)
|
||||
make linux_release # release tar.gz with resources.pack
|
||||
make windows_release # release zip for Windows
|
||||
make macos_release # release dmg for macOS (Intel + Apple Silicon)
|
||||
make raspi_release # release tar.gz for Raspberry Pi
|
||||
```
|
||||
|
||||
### Tools & Resources
|
||||
```bash
|
||||
make pack_tool # compile resource packer
|
||||
make resources.pack # pack data/ into resources.pack (required for release builds)
|
||||
make spirv # compile GLSL shaders to SPIR-V headers
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
```bash
|
||||
make format # run clang-format on all sources (or: cmake --build build --target format)
|
||||
make format-check # check formatting without modifying
|
||||
make tidy # run clang-tidy static analysis (cmake --build build --target tidy)
|
||||
make tidy-fix # run clang-tidy with auto-fix
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Source layout
|
||||
The `source/` tree is organised in the same style as the sibling projects `projecte_2026` and `jaildoctors_dilemma`:
|
||||
|
||||
```
|
||||
source/
|
||||
├── core/ # engine: audio, input, locale, rendering (+ sdl3gpu, sprite), resources, system
|
||||
├── game/ # gameplay: entities, gameplay, scenes, ui, options
|
||||
├── utils/ # color, param, utils
|
||||
├── external/ # vendored third-party headers (json, fkyaml, stb_*)
|
||||
└── main.cpp
|
||||
```
|
||||
|
||||
`#include` paths are absolute relative to `source/` (e.g. `#include "core/audio/audio.hpp"`, `#include "game/scenes/logo.hpp"`). The CMake build adds a single `-I${CMAKE_SOURCE_DIR}/source`.
|
||||
|
||||
### Singletons (core systems)
|
||||
- **Director** (`source/core/system/director.hpp`) — Application state machine, orchestrates scene transitions (Logo → Intro → Title → Game → Credits/HiScore → Title)
|
||||
- **Screen** (`source/core/rendering/screen.hpp`) — Window management, SDL3 GPU rendering pipeline, post-processing effects
|
||||
- **Resource** (`source/core/resources/resource.hpp`) — Asset loading/caching with PRELOAD and LAZY_LOAD modes, reads from `resources.pack`
|
||||
- **Audio** (`source/core/audio/audio.hpp`) — Music and SFX management
|
||||
- **Input** (`source/core/input/input.hpp`) — Keyboard and gamepad input handling
|
||||
|
||||
### Scenes (source/game/scenes/)
|
||||
Each scene is a self-contained class with update/render lifecycle. Scene flow is managed by Director.
|
||||
|
||||
### Entity Managers
|
||||
- `BalloonManager` / `BulletManager` — Object pool-based entity management (`source/game/gameplay/`)
|
||||
- `Player` — Two-player support (player 1: keyboard, player 2: gamepad) (`source/game/entities/`)
|
||||
|
||||
### Rendering Pipeline
|
||||
- SDL3 GPU API (Vulkan/Metal/D3D12 backends)
|
||||
- SPIR-V shaders compiled offline from GLSL (`data/shaders/`) via `glslc`
|
||||
- Compiled shader headers embedded in `source/core/rendering/sdl3gpu/postfx_*_spv.h`
|
||||
- macOS uses Metal (no SPIR-V compilation needed)
|
||||
|
||||
### Configuration
|
||||
- Game parameters: `config/param_320x240.txt`, `config/param_320x256.txt`
|
||||
- Asset manifest: `config/assets.txt`
|
||||
- Balloon formations: `config/formations.txt`
|
||||
- Level definitions: `config/stages.txt`
|
||||
- Gamepad mappings: `config/gamecontrollerdb.txt`
|
||||
|
||||
### External Libraries (header-only/vendored in source/external/)
|
||||
- nlohmann/json, fkyaml (YAML), stb_image, stb_vorbis
|
||||
|
||||
`jail_audio` lives in `source/core/audio/` and `gif.{hpp,cpp}` in `source/core/rendering/` — these are first-party, not third-party.
|
||||
|
||||
## Code Style
|
||||
|
||||
Enforced via `.clang-format` (Google-based) and `.clang-tidy`:
|
||||
|
||||
- **Naming conventions**: Classes/structs `CamelCase`, methods/functions `camelBack`, variables/params `snake_case`, private/protected members `snake_case_` (trailing underscore), constants/constexpr `UPPER_CASE`, namespaces `CamelCase`, enum values `UPPER_CASE`
|
||||
- 4-space indentation, no column limit, braces attach to statement
|
||||
- clang-tidy treats all warnings as errors
|
||||
|
||||
## Conditional Compilation Defines
|
||||
|
||||
| Define | Purpose |
|
||||
|--------|---------|
|
||||
| `WINDOWS_BUILD` / `LINUX_BUILD` / `MACOS_BUILD` | Platform selection |
|
||||
| `DEBUG` / `VERBOSE` | Debug output |
|
||||
| `RELEASE_BUILD` | Release-specific code paths |
|
||||
| `RECORDING` | Demo recording mode |
|
||||
| `NO_SHADERS` | Disable shader pipeline (Anbernic) |
|
||||
| `NO_AUDIO` | Build without audio |
|
||||
| `ARCADE` | Arcade-specific mode |
|
||||
| `MACOS_BUNDLE` | macOS .app bundle paths |
|
||||
| `ANBERNIC` | Anbernic handheld build |
|
||||
|
||||
## Language
|
||||
|
||||
Code comments are in Spanish/Catalan. Game UI supports multiple languages via JSON files in `data/lang/`.
|
||||
446
CMakeLists.txt
@@ -6,114 +6,233 @@ project(coffee_crisis_arcade_edition VERSION 2.00)
|
||||
# Establecer estándar de C++
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Establece la política CMP0072 para indicar cómo se debe seleccionar la implementación de OpenGL.
|
||||
# En este caso, se elige la opción "GLVND", que utiliza bibliotecas modernas y modulares (libOpenGL, libGLX),
|
||||
# en lugar de la biblioteca OpenGL clásica (libGL). Esto mejora la compatibilidad con drivers recientes
|
||||
# y evita ambigüedades cuando se encuentran múltiples implementaciones de OpenGL en el sistema.
|
||||
cmake_policy(SET CMP0072 NEW)
|
||||
set(OpenGL_GL_PREFERENCE GLVND)
|
||||
|
||||
# --- GENERACIÓN DE VERSIÓN AUTOMÁTICA ---
|
||||
# Si GIT_HASH se ha pasado desde fuera (p.ej. desde el Makefile via -DGIT_HASH=xxx),
|
||||
# lo usamos tal cual. Esto evita problemas con Docker/emscripten, donde git aborta por
|
||||
# "dubious ownership" en el volumen montado. En builds locales sin -DGIT_HASH, se
|
||||
# resuelve aquí ejecutando git directamente.
|
||||
if(NOT DEFINED GIT_HASH OR GIT_HASH STREQUAL "")
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
)
|
||||
endif()
|
||||
if(NOT DEFINED GIT_HASH OR GIT_HASH STREQUAL "")
|
||||
set(GIT_HASH "unknown")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Configurar archivo de versión
|
||||
configure_file(${CMAKE_SOURCE_DIR}/source/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
|
||||
|
||||
# --- 1. LISTA EXPLÍCITA DE FUENTES ---
|
||||
set(APP_SOURCES
|
||||
# --- Archivos Principales del Sistema ---
|
||||
source/asset.cpp
|
||||
source/audio.cpp
|
||||
source/director.cpp
|
||||
source/global_events.cpp
|
||||
source/global_inputs.cpp
|
||||
source/input.cpp
|
||||
source/lang.cpp
|
||||
source/main.cpp
|
||||
source/param.cpp
|
||||
source/resource.cpp
|
||||
source/resource_helper.cpp
|
||||
source/resource_loader.cpp
|
||||
source/resource_pack.cpp
|
||||
source/screen.cpp
|
||||
source/text.cpp
|
||||
source/writer.cpp
|
||||
|
||||
# --- UI (User Interface) ---
|
||||
source/ui/menu_option.cpp
|
||||
source/ui/menu_renderer.cpp
|
||||
source/ui/notifier.cpp
|
||||
source/ui/service_menu.cpp
|
||||
source/ui/ui_message.cpp
|
||||
source/ui/window_message.cpp
|
||||
# --- core/audio ---
|
||||
source/core/audio/audio.cpp
|
||||
|
||||
# --- Lógica del Juego ---
|
||||
source/balloon_formations.cpp
|
||||
source/balloon_manager.cpp
|
||||
source/balloon.cpp
|
||||
source/bullet.cpp
|
||||
source/enter_name.cpp
|
||||
source/explosions.cpp
|
||||
source/game_logo.cpp
|
||||
source/item.cpp
|
||||
source/manage_hiscore_table.cpp
|
||||
source/player.cpp
|
||||
source/scoreboard.cpp
|
||||
source/tabe.cpp
|
||||
# --- core/input ---
|
||||
source/core/input/define_buttons.cpp
|
||||
source/core/input/global_inputs.cpp
|
||||
source/core/input/input.cpp
|
||||
source/core/input/input_types.cpp
|
||||
source/core/input/mouse.cpp
|
||||
|
||||
# --- Escenas ---
|
||||
source/sections/credits.cpp
|
||||
source/sections/game.cpp
|
||||
source/sections/hiscore_table.cpp
|
||||
source/sections/instructions.cpp
|
||||
source/sections/intro.cpp
|
||||
source/sections/logo.cpp
|
||||
source/sections/title.cpp
|
||||
# --- core/locale ---
|
||||
source/core/locale/lang.cpp
|
||||
|
||||
# --- Sprites y Gráficos ---
|
||||
source/animated_sprite.cpp
|
||||
source/background.cpp
|
||||
source/fade.cpp
|
||||
source/moving_sprite.cpp
|
||||
source/path_sprite.cpp
|
||||
source/smart_sprite.cpp
|
||||
source/sprite.cpp
|
||||
source/texture.cpp
|
||||
source/tiled_bg.cpp
|
||||
# --- core/rendering ---
|
||||
source/core/rendering/background.cpp
|
||||
source/core/rendering/fade.cpp
|
||||
source/core/rendering/gif.cpp
|
||||
source/core/rendering/screen.cpp
|
||||
source/core/rendering/text.cpp
|
||||
source/core/rendering/texture.cpp
|
||||
source/core/rendering/tiled_bg.cpp
|
||||
source/core/rendering/writer.cpp
|
||||
source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp
|
||||
source/core/rendering/sprite/animated_sprite.cpp
|
||||
source/core/rendering/sprite/card_sprite.cpp
|
||||
source/core/rendering/sprite/moving_sprite.cpp
|
||||
source/core/rendering/sprite/path_sprite.cpp
|
||||
source/core/rendering/sprite/smart_sprite.cpp
|
||||
source/core/rendering/sprite/sprite.cpp
|
||||
|
||||
# --- Otros ---
|
||||
source/color.cpp
|
||||
source/define_buttons.cpp
|
||||
source/difficulty.cpp
|
||||
source/input_types.cpp
|
||||
source/mouse.cpp
|
||||
source/options.cpp
|
||||
source/shutdown.cpp
|
||||
source/stage.cpp
|
||||
source/system_utils.cpp
|
||||
source/utils.cpp
|
||||
# --- core/resources ---
|
||||
source/core/resources/asset.cpp
|
||||
source/core/resources/asset_integrated.cpp
|
||||
source/core/resources/resource.cpp
|
||||
source/core/resources/resource_helper.cpp
|
||||
source/core/resources/resource_loader.cpp
|
||||
source/core/resources/resource_pack.cpp
|
||||
|
||||
# --- core/system ---
|
||||
source/core/system/demo.cpp
|
||||
source/core/system/director.cpp
|
||||
source/core/system/global_events.cpp
|
||||
source/core/system/shutdown.cpp
|
||||
source/core/system/system_utils.cpp
|
||||
|
||||
# --- game ---
|
||||
source/game/options.cpp
|
||||
|
||||
# --- game/entities ---
|
||||
source/game/entities/balloon.cpp
|
||||
source/game/entities/bullet.cpp
|
||||
source/game/entities/explosions.cpp
|
||||
source/game/entities/item.cpp
|
||||
source/game/entities/player.cpp
|
||||
source/game/entities/tabe.cpp
|
||||
|
||||
# --- game/gameplay ---
|
||||
source/game/gameplay/balloon_formations.cpp
|
||||
source/game/gameplay/balloon_manager.cpp
|
||||
source/game/gameplay/bullet_manager.cpp
|
||||
source/game/gameplay/difficulty.cpp
|
||||
source/game/gameplay/enter_name.cpp
|
||||
source/game/gameplay/game_logo.cpp
|
||||
source/game/gameplay/manage_hiscore_table.cpp
|
||||
source/game/gameplay/scoreboard.cpp
|
||||
source/game/gameplay/stage.cpp
|
||||
|
||||
# --- game/scenes ---
|
||||
source/game/scenes/credits.cpp
|
||||
source/game/scenes/game.cpp
|
||||
source/game/scenes/hiscore_table.cpp
|
||||
source/game/scenes/instructions.cpp
|
||||
source/game/scenes/intro.cpp
|
||||
source/game/scenes/logo.cpp
|
||||
source/game/scenes/preload.cpp
|
||||
source/game/scenes/title.cpp
|
||||
|
||||
# --- game/ui ---
|
||||
source/game/ui/menu_option.cpp
|
||||
source/game/ui/menu_renderer.cpp
|
||||
source/game/ui/notifier.cpp
|
||||
source/game/ui/service_menu.cpp
|
||||
source/game/ui/ui_message.cpp
|
||||
source/game/ui/window_message.cpp
|
||||
|
||||
# --- utils ---
|
||||
source/utils/color.cpp
|
||||
source/utils/param.cpp
|
||||
source/utils/utils.cpp
|
||||
)
|
||||
|
||||
# Fuentes de librerías de terceros
|
||||
set(EXTERNAL_SOURCES
|
||||
source/external/jail_shader.cpp
|
||||
source/external/json.hpp
|
||||
source/external/gif.cpp
|
||||
)
|
||||
|
||||
# Añadir jail_audio.cpp solo si el audio está habilitado
|
||||
if(NOT DISABLE_AUDIO)
|
||||
list(APPEND EXTERNAL_SOURCES source/external/jail_audio.cpp)
|
||||
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.2.12
|
||||
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/postfx_vert_spv.h")
|
||||
set(SHADER_FRAG_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/postfx_frag_spv.h")
|
||||
set(SHADER_CRTPI_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/crtpi_frag_spv.h")
|
||||
set(SHADER_UPSCALE_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/upscale_frag_spv.h")
|
||||
set(SHADER_DOWNSCALE_H "${CMAKE_SOURCE_DIR}/source/core/rendering/sdl3gpu/downscale_frag_spv.h")
|
||||
|
||||
set(ALL_SHADER_SOURCES "${SHADER_VERT_SRC}" "${SHADER_FRAG_SRC}" "${SHADER_CRTPI_SRC}" "${SHADER_UPSCALE_SRC}" "${SHADER_DOWNSCALE_SRC}")
|
||||
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)\n"
|
||||
" O genera los headers manualmente: tools/shaders/compile_spirv.sh"
|
||||
)
|
||||
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)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- 2. AÑADIR EJECUTABLE ---
|
||||
add_executable(${PROJECT_NAME} ${APP_SOURCES} ${EXTERNAL_SOURCES})
|
||||
if(EMSCRIPTEN)
|
||||
# En Emscripten no compilamos sdl3gpu_shader (SDL3 GPU no está soportado en WebGL2)
|
||||
set(APP_SOURCES_WASM ${APP_SOURCES})
|
||||
list(REMOVE_ITEM APP_SOURCES_WASM source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp)
|
||||
add_executable(${PROJECT_NAME} ${APP_SOURCES_WASM})
|
||||
else()
|
||||
add_executable(${PROJECT_NAME} ${APP_SOURCES})
|
||||
endif()
|
||||
|
||||
if(NOT APPLE AND NOT EMSCRIPTEN AND GLSLC_EXE)
|
||||
add_dependencies(${PROJECT_NAME} shaders)
|
||||
endif()
|
||||
|
||||
# --- 3. DIRECTORIOS DE INCLUSIÓN ---
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/source"
|
||||
"${CMAKE_SOURCE_DIR}/source/external"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
)
|
||||
|
||||
# Enlazar la librería SDL3
|
||||
@@ -128,39 +247,152 @@ target_compile_options(${PROJECT_NAME} PRIVATE $<$<CONFIG:RELEASE>:-Os -ffunctio
|
||||
# Definir _DEBUG en modo Debug
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:DEBUG>:_DEBUG>)
|
||||
|
||||
# Opción para habilitar/deshabilitar audio
|
||||
option(DISABLE_AUDIO "Disable audio system" OFF)
|
||||
# Descomentar la siguiente línea para activar el modo grabación de demos
|
||||
# target_compile_definitions(${PROJECT_NAME} PRIVATE RECORDING)
|
||||
|
||||
# Definir NO_AUDIO si la opción está activada
|
||||
if(DISABLE_AUDIO)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE NO_AUDIO)
|
||||
message(STATUS "Audio deshabilitado - NO_AUDIO definido")
|
||||
else()
|
||||
message(STATUS "Audio habilitado")
|
||||
endif()
|
||||
|
||||
# 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 opengl32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32 mingw32)
|
||||
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)
|
||||
# -fexceptions: habilita excepciones C++ (fkyaml, std::runtime_error...) — sin esto cualquier throw llama a abort()
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -fexceptions)
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/data@/data"
|
||||
"SHELL:--preload-file ${CMAKE_SOURCE_DIR}/config@/config"
|
||||
-fexceptions
|
||||
-sALLOW_MEMORY_GROWTH=1
|
||||
-sMAX_WEBGL_VERSION=2
|
||||
-sINITIAL_MEMORY=67108864
|
||||
-sASSERTIONS=1
|
||||
# ASYNCIFY solo para permitir emscripten_sleep(0) durante la precarga de recursos
|
||||
# (el bucle principal del juego ya usa SDL3 Callback API, no depende de ASYNCIFY).
|
||||
-sASYNCIFY=1
|
||||
)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
||||
endif()
|
||||
|
||||
# Configuración común para OpenGL
|
||||
if(NOT WIN32)
|
||||
find_package(OpenGL REQUIRED)
|
||||
if(OPENGL_FOUND)
|
||||
message(STATUS "OpenGL encontrado: ${OPENGL_LIBRARIES}")
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENGL_LIBRARIES})
|
||||
# Especificar la ubicación del ejecutable
|
||||
if(EMSCRIPTEN)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
else()
|
||||
message(FATAL_ERROR "OpenGL no encontrado")
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
# Especificar la ubicación del ejecutable
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
# --- 5. 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, excluyendo external/
|
||||
file(GLOB_RECURSE ALL_SOURCE_FILES
|
||||
"${CMAKE_SOURCE_DIR}/source/*.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/source/*.hpp"
|
||||
"${CMAKE_SOURCE_DIR}/source/*.h"
|
||||
)
|
||||
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX ".*/external/.*")
|
||||
|
||||
# Para cppcheck, pasar solo .cpp (los headers se procesan transitivamente).
|
||||
# Si pasamos .hpp como TUs independientes, cppcheck reporta falsos positivos de
|
||||
# 'unusedStructMember' porque no hace análisis cross-TU y ve miembros de clase
|
||||
# cuyo uso vive en un .cpp distinto.
|
||||
set(CPPCHECK_SOURCES ${ALL_SOURCE_FILES})
|
||||
list(FILTER CPPCHECK_SOURCES INCLUDE REGEX ".*\\.cpp$")
|
||||
list(FILTER CPPCHECK_SOURCES EXCLUDE REGEX ".*_spv\\.h$")
|
||||
|
||||
# Targets de clang-tidy
|
||||
if(CLANG_TIDY_EXE)
|
||||
# En macOS con clang-tidy de Homebrew LLVM, es necesario pasar el sysroot
|
||||
# explícitamente para que encuentre los headers del sistema (string, memory, etc.)
|
||||
if(APPLE)
|
||||
execute_process(
|
||||
COMMAND xcrun --show-sdk-path
|
||||
OUTPUT_VARIABLE MACOS_SDK_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
set(TIDY_EXTRA_ARGS --extra-arg=-isysroot --extra-arg=${MACOS_SDK_PATH})
|
||||
endif()
|
||||
|
||||
add_custom_target(tidy
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
-p ${CMAKE_BINARY_DIR}
|
||||
${TIDY_EXTRA_ARGS}
|
||||
${ALL_SOURCE_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Running clang-tidy..."
|
||||
)
|
||||
|
||||
add_custom_target(tidy-fix
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
-p ${CMAKE_BINARY_DIR}
|
||||
--fix
|
||||
${TIDY_EXTRA_ARGS}
|
||||
${ALL_SOURCE_FILES}
|
||||
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
|
||||
${ALL_SOURCE_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Running clang-format..."
|
||||
)
|
||||
|
||||
add_custom_target(format-check
|
||||
COMMAND ${CLANG_FORMAT_EXE}
|
||||
--dry-run
|
||||
--Werror
|
||||
${ALL_SOURCE_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Checking clang-format..."
|
||||
)
|
||||
else()
|
||||
message(STATUS "clang-format no encontrado - targets 'format' y 'format-check' no disponibles")
|
||||
endif()
|
||||
|
||||
# Targets 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
|
||||
-D_DEBUG
|
||||
-DLINUX_BUILD
|
||||
--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()
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
# Plan de Migración DeltaTime - Eliminación de frameFactor
|
||||
|
||||
## Problema Identificado
|
||||
Se están usando `frameFactor` conversions en 7 archivos, lo que indica una migración incompleta a deltaTime.
|
||||
El patrón `float frameFactor = deltaTime / (1000.0f / 60.0f)` simula frames de 60fps en lugar de usar tiempo real.
|
||||
|
||||
## Archivos Afectados y Estado
|
||||
1. **balloon.cpp** - 9 ocurrencias en métodos: moveX(), moveY(), updateState(), updateCreation()
|
||||
2. **balloon_manager.cpp** - 2 ocurrencias en updateBalloonDeployment()
|
||||
3. **bullet.cpp** - 3 ocurrencias en move()
|
||||
4. **item.cpp** - 6 ocurrencias en move()
|
||||
5. **moving_sprite.cpp** - 5 ocurrencias en move()
|
||||
6. **tabe.cpp** - 5 ocurrencias en update() y updateHitEffect()
|
||||
7. **credits.cpp** - 3 ocurrencias en update() y handleFadeOut()
|
||||
|
||||
## Estrategia de Migración
|
||||
|
||||
### Opción A: Velocidades ya en pixels/segundo
|
||||
Si las velocidades están definidas en pixels/segundo:
|
||||
```cpp
|
||||
// ANTES (incorrecto)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
pos_x_ += vel_x_ * frameFactor;
|
||||
|
||||
// DESPUÉS (correcto)
|
||||
pos_x_ += vel_x_ * (deltaTime / 1000.0f); // deltaTime en ms -> segundos
|
||||
```
|
||||
|
||||
### Opción B: Velocidades en pixels/frame (legacy)
|
||||
Si las velocidades están en pixels/frame (sistema legacy):
|
||||
```cpp
|
||||
// ANTES (incorrecto con deltaTime)
|
||||
float frameFactor = deltaTime / (1000.0f / 60.0f);
|
||||
pos_x_ += vel_x_ * frameFactor;
|
||||
|
||||
// OPCIÓN 1: Convertir velocidades a pixels/segundo
|
||||
static constexpr float VEL_X_PER_SECOND = VEL_X_PER_FRAME * 60.0f;
|
||||
pos_x_ += VEL_X_PER_SECOND * (deltaTime / 1000.0f);
|
||||
|
||||
// OPCIÓN 2: Mantener frame-factor pero mejorar claridad
|
||||
pos_x_ += vel_x_ * (deltaTime / FRAME_TIME_MS); // donde FRAME_TIME_MS = 16.67f
|
||||
```
|
||||
|
||||
## Plan de Ejecución
|
||||
|
||||
### Fase 1: Análisis de Velocidades
|
||||
- [ ] Revisar definiciones de velocidades en cada clase
|
||||
- [ ] Determinar si están en pixels/frame o pixels/segundo
|
||||
- [ ] Identificar constantes que necesitan conversión
|
||||
|
||||
### Fase 2: Migración por Archivo
|
||||
- [x] **balloon.cpp**: Migrar velocidades x/y y contadores ✅
|
||||
- [x] **balloon_manager.cpp**: Migrar balloon_deploy_counter_ ✅
|
||||
- [x] **bullet.cpp**: Migrar velocidades de bala ✅ (VEL_Y: -3.0F→-0.18F, VEL_X: ±2.0F→±0.12F)
|
||||
- [x] **item.cpp**: Migrar física de ítems ✅ (vel_x: ±1.0F→±0.06F, vel_y: -4.0F→-0.24F, accel_y: 0.2F→0.012F)
|
||||
- [ ] **moving_sprite.cpp**: Migrar sistema base de movimiento
|
||||
- [ ] **tabe.cpp**: Migrar movimiento y efectos
|
||||
- [ ] **credits.cpp**: Migrar contadores de timing
|
||||
|
||||
### Fase 3: Verificación
|
||||
- [ ] Compilar y probar cada archivo migrado
|
||||
- [ ] Verificar que el comportamiento se mantiene consistente
|
||||
- [ ] Eliminar todas las referencias a frameFactor
|
||||
- [ ] Actualizar comentarios para reflejar unidades correctas
|
||||
|
||||
## Criterios de Éxito
|
||||
1. ✅ Cero ocurrencias de "frameFactor" en el código
|
||||
2. ✅ Todas las velocidades claramente documentadas (pixels/segundo vs pixels/frame)
|
||||
3. ✅ Comportamiento del juego idéntico al anterior
|
||||
4. ✅ Código más limpio y mantenible
|
||||
|
||||
## Notas Importantes
|
||||
- El frameFactor actual simula 60fps: `deltaTime / 16.67ms`
|
||||
- Esto significa que las velocidades actuales están en "pixels per 16.67ms"
|
||||
- Para verdadero deltaTime, necesitamos convertir a "pixels per second" o usar factor de frame explícito
|
||||
- Mantener constantes claras para evitar números mágicos
|
||||
|
||||
## Estado: En Progreso
|
||||
- Análisis iniciado
|
||||
- Plan documentado
|
||||
- Próximo paso: Análisis de velocidades en cada archivo
|
||||
536
Makefile
@@ -1,269 +1,272 @@
|
||||
# Directorios
|
||||
# ==============================================================================
|
||||
# DIRECTORIES
|
||||
# ==============================================================================
|
||||
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
||||
DIR_SOURCES := $(addsuffix /, $(DIR_ROOT)source)
|
||||
DIR_BIN := $(addsuffix /, $(DIR_ROOT))
|
||||
DIR_BUILD := $(addsuffix /, $(DIR_ROOT)build)
|
||||
DIR_TOOLS := $(addsuffix /, $(DIR_ROOT)tools)
|
||||
|
||||
# Variables
|
||||
# ==============================================================================
|
||||
# TARGET NAMES
|
||||
# ==============================================================================
|
||||
TARGET_NAME := coffee_crisis_arcade_edition
|
||||
TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
|
||||
APP_NAME := Coffee Crisis Arcade Edition
|
||||
RELEASE_FOLDER := ccae_release
|
||||
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
||||
RESOURCE_FILE := release/coffee.res
|
||||
|
||||
# Versión automática basada en la fecha actual (específica por SO)
|
||||
ifeq ($(OS),Windows_NT)
|
||||
VERSION := $(shell powershell -Command "Get-Date -Format 'yyyy-MM-dd'")
|
||||
TARGET_FILE := $(DIR_ROOT)$(TARGET_NAME).exe
|
||||
else
|
||||
VERSION := $(shell date +%Y-%m-%d)
|
||||
TARGET_FILE := $(DIR_ROOT)$(TARGET_NAME)
|
||||
endif
|
||||
APP_NAME := Coffee Crisis Arcade Edition
|
||||
DIST_DIR := dist
|
||||
RELEASE_FOLDER := dist/_tmp
|
||||
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
||||
RESOURCE_FILE := release/windows/coffee.res
|
||||
|
||||
# ==============================================================================
|
||||
# TOOLS
|
||||
# ==============================================================================
|
||||
DIR_PACK_TOOL := $(DIR_TOOLS)pack_resources
|
||||
SHADER_SCRIPT := $(DIR_ROOT)tools/shaders/compile_spirv.sh
|
||||
|
||||
# ==============================================================================
|
||||
# VERSION (extraída de 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
|
||||
|
||||
# Variables específicas para Windows (usando APP_NAME)
|
||||
# Hash del commit actual, computado en el host. Se pasa a CMake via -DGIT_HASH
|
||||
# para que el build en docker/emscripten no falle por "dubious ownership" de Git.
|
||||
ifeq ($(OS),Windows_NT)
|
||||
WIN_TARGET_FILE := $(DIR_BIN)$(APP_NAME)
|
||||
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
|
||||
|
||||
# ==============================================================================
|
||||
# SHELL (Windows usa cmd.exe)
|
||||
# ==============================================================================
|
||||
ifeq ($(OS),Windows_NT)
|
||||
SHELL := cmd.exe
|
||||
endif
|
||||
|
||||
# ==============================================================================
|
||||
# WINDOWS-SPECIFIC VARIABLES
|
||||
# ==============================================================================
|
||||
ifeq ($(OS),Windows_NT)
|
||||
WIN_TARGET_FILE := $(DIR_ROOT)$(APP_NAME)
|
||||
WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME)
|
||||
else
|
||||
WIN_TARGET_FILE := $(TARGET_FILE)
|
||||
WIN_RELEASE_FILE := $(RELEASE_FILE)
|
||||
endif
|
||||
|
||||
# Nombres para los ficheros de lanzamiento
|
||||
WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-win32-x64.zip
|
||||
MACOS_INTEL_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-intel.dmg
|
||||
MACOS_APPLE_SILICON_RELEASE := $(TARGET_FILE)-$(VERSION)-macos-apple-silicon.dmg
|
||||
LINUX_RELEASE := $(TARGET_FILE)-$(VERSION)-linux.tar.gz
|
||||
RASPI_RELEASE := $(TARGET_FILE)-$(VERSION)-raspberry.tar.gz
|
||||
# ==============================================================================
|
||||
# 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
|
||||
RASPI_RELEASE := $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-raspberry.tar.gz
|
||||
|
||||
# Lista completa de archivos fuente (basada en CMakeLists.txt)
|
||||
APP_SOURCES := \
|
||||
source/animated_sprite.cpp \
|
||||
source/asset.cpp \
|
||||
source/audio.cpp \
|
||||
source/background.cpp \
|
||||
source/balloon_formations.cpp \
|
||||
source/balloon_manager.cpp \
|
||||
source/balloon.cpp \
|
||||
source/bullet.cpp \
|
||||
source/color.cpp \
|
||||
source/define_buttons.cpp \
|
||||
source/difficulty.cpp \
|
||||
source/director.cpp \
|
||||
source/enter_name.cpp \
|
||||
source/explosions.cpp \
|
||||
source/external/gif.cpp \
|
||||
source/external/jail_audio.cpp \
|
||||
source/external/jail_shader.cpp \
|
||||
source/fade.cpp \
|
||||
source/game_logo.cpp \
|
||||
source/global_events.cpp \
|
||||
source/global_inputs.cpp \
|
||||
source/input_types.cpp \
|
||||
source/input.cpp \
|
||||
source/item.cpp \
|
||||
source/lang.cpp \
|
||||
source/main.cpp \
|
||||
source/manage_hiscore_table.cpp \
|
||||
source/mouse.cpp \
|
||||
source/moving_sprite.cpp \
|
||||
source/options.cpp \
|
||||
source/param.cpp \
|
||||
source/path_sprite.cpp \
|
||||
source/player.cpp \
|
||||
source/resource.cpp \
|
||||
source/resource_helper.cpp \
|
||||
source/resource_loader.cpp \
|
||||
source/resource_pack.cpp \
|
||||
source/scoreboard.cpp \
|
||||
source/screen.cpp \
|
||||
source/sections/credits.cpp \
|
||||
source/sections/game.cpp \
|
||||
source/sections/hiscore_table.cpp \
|
||||
source/sections/instructions.cpp \
|
||||
source/sections/intro.cpp \
|
||||
source/sections/logo.cpp \
|
||||
source/sections/title.cpp \
|
||||
source/shutdown.cpp \
|
||||
source/smart_sprite.cpp \
|
||||
source/sprite.cpp \
|
||||
source/stage.cpp \
|
||||
source/system_utils.cpp \
|
||||
source/tabe.cpp \
|
||||
source/text.cpp \
|
||||
source/texture.cpp \
|
||||
source/tiled_bg.cpp \
|
||||
source/ui/menu_option.cpp \
|
||||
source/ui/menu_renderer.cpp \
|
||||
source/ui/notifier.cpp \
|
||||
source/ui/service_menu.cpp \
|
||||
source/ui/ui_message.cpp \
|
||||
source/ui/window_message.cpp \
|
||||
source/utils.cpp \
|
||||
source/writer.cpp
|
||||
|
||||
# Includes
|
||||
INCLUDES := -Isource -Isource/external
|
||||
|
||||
# Variables según el sistema operativo
|
||||
# ==============================================================================
|
||||
# PLATAFORMA
|
||||
# ==============================================================================
|
||||
ifeq ($(OS),Windows_NT)
|
||||
FixPath = $(subst /,\\,$1)
|
||||
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -static-libstdc++ -static-libgcc -Wl,-Bstatic -lpthread -Wl,-Bdynamic -Wl,-subsystem,windows -DWINDOWS_BUILD
|
||||
CXXFLAGS_DEBUG := -std=c++20 -Wall -g -D_DEBUG -DWINDOWS_BUILD
|
||||
LDFLAGS := -lmingw32 -lws2_32 -lSDL3 -lopengl32
|
||||
RM := del /Q
|
||||
MKDIR := mkdir
|
||||
else
|
||||
FixPath = $1
|
||||
CXXFLAGS := -std=c++20 -Wall -Os -ffunction-sections -fdata-sections
|
||||
CXXFLAGS_DEBUG := -std=c++20 -Wall -g -D_DEBUG
|
||||
LDFLAGS := -lSDL3
|
||||
RMFILE := rm -f
|
||||
RMDIR := rm -rdf
|
||||
MKDIR := mkdir -p
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
CXXFLAGS += -DLINUX_BUILD
|
||||
LDFLAGS += -lGL
|
||||
endif
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN CON CMAKE
|
||||
# ==============================================================================
|
||||
all:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
debug:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
|
||||
@cmake --build build
|
||||
|
||||
# ==============================================================================
|
||||
# RELEASE AUTOMÁTICO (detecta SO)
|
||||
# ==============================================================================
|
||||
release:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@"$(MAKE)" windows_release
|
||||
else
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CXXFLAGS += -Wno-deprecated -DMACOS_BUILD
|
||||
CXXFLAGS_DEBUG += -Wno-deprecated -DMACOS_BUILD
|
||||
LDFLAGS += -framework OpenGL
|
||||
# Configurar arquitectura (por defecto arm64, como en CMake)
|
||||
CXXFLAGS += -arch arm64
|
||||
CXXFLAGS_DEBUG += -arch arm64
|
||||
@$(MAKE) macos_release
|
||||
else
|
||||
@$(MAKE) linux_release
|
||||
endif
|
||||
endif
|
||||
|
||||
# Reglas para compilación
|
||||
windows:
|
||||
@echo off
|
||||
@echo Compilando para Windows con nombre: "$(APP_NAME).exe"
|
||||
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_TARGET_FILE).exe"
|
||||
strip -s -R .comment -R .gnu.version "$(WIN_TARGET_FILE).exe" --strip-unneeded
|
||||
# ==============================================================================
|
||||
# REGLAS PARA HERRAMIENTA DE EMPAQUETADO Y RESOURCES.PACK
|
||||
# ==============================================================================
|
||||
pack_tool:
|
||||
@$(MAKE) -C $(DIR_PACK_TOOL)
|
||||
|
||||
windows_rec:
|
||||
@echo off
|
||||
@echo Compilando version de grabacion para Windows: "$(APP_NAME)_rec.exe"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DRECORDING $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_TARGET_FILE)_rec.exe"
|
||||
resources.pack:
|
||||
@$(MAKE) -C $(DIR_PACK_TOOL) pack
|
||||
|
||||
windows_debug:
|
||||
@echo off
|
||||
@echo Compilando version debug para Windows: "$(APP_NAME)_debug.exe"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(WIN_TARGET_FILE)_debug.exe"
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN DE SHADERS
|
||||
# ==============================================================================
|
||||
spirv:
|
||||
@echo "Compilando shaders SPIR-V..."
|
||||
$(SHADER_SCRIPT)
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA WINDOWS (RELEASE)
|
||||
# ==============================================================================
|
||||
windows_release:
|
||||
@$(MAKE) resources.pack
|
||||
@echo off
|
||||
@echo Creando release para Windows - Version: $(VERSION)
|
||||
|
||||
# Crea carpeta temporal 'RELEASE_FOLDER'
|
||||
powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||
powershell if (-not (Test-Path "$(RELEASE_FOLDER)")) {New-Item "$(RELEASE_FOLDER)" -ItemType Directory}
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Crea carpeta de distribución y carpeta temporal 'RELEASE_FOLDER'
|
||||
@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 la carpeta 'config' y el archivo 'resources.pack'
|
||||
powershell Copy-Item -Path "config" -Destination "$(RELEASE_FOLDER)" -recurse -Force
|
||||
powershell Copy-Item -Path "resources.pack" -Destination "$(RELEASE_FOLDER)"
|
||||
@powershell -Command "Copy-Item -Path 'config' -Destination '$(RELEASE_FOLDER)' -recurse -Force"
|
||||
@powershell -Command "Copy-Item -Path 'resources.pack' -Destination '$(RELEASE_FOLDER)'"
|
||||
|
||||
# Copia los ficheros que estan en la raíz del proyecto
|
||||
powershell Copy-Item "LICENSE" -Destination "$(RELEASE_FOLDER)"
|
||||
powershell Copy-Item "README.md" -Destination "$(RELEASE_FOLDER)"
|
||||
powershell Copy-Item "release\*.dll" -Destination "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila
|
||||
windres release/coffee.rc -O coff -o $(RESOURCE_FILE)
|
||||
$(CXX) $(APP_SOURCES) $(RESOURCE_FILE) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(WIN_RELEASE_FILE).exe"
|
||||
@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)' -Destination '$(WIN_RELEASE_FILE).exe'"
|
||||
strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded
|
||||
|
||||
# Crea el fichero .zip
|
||||
powershell if (Test-Path "$(WINDOWS_RELEASE)") {Remove-Item "$(WINDOWS_RELEASE)"}
|
||||
powershell Compress-Archive -Path "$(RELEASE_FOLDER)"/* -DestinationPath "$(WINDOWS_RELEASE)"
|
||||
@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 'RELEASE_FOLDER'
|
||||
powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||
|
||||
macos:
|
||||
@echo "Compilando para macOS: $(TARGET_NAME)"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||
|
||||
macos_debug:
|
||||
@echo "Compilando version debug para macOS: $(TARGET_NAME)_debug"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA MACOS (RELEASE)
|
||||
# ==============================================================================
|
||||
macos_release:
|
||||
@$(MAKE) resources.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
|
||||
@cmake --build build/intel
|
||||
|
||||
# Elimina datos de compilaciones anteriores
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) Frameworks
|
||||
$(RMFILE) tmp.dmg
|
||||
$(RMFILE) "$(DIST_DIR)"/rw.*
|
||||
$(RMFILE) "$(MACOS_INTEL_RELEASE)"
|
||||
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||
|
||||
# Crea la carpeta temporal para hacer el trabajo y las carpetas obligatorias para crear una app de macos
|
||||
# Crea la carpeta de distribución y la carpeta temporal con las carpetas obligatorias para una app macOS
|
||||
$(MKDIR) "$(DIST_DIR)"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
$(MKDIR) Frameworks
|
||||
|
||||
# Copia carpetas y ficheros
|
||||
cp -R config "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
cp resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
cp -R release/frameworks/SDL3.xcframework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||
cp -R release/frameworks/SDL3.xcframework Frameworks
|
||||
cp release/*.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
cp release/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
|
||||
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)"
|
||||
|
||||
# Crea enlaces
|
||||
ln -s /Applications "$(RELEASE_FOLDER)"/Applications
|
||||
|
||||
# Compila la versión para procesadores Intel
|
||||
ifdef ENABLE_MACOS_X86_64
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DMACOS_BUNDLE $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.15
|
||||
# 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
|
||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_INTEL_RELEASE)"
|
||||
$(RMFILE) tmp.dmg
|
||||
# Empaqueta el .dmg de la versión Intel con create-dmg
|
||||
@echo "Creando DMG Intel con iconos de 96x96..."
|
||||
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)"
|
||||
endif
|
||||
|
||||
# Compila la versión para procesadores Apple Silicon
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DMACOS_BUNDLE -DSDL_DISABLE_IMMINTRIN_H $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)" -rpath @executable_path/../Frameworks/ -target arm64-apple-macos11
|
||||
# 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
|
||||
@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
|
||||
hdiutil create tmp.dmg -ov -volname "$(APP_NAME)" -fs HFS+ -srcfolder "$(RELEASE_FOLDER)"
|
||||
hdiutil convert tmp.dmg -format UDZO -o "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||
$(RMFILE) tmp.dmg
|
||||
# Empaqueta el .dmg de la versión Apple Silicon con create-dmg
|
||||
@echo "Creando DMG Apple Silicon con iconos de 96x96..."
|
||||
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) Frameworks
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) build/intel
|
||||
$(RMDIR) build/arm
|
||||
$(RMFILE) "$(DIST_DIR)"/rw.*
|
||||
|
||||
linux:
|
||||
@echo "Compilando para Linux: $(TARGET_NAME)"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(TARGET_FILE)" --strip-unneeded
|
||||
|
||||
linux_debug:
|
||||
@echo "Compilando version debug para Linux: $(TARGET_NAME)_debug"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DDEBUG -DVERBOSE $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA LINUX (RELEASE)
|
||||
# ==============================================================================
|
||||
linux_release:
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Creando release para Linux - Version: $(VERSION)"
|
||||
# Elimina carpetas previas
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Crea la carpeta temporal para realizar el lanzamiento
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Elimina carpeta temporal previa y la recrea (crea dist/ si no existe)
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Copia ficheros
|
||||
@@ -271,9 +274,7 @@ linux_release:
|
||||
cp resources.pack "$(RELEASE_FOLDER)"
|
||||
cp LICENSE "$(RELEASE_FOLDER)"
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE)"
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||
|
||||
# Empaqueta ficheros
|
||||
@@ -284,9 +285,18 @@ linux_release:
|
||||
# Elimina la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA LINUX (RELEASE CON INTEGRACIÓN DESKTOP)
|
||||
# ==============================================================================
|
||||
linux_release_desktop:
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Creando release con integracion desktop para Linux - Version: $(VERSION)"
|
||||
# Elimina carpetas previas
|
||||
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Elimina carpetas previas y recrea (crea dist/ si no existe)
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Crea la estructura de directorios estándar para Linux
|
||||
@@ -302,8 +312,8 @@ linux_release_desktop:
|
||||
cp LICENSE "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
||||
cp README.md "$(RELEASE_FOLDER)/$(TARGET_NAME)/"
|
||||
|
||||
# Compila el ejecutable
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)"
|
||||
# Copia el ejecutable
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FOLDER)/$(TARGET_NAME)/bin/$(TARGET_NAME)" --strip-unneeded
|
||||
|
||||
# Crea el archivo .desktop
|
||||
@@ -321,25 +331,22 @@ linux_release_desktop:
|
||||
@echo 'Keywords=arcade;action;shooter;retro;' >> "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/applications/$(TARGET_NAME).desktop"
|
||||
|
||||
# Copia el icono (si existe) y lo redimensiona si es necesario
|
||||
@if [ -f "release/icon.png" ]; then \
|
||||
@if [ -f "release/icons/icon.png" ]; then \
|
||||
if command -v magick >/dev/null 2>&1; then \
|
||||
magick "release/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||
echo "Icono redimensionado de release/icon.png (usando ImageMagick)"; \
|
||||
magick "release/icons/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||
echo "Icono redimensionado de release/icons/icon.png (usando ImageMagick)"; \
|
||||
elif command -v convert >/dev/null 2>&1; then \
|
||||
convert "release/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||
echo "Icono redimensionado de release/icon.png (usando ImageMagick legacy)"; \
|
||||
convert "release/icons/icon.png" -resize 256x256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||
echo "Icono redimensionado de release/icons/icon.png (usando ImageMagick legacy)"; \
|
||||
elif command -v ffmpeg >/dev/null 2>&1; then \
|
||||
ffmpeg -i "release/icon.png" -vf scale=256:256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png" -y -loglevel quiet; \
|
||||
echo "Icono redimensionado de release/icon.png (usando ffmpeg)"; \
|
||||
ffmpeg -i "release/icons/icon.png" -vf scale=256:256 "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png" -y -loglevel quiet; \
|
||||
echo "Icono redimensionado de release/icons/icon.png (usando ffmpeg)"; \
|
||||
else \
|
||||
cp "release/icon.png" "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||
cp "release/icons/icon.png" "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||
echo "Icono copiado sin redimensionar (instalar ImageMagick o ffmpeg para redimensionado automatico)"; \
|
||||
fi; \
|
||||
elif [ -f "release/coffee.png" ]; then \
|
||||
cp "release/coffee.png" "$(RELEASE_FOLDER)/$(TARGET_NAME)/share/icons/hicolor/256x256/apps/$(TARGET_NAME).png"; \
|
||||
echo "Icono copiado desde release/coffee.png"; \
|
||||
else \
|
||||
echo "Advertencia: No se encontró release/icon.png ni release/coffee.png - crear icono manualmente"; \
|
||||
echo "Advertencia: No se encontró release/icons/icon.png - crear icono manualmente"; \
|
||||
fi
|
||||
|
||||
# Crea script de instalación
|
||||
@@ -372,29 +379,27 @@ linux_release_desktop:
|
||||
chmod +x "$(RELEASE_FOLDER)/$(TARGET_NAME)/uninstall.sh"
|
||||
|
||||
# Empaqueta ficheros
|
||||
$(RMFILE) "$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
||||
tar -czvf "$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz" -C "$(RELEASE_FOLDER)" .
|
||||
@echo "Release con integracion desktop creado: $(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
||||
$(RMFILE) "$(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
||||
tar -czvf "$(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz" -C "$(RELEASE_FOLDER)" .
|
||||
@echo "Release con integracion desktop creado: $(DIST_DIR)/$(TARGET_NAME)-$(VERSION)-linux-desktop.tar.gz"
|
||||
@echo "Para instalar: extraer y ejecutar ./$(TARGET_NAME)/install.sh"
|
||||
|
||||
# Elimina la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
raspi:
|
||||
@echo "Compilando para Raspberry Pi: $(TARGET_NAME)"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(TARGET_FILE)
|
||||
strip -s -R .comment -R .gnu.version $(TARGET_FILE) --strip-unneeded
|
||||
|
||||
raspi_debug:
|
||||
@echo "Compilando version debug para Raspberry Pi: $(TARGET_NAME)_debug"
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE -DDEBUG $(CXXFLAGS_DEBUG) $(LDFLAGS) -o "$(TARGET_FILE)_debug"
|
||||
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA RASPBERRY PI (RELEASE)
|
||||
# ==============================================================================
|
||||
raspi_release:
|
||||
@$(MAKE) resources.pack
|
||||
@echo "Creando release para Raspberry Pi - Version: $(VERSION)"
|
||||
# Elimina carpetas previas
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Crea la carpeta temporal para realizar el lanzamiento
|
||||
# Compila con cmake
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
|
||||
# Elimina carpetas previas y recrea (crea dist/ si no existe)
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Copia ficheros
|
||||
@@ -402,9 +407,7 @@ raspi_release:
|
||||
cp resources.pack "$(RELEASE_FOLDER)"
|
||||
cp LICENSE "$(RELEASE_FOLDER)"
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
|
||||
# Compila
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o "$(RELEASE_FILE)"
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||
|
||||
# Empaqueta ficheros
|
||||
@@ -415,49 +418,78 @@ raspi_release:
|
||||
# Elimina la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
anbernic:
|
||||
@echo "Compilando para Anbernic: $(TARGET_NAME)"
|
||||
# Elimina carpetas previas
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||
# ==============================================================================
|
||||
# COMPILACIÓN PARA WEBASSEMBLY (requiere Docker)
|
||||
# ==============================================================================
|
||||
wasm:
|
||||
@echo "Compilando para WebAssembly - Version: $(VERSION) ($(GIT_HASH))"
|
||||
docker run --rm \
|
||||
-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/"
|
||||
|
||||
# Crea la carpeta temporal para realizar el lanzamiento
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"_anbernic
|
||||
# ==============================================================================
|
||||
# CODE QUALITY (delegados a cmake)
|
||||
# ==============================================================================
|
||||
format:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target format
|
||||
|
||||
# Copia ficheros
|
||||
cp -R config "$(RELEASE_FOLDER)"_anbernic
|
||||
cp resources.pack "$(RELEASE_FOLDER)"_anbernic
|
||||
format-check:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target format-check
|
||||
|
||||
# Compila
|
||||
$(CXX) $(APP_SOURCES) $(INCLUDES) -DANBERNIC -DNO_SHADERS -DARCADE -DVERBOSE $(CXXFLAGS) $(LDFLAGS) -o $(RELEASE_FOLDER)_anbernic/$(TARGET_NAME)
|
||||
tidy:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target tidy
|
||||
|
||||
# Opción para deshabilitar audio (equivalente a la opción DISABLE_AUDIO de CMake)
|
||||
no_audio:
|
||||
@echo "Compilando sin audio: $(TARGET_NAME)_no_audio"
|
||||
$(CXX) $(filter-out source/external/jail_audio.cpp,$(APP_SOURCES)) $(INCLUDES) -DNO_AUDIO $(CXXFLAGS) $(LDFLAGS) -o "$(TARGET_FILE)_no_audio"
|
||||
tidy-fix:
|
||||
@cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build --target tidy-fix
|
||||
|
||||
# Regla para mostrar la versión actual
|
||||
# ==============================================================================
|
||||
# REGLAS ESPECIALES
|
||||
# ==============================================================================
|
||||
show_version:
|
||||
@echo "Version actual: $(VERSION)"
|
||||
|
||||
# Regla de ayuda
|
||||
help:
|
||||
@echo "Makefile para Coffee Crisis Arcade Edition"
|
||||
@echo "Comandos disponibles:"
|
||||
@echo " windows - Compilar para Windows"
|
||||
@echo " windows_debug - Compilar debug para Windows"
|
||||
@echo " windows_release - Crear release completo para Windows"
|
||||
@echo " linux - Compilar para Linux"
|
||||
@echo " linux_debug - Compilar debug para Linux"
|
||||
@echo " linux_release - Crear release basico para Linux"
|
||||
@echo " linux_release_desktop - Crear release con integracion desktop para Linux"
|
||||
@echo " macos - Compilar para macOS"
|
||||
@echo " macos_debug - Compilar debug para macOS"
|
||||
@echo " macos_release - Crear release completo para macOS"
|
||||
@echo " raspi - Compilar para Raspberry Pi"
|
||||
@echo " raspi_release - Crear release completo para Raspberry Pi"
|
||||
@echo " anbernic - Compilar para Anbernic"
|
||||
@echo " no_audio - Compilar sin sistema de audio"
|
||||
@echo " show_version - Mostrar version actual ($(VERSION))"
|
||||
@echo " help - Mostrar esta ayuda"
|
||||
@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 windows_release - Crear release para Windows"
|
||||
@echo " make linux_release - Crear release basico para Linux"
|
||||
@echo " make linux_release_desktop - Crear release con integracion desktop para Linux"
|
||||
@echo " make macos_release - Crear release para macOS"
|
||||
@echo " make raspi_release - Crear release para Raspberry Pi"
|
||||
@echo " make wasm - Crear build WebAssembly (requiere Docker) en dist/wasm"
|
||||
@echo ""
|
||||
@echo " Herramientas:"
|
||||
@echo " make spirv - Compilar shaders SPIR-V"
|
||||
@echo " make pack_tool - Compilar herramienta de empaquetado"
|
||||
@echo " make resources.pack - Generar pack de recursos desde data/"
|
||||
@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 ""
|
||||
@echo " Otros:"
|
||||
@echo " make show_version - Mostrar version actual ($(VERSION))"
|
||||
@echo " make help - Mostrar esta ayuda"
|
||||
|
||||
.PHONY: windows windows_rec windows_debug windows_release macos macos_debug macos_release linux linux_debug linux_release linux_release_desktop raspi raspi_debug raspi_release anbernic no_audio show_version help
|
||||
.PHONY: all debug release windows_release macos_release linux_release linux_release_desktop raspi_release wasm pack_tool resources.pack spirv format format-check tidy tidy-fix show_version help
|
||||
|
||||
13
README.md
@@ -1,6 +1,8 @@
|
||||
# Coffee Crisis Arcade Edition
|
||||
<div align="center">
|
||||
<img src="https://php.sustancia.synology.me/images/ccae/coffee_crisis_arcade_edition_cover_web.png" width="600" alt="Coffee Crisis Cover">
|
||||
</div>
|
||||
|
||||
<img src="https://php.sustancia.synology.me/images/ccae/coffee_crisis_arcade_edition_cover_web.png" width="300" align="left" style="margin-right: 20px; margin-bottom: 10px;" alt="Coffee Crisis Cover">
|
||||
# Coffee Crisis Arcade Edition
|
||||
|
||||
## ¡La batalla definitiva pel cafè està ací!
|
||||
|
||||
@@ -35,10 +37,7 @@ El joc està optimitzat per a ser jugat amb un mando de jocs, encara que un dels
|
||||
|
||||
> Nota: El joc suporta nomes un jugador amb teclat.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://php.sustancia.synology.me/images/ccae/ccae1.png" alt="Joc" width="45%" />
|
||||
<img src="https://php.sustancia.synology.me/images/ccae/ccae3.png" alt="Joc" width="45%" />
|
||||
</p>
|
||||

|
||||
|
||||
## Altres tecles
|
||||
|
||||
@@ -64,6 +63,8 @@ El joc està optimitzat per a ser jugat amb un mando de jocs, encara que un dels
|
||||
2. Descomprimix i executa l'arxiu `coffee_crisis_arcade_edition.exe`.
|
||||
3. Gaudeix del joc!
|
||||
|
||||

|
||||
|
||||
## Agraïments
|
||||
|
||||
Vull expressar la meua gratitud a **ChatGPT** i **GitHub Copilot**. Gràcies per ser un suport constant en el desenvolupament d'aquest joc!
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
# Variables: ${PREFIX}, ${SYSTEM_FOLDER}
|
||||
|
||||
# Archivos de configuración del sistema (absolutos y opcionales)
|
||||
DATA|${SYSTEM_FOLDER}/config.txt|optional,absolute
|
||||
DATA|${SYSTEM_FOLDER}/config.yaml|optional,absolute
|
||||
DATA|${SYSTEM_FOLDER}/controllers.json|optional,absolute
|
||||
DATA|${SYSTEM_FOLDER}/postfx.yaml|optional,absolute
|
||||
DATA|${SYSTEM_FOLDER}/crtpi.yaml|optional,absolute
|
||||
DATA|${SYSTEM_FOLDER}/score.bin|optional,absolute
|
||||
|
||||
# Archivos de configuración del juego
|
||||
@@ -18,183 +20,183 @@ DATA|${PREFIX}/config/pools.txt
|
||||
DATA|${PREFIX}/config/stages.txt
|
||||
|
||||
# Archivos con los datos de la demo
|
||||
DEMODATA|${PREFIX}/data/demo/demo1.bin
|
||||
DEMODATA|${PREFIX}/data/demo/demo2.bin
|
||||
DEMODATA|/data/demo/demo1.bin
|
||||
DEMODATA|/data/demo/demo2.bin
|
||||
DEMODATA|/data/demo/demo3.bin
|
||||
|
||||
# Música
|
||||
MUSIC|${PREFIX}/data/music/credits.ogg
|
||||
MUSIC|${PREFIX}/data/music/intro.ogg
|
||||
MUSIC|${PREFIX}/data/music/playing.ogg
|
||||
MUSIC|${PREFIX}/data/music/title.ogg
|
||||
MUSIC|/data/music/congratulations.ogg
|
||||
MUSIC|/data/music/credits.ogg
|
||||
MUSIC|/data/music/intro.ogg
|
||||
MUSIC|/data/music/playing.ogg
|
||||
MUSIC|/data/music/title.ogg
|
||||
|
||||
# Sonidos
|
||||
SOUND|${PREFIX}/data/sound/balloon_bounce0.wav
|
||||
SOUND|${PREFIX}/data/sound/balloon_bounce1.wav
|
||||
SOUND|${PREFIX}/data/sound/balloon_bounce2.wav
|
||||
SOUND|${PREFIX}/data/sound/balloon_bounce3.wav
|
||||
SOUND|${PREFIX}/data/sound/balloon_pop0.wav
|
||||
SOUND|${PREFIX}/data/sound/balloon_pop1.wav
|
||||
SOUND|${PREFIX}/data/sound/balloon_pop2.wav
|
||||
SOUND|${PREFIX}/data/sound/balloon_pop3.wav
|
||||
SOUND|${PREFIX}/data/sound/bullet.wav
|
||||
SOUND|${PREFIX}/data/sound/clock.wav
|
||||
SOUND|${PREFIX}/data/sound/coffee_out.wav
|
||||
SOUND|${PREFIX}/data/sound/continue_clock.wav
|
||||
SOUND|${PREFIX}/data/sound/credit.wav
|
||||
SOUND|${PREFIX}/data/sound/debian_drop.wav
|
||||
SOUND|${PREFIX}/data/sound/debian_pickup.wav
|
||||
SOUND|${PREFIX}/data/sound/hi_score_achieved.wav
|
||||
SOUND|${PREFIX}/data/sound/item_drop.wav
|
||||
SOUND|${PREFIX}/data/sound/item_pickup.wav
|
||||
SOUND|${PREFIX}/data/sound/jump.wav
|
||||
SOUND|${PREFIX}/data/sound/logo.wav
|
||||
SOUND|${PREFIX}/data/sound/notify.wav
|
||||
SOUND|${PREFIX}/data/sound/player_collision.wav
|
||||
SOUND|${PREFIX}/data/sound/power_ball_explosion.wav
|
||||
SOUND|${PREFIX}/data/sound/service_menu_adjust.wav
|
||||
SOUND|${PREFIX}/data/sound/service_menu_back.wav
|
||||
SOUND|${PREFIX}/data/sound/service_menu_move.wav
|
||||
SOUND|${PREFIX}/data/sound/service_menu_select.wav
|
||||
SOUND|${PREFIX}/data/sound/stage_change.wav
|
||||
SOUND|${PREFIX}/data/sound/tabe_hit.wav
|
||||
SOUND|${PREFIX}/data/sound/tabe.wav
|
||||
SOUND|${PREFIX}/data/sound/title.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_aw_aw_aw.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_coffee.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_credit_thankyou.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_get_ready.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_no.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_power_up.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_recover.wav
|
||||
SOUND|${PREFIX}/data/sound/voice_thankyou.wav
|
||||
SOUND|${PREFIX}/data/sound/walk.wav
|
||||
|
||||
# Shaders
|
||||
DATA|${PREFIX}/data/shaders/crtpi_240.glsl
|
||||
DATA|${PREFIX}/data/shaders/crtpi_256.glsl
|
||||
SOUND|/data/sound/balloon_bounce0.wav
|
||||
SOUND|/data/sound/balloon_bounce1.wav
|
||||
SOUND|/data/sound/balloon_bounce2.wav
|
||||
SOUND|/data/sound/balloon_bounce3.wav
|
||||
SOUND|/data/sound/balloon_pop0.wav
|
||||
SOUND|/data/sound/balloon_pop1.wav
|
||||
SOUND|/data/sound/balloon_pop2.wav
|
||||
SOUND|/data/sound/balloon_pop3.wav
|
||||
SOUND|/data/sound/bullet1p.wav
|
||||
SOUND|/data/sound/bullet2p.wav
|
||||
SOUND|/data/sound/clock.wav
|
||||
SOUND|/data/sound/coffee_out.wav
|
||||
SOUND|/data/sound/continue_clock.wav
|
||||
SOUND|/data/sound/credit.wav
|
||||
SOUND|/data/sound/debian_drop.wav
|
||||
SOUND|/data/sound/debian_pickup.wav
|
||||
SOUND|/data/sound/hi_score_achieved.wav
|
||||
SOUND|/data/sound/item_drop.wav
|
||||
SOUND|/data/sound/item_pickup.wav
|
||||
SOUND|/data/sound/jump.wav
|
||||
SOUND|/data/sound/logo.wav
|
||||
SOUND|/data/sound/name_input_accept.wav
|
||||
SOUND|/data/sound/notify.wav
|
||||
SOUND|/data/sound/player_collision.wav
|
||||
SOUND|/data/sound/power_ball_explosion.wav
|
||||
SOUND|/data/sound/service_menu_adjust.wav
|
||||
SOUND|/data/sound/service_menu_back.wav
|
||||
SOUND|/data/sound/service_menu_move.wav
|
||||
SOUND|/data/sound/service_menu_select.wav
|
||||
SOUND|/data/sound/stage_change.wav
|
||||
SOUND|/data/sound/tabe_hit.wav
|
||||
SOUND|/data/sound/tabe.wav
|
||||
SOUND|/data/sound/title.wav
|
||||
SOUND|/data/sound/voice_aw_aw_aw.wav
|
||||
SOUND|/data/sound/voice_coffee.wav
|
||||
SOUND|/data/sound/voice_credit_thankyou.wav
|
||||
SOUND|/data/sound/voice_game_over.wav
|
||||
SOUND|/data/sound/voice_get_ready.wav
|
||||
SOUND|/data/sound/voice_no.wav
|
||||
SOUND|/data/sound/voice_power_up.wav
|
||||
SOUND|/data/sound/voice_recover.wav
|
||||
SOUND|/data/sound/voice_thankyou.wav
|
||||
SOUND|/data/sound/walk.wav
|
||||
|
||||
# Texturas - Balloons
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon0.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon1.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon2.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/balloon3.ani
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon0.png
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon1.png
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon2.png
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/balloon3.png
|
||||
ANIMATION|/data/gfx/balloon/balloon0.ani
|
||||
ANIMATION|/data/gfx/balloon/balloon1.ani
|
||||
ANIMATION|/data/gfx/balloon/balloon2.ani
|
||||
ANIMATION|/data/gfx/balloon/balloon3.ani
|
||||
BITMAP|/data/gfx/balloon/balloon0.png
|
||||
BITMAP|/data/gfx/balloon/balloon1.png
|
||||
BITMAP|/data/gfx/balloon/balloon2.png
|
||||
BITMAP|/data/gfx/balloon/balloon3.png
|
||||
|
||||
# Texturas - Explosiones
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion0.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion1.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion2.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/explosion3.ani
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion0.png
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion1.png
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion2.png
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/explosion3.png
|
||||
ANIMATION|/data/gfx/balloon/explosion0.ani
|
||||
ANIMATION|/data/gfx/balloon/explosion1.ani
|
||||
ANIMATION|/data/gfx/balloon/explosion2.ani
|
||||
ANIMATION|/data/gfx/balloon/explosion3.ani
|
||||
BITMAP|/data/gfx/balloon/explosion0.png
|
||||
BITMAP|/data/gfx/balloon/explosion1.png
|
||||
BITMAP|/data/gfx/balloon/explosion2.png
|
||||
BITMAP|/data/gfx/balloon/explosion3.png
|
||||
|
||||
# Texturas - Power Ball
|
||||
ANIMATION|${PREFIX}/data/gfx/balloon/powerball.ani
|
||||
BITMAP|${PREFIX}/data/gfx/balloon/powerball.png
|
||||
ANIMATION|/data/gfx/balloon/powerball.ani
|
||||
BITMAP|/data/gfx/balloon/powerball.png
|
||||
|
||||
# Texturas - Bala
|
||||
ANIMATION|${PREFIX}/data/gfx/bullet/bullet.ani
|
||||
BITMAP|${PREFIX}/data/gfx/bullet/bullet.png
|
||||
ANIMATION|/data/gfx/bullet/bullet.ani
|
||||
BITMAP|/data/gfx/bullet/bullet.png
|
||||
|
||||
# Texturas - Tabe
|
||||
ANIMATION|${PREFIX}/data/gfx/tabe/tabe.ani
|
||||
BITMAP|${PREFIX}/data/gfx/tabe/tabe.png
|
||||
ANIMATION|/data/gfx/tabe/tabe.ani
|
||||
BITMAP|/data/gfx/tabe/tabe.png
|
||||
|
||||
# Texturas - Juego
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_buildings.png
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_clouds1.png
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_clouds2.png
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_grass.png
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_moon.png
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_power_meter.png
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_sky_colors.png
|
||||
BITMAP|${PREFIX}/data/gfx/game/game_sun.png
|
||||
BITMAP|/data/gfx/game/game_buildings.png
|
||||
BITMAP|/data/gfx/game/game_clouds1.png
|
||||
BITMAP|/data/gfx/game/game_clouds2.png
|
||||
ANIMATION|/data/gfx/game/game_grass.ani
|
||||
BITMAP|/data/gfx/game/game_grass.png
|
||||
BITMAP|/data/gfx/game/game_moon.png
|
||||
BITMAP|/data/gfx/game/game_power_meter.png
|
||||
BITMAP|/data/gfx/game/game_sky_colors.png
|
||||
BITMAP|/data/gfx/game/game_sun.png
|
||||
|
||||
# Texturas - Intro
|
||||
BITMAP|${PREFIX}/data/gfx/intro/intro1.png
|
||||
BITMAP|${PREFIX}/data/gfx/intro/intro2.png
|
||||
BITMAP|${PREFIX}/data/gfx/intro/intro3.png
|
||||
BITMAP|${PREFIX}/data/gfx/intro/intro4.png
|
||||
BITMAP|${PREFIX}/data/gfx/intro/intro5.png
|
||||
BITMAP|${PREFIX}/data/gfx/intro/intro6.png
|
||||
BITMAP|/data/gfx/intro/intro1.png
|
||||
BITMAP|/data/gfx/intro/intro2.png
|
||||
BITMAP|/data/gfx/intro/intro3.png
|
||||
BITMAP|/data/gfx/intro/intro4.png
|
||||
BITMAP|/data/gfx/intro/intro5.png
|
||||
BITMAP|/data/gfx/intro/intro6.png
|
||||
|
||||
# Texturas - Logo
|
||||
BITMAP|${PREFIX}/data/gfx/logo/logo_jailgames_mini.png
|
||||
BITMAP|${PREFIX}/data/gfx/logo/logo_jailgames.png
|
||||
BITMAP|${PREFIX}/data/gfx/logo/logo_since_1998.png
|
||||
BITMAP|/data/gfx/logo/logo_jailgames_mini.png
|
||||
BITMAP|/data/gfx/logo/logo_jailgames.png
|
||||
BITMAP|/data/gfx/logo/logo_since_1998.png
|
||||
|
||||
# Texturas - Items
|
||||
ANIMATION|${PREFIX}/data/gfx/item/item_clock.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/item/item_coffee_machine.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/item/item_coffee.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/item/item_debian.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/item/item_points1_disk.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/item/item_points2_gavina.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/item/item_points3_pacmar.ani
|
||||
BITMAP|${PREFIX}/data/gfx/item/item_clock.png
|
||||
BITMAP|${PREFIX}/data/gfx/item/item_coffee_machine.png
|
||||
BITMAP|${PREFIX}/data/gfx/item/item_coffee.png
|
||||
BITMAP|${PREFIX}/data/gfx/item/item_debian.png
|
||||
BITMAP|${PREFIX}/data/gfx/item/item_points1_disk.png
|
||||
BITMAP|${PREFIX}/data/gfx/item/item_points2_gavina.png
|
||||
BITMAP|${PREFIX}/data/gfx/item/item_points3_pacmar.png
|
||||
ANIMATION|/data/gfx/item/item_clock.ani
|
||||
ANIMATION|/data/gfx/item/item_coffee_machine.ani
|
||||
ANIMATION|/data/gfx/item/item_coffee.ani
|
||||
ANIMATION|/data/gfx/item/item_debian.ani
|
||||
ANIMATION|/data/gfx/item/item_points1_disk.ani
|
||||
ANIMATION|/data/gfx/item/item_points2_gavina.ani
|
||||
ANIMATION|/data/gfx/item/item_points3_pacmar.ani
|
||||
BITMAP|/data/gfx/item/item_clock.png
|
||||
BITMAP|/data/gfx/item/item_coffee_machine.png
|
||||
BITMAP|/data/gfx/item/item_coffee.png
|
||||
BITMAP|/data/gfx/item/item_debian.png
|
||||
BITMAP|/data/gfx/item/item_points1_disk.png
|
||||
BITMAP|/data/gfx/item/item_points2_gavina.png
|
||||
BITMAP|/data/gfx/item/item_points3_pacmar.png
|
||||
|
||||
# Texturas - Titulo
|
||||
ANIMATION|${PREFIX}/data/gfx/title/title_dust.ani
|
||||
BITMAP|${PREFIX}/data/gfx/title/title_arcade_edition.png
|
||||
BITMAP|${PREFIX}/data/gfx/title/title_bg_tile.png
|
||||
BITMAP|${PREFIX}/data/gfx/title/title_coffee.png
|
||||
BITMAP|${PREFIX}/data/gfx/title/title_crisis.png
|
||||
BITMAP|${PREFIX}/data/gfx/title/title_dust.png
|
||||
ANIMATION|/data/gfx/title/title_dust.ani
|
||||
BITMAP|/data/gfx/title/title_arcade_edition.png
|
||||
BITMAP|/data/gfx/title/title_bg_tile.png
|
||||
BITMAP|/data/gfx/title/title_coffee.png
|
||||
BITMAP|/data/gfx/title/title_crisis.png
|
||||
BITMAP|/data/gfx/title/title_dust.png
|
||||
|
||||
# Texturas - Jugador 1
|
||||
BITMAP|${PREFIX}/data/gfx/player/player1_power.png
|
||||
BITMAP|${PREFIX}/data/gfx/player/player1.gif
|
||||
PALETTE|${PREFIX}/data/gfx/player/player1_coffee1.pal
|
||||
PALETTE|${PREFIX}/data/gfx/player/player1_coffee2.pal
|
||||
PALETTE|${PREFIX}/data/gfx/player/player1_invencible.pal
|
||||
BITMAP|/data/gfx/player/player1_power.png
|
||||
BITMAP|/data/gfx/player/player1.gif
|
||||
PALETTE|/data/gfx/player/player1_coffee1.pal
|
||||
PALETTE|/data/gfx/player/player1_coffee2.pal
|
||||
PALETTE|/data/gfx/player/player1_invencible.pal
|
||||
|
||||
# Texturas - Jugador 2
|
||||
BITMAP|${PREFIX}/data/gfx/player/player2_power.png
|
||||
BITMAP|${PREFIX}/data/gfx/player/player2.gif
|
||||
PALETTE|${PREFIX}/data/gfx/player/player2_coffee1.pal
|
||||
PALETTE|${PREFIX}/data/gfx/player/player2_coffee2.pal
|
||||
PALETTE|${PREFIX}/data/gfx/player/player2_invencible.pal
|
||||
BITMAP|/data/gfx/player/player2_power.png
|
||||
BITMAP|/data/gfx/player/player2.gif
|
||||
PALETTE|/data/gfx/player/player2_coffee1.pal
|
||||
PALETTE|/data/gfx/player/player2_coffee2.pal
|
||||
PALETTE|/data/gfx/player/player2_invencible.pal
|
||||
|
||||
# Animaciones del jugador
|
||||
ANIMATION|${PREFIX}/data/gfx/player/player_power.ani
|
||||
ANIMATION|${PREFIX}/data/gfx/player/player.ani
|
||||
|
||||
# Texturas - Golpe del jugador
|
||||
BITMAP|${PREFIX}/data/gfx/player/hit.png
|
||||
ANIMATION|/data/gfx/player/player_power.ani
|
||||
ANIMATION|/data/gfx/player/player1.ani
|
||||
ANIMATION|/data/gfx/player/player2.ani
|
||||
|
||||
# Fuentes de texto
|
||||
BITMAP|${PREFIX}/data/font/04b_25_2x.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_2x_white.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_flat_2x.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_flat.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_grey.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_metal.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_reversed_2x.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_reversed.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25_white.png
|
||||
BITMAP|${PREFIX}/data/font/04b_25.png
|
||||
BITMAP|${PREFIX}/data/font/8bithud.png
|
||||
BITMAP|${PREFIX}/data/font/aseprite.png
|
||||
BITMAP|${PREFIX}/data/font/smb2_grad.png
|
||||
BITMAP|${PREFIX}/data/font/smb2.png
|
||||
FONT|${PREFIX}/data/font/04b_25_2x.txt
|
||||
FONT|${PREFIX}/data/font/04b_25.txt
|
||||
FONT|${PREFIX}/data/font/8bithud.txt
|
||||
FONT|${PREFIX}/data/font/aseprite.txt
|
||||
FONT|${PREFIX}/data/font/smb2.txt
|
||||
BITMAP|/data/font/04b_25_2x.png
|
||||
BITMAP|/data/font/04b_25_2x_white.png
|
||||
BITMAP|/data/font/04b_25_flat_2x.png
|
||||
BITMAP|/data/font/04b_25_flat.png
|
||||
BITMAP|/data/font/04b_25_grey.png
|
||||
BITMAP|/data/font/04b_25_metal.png
|
||||
BITMAP|/data/font/04b_25_reversed_2x.png
|
||||
BITMAP|/data/font/04b_25_reversed.png
|
||||
BITMAP|/data/font/04b_25_white.png
|
||||
BITMAP|/data/font/04b_25.png
|
||||
BITMAP|/data/font/8bithud.png
|
||||
BITMAP|/data/font/aseprite.png
|
||||
BITMAP|/data/font/smb2_grad.png
|
||||
BITMAP|/data/font/smb2.png
|
||||
FONT|/data/font/04b_25_2x.txt
|
||||
FONT|/data/font/04b_25.txt
|
||||
FONT|/data/font/8bithud.txt
|
||||
FONT|/data/font/aseprite.txt
|
||||
FONT|/data/font/smb2.txt
|
||||
|
||||
# Idiomas
|
||||
LANG|${PREFIX}/data/lang/ba_BA.json
|
||||
LANG|${PREFIX}/data/lang/en_UK.json
|
||||
LANG|${PREFIX}/data/lang/es_ES.json
|
||||
LANG|/data/lang/ba_BA.json
|
||||
LANG|/data/lang/en_UK.json
|
||||
LANG|/data/lang/es_ES.json
|
||||
@@ -8,270 +8,270 @@
|
||||
|
||||
formation: 0
|
||||
# Dos enemigos BALLOON3 uno a cada extremo
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 1
|
||||
# Dos enemigos BALLOON3 uno a cada cuarto. Ambos van hacia el centro
|
||||
X3_25, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_75, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_25, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_75, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 2
|
||||
# Cuatro enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 500
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 334
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 167
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.5000
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.3333
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1667
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 3
|
||||
# Cuatro enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 500
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 334
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 167
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.5000
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.3333
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1667
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 4
|
||||
# Tres enemigos BALLOON2. 0, 417, 834. Hacia la derecha
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 334
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 167
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
# Tres enemigos BALLOON2. 0, 25, 50. Hacia la derecha
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 5
|
||||
# Tres enemigos BALLOON2. 50, 75, 1667. Hacia la izquierda
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 334
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 167
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
# Tres enemigos BALLOON2. 50, 75, 100. Hacia la izquierda
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 6
|
||||
# Tres enemigos BALLOON2. 0, 0, 0. Hacia la derecha
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 334
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 167
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 7
|
||||
# Tres enemigos BALLOON2. 100, 1667, 1667. Hacia la izquierda
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 334
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 167
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
# Tres enemigos BALLOON2. 100, 100, 100. Hacia la izquierda
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 8
|
||||
# Seis enemigos BALLOON0. 0, 0, 0, 0, 0, 0. Hacia la derecha
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 834
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 667
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 500
|
||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 334
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 167
|
||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 9
|
||||
# Seis enemigos BALLOON0. 100, 1667, 1667, 1667, 1667, 1667. Hacia la izquierda
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 834
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 667
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 500
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 334
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 167
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
# Seis enemigos BALLOON0. 100, 100, 100, 100, 100, 100. Hacia la izquierda
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 10
|
||||
# Tres enemigos BALLOON3 seguidos desde la izquierda. Hacia la derecha
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 500
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 250
|
||||
X3_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.5000
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.2500
|
||||
X3_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 11
|
||||
# Tres enemigos BALLOON3 seguidos desde la derecha. Hacia la izquierda
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 500
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 250
|
||||
X3_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.5000
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.2500
|
||||
X3_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 12
|
||||
# Seis enemigos BALLOON1 uno detrás del otro. A la izquierda y hacia el centro
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 834
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 667
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 500
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 334
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 167
|
||||
X1_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.8333
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.6667
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.5000
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.3333
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1667
|
||||
X1_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 13
|
||||
# Seis enemigos BALLOON1 uno detrás del otro. A la derecha y hacia el centro
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 834
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 667
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 500
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 334
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 167
|
||||
X1_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.8333
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.6667
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.5000
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.3333
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1667
|
||||
X1_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 14
|
||||
# Cinco enemigos BALLOON2. Hacia la derecha. Separados
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 500
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 334
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 167
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 15
|
||||
# Cinco enemigos BALLOON2. Hacia la izquierda. Separados
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 500
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 334
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 167
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 16
|
||||
# Cinco enemigos BALLOON2. Hacia la derecha. Juntos
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 667
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 500
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 334
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 167
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 17
|
||||
# Cinco enemigos BALLOON2. Hacia la izquierda. Juntos
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 667
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 500
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 334
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 167
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 18
|
||||
# Doce enemigos BALLOON0. Hacia la derecha. Juntos
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1834
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1667
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 25000
|
||||
X0_0, 50, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1334
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 70
|
||||
X0_0, 83, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1000
|
||||
X0_0, 100, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 830
|
||||
X0_0, 7, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 40
|
||||
X0_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 500
|
||||
X0_0, 150, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 20
|
||||
X0_0, 167, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 10
|
||||
X0_0, 11, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.8333
|
||||
X0_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.6667
|
||||
X0_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.5000
|
||||
X0_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.3333
|
||||
X0_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||
X0_0, 5, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||
X0_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_0, 7, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_0, 9, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_0, 10, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_0, 11, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 19
|
||||
# Doce enemigos BALLOON0. Hacia la izquierda. Juntos
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1834
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1667
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 25000
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1334
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 70
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1000
|
||||
X0_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 830
|
||||
X0_100, -7, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 40
|
||||
X0_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 500
|
||||
X0_100, -9, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 20
|
||||
X0_100, -10, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 10
|
||||
X0_100, -11, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
X0_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.8333
|
||||
X0_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.6667
|
||||
X0_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.5000
|
||||
X0_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.3333
|
||||
X0_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||
X0_100, -5, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||
X0_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_100, -7, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_100, -9, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_100, -10, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_100, -11, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
|
||||
formation: 20
|
||||
# Cuatro enemigos BALLOON3 seguidos desde la izquierda/derecha. Simétricos
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0
|
||||
X3_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
X3_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, EXTRALARGE, 0.0000
|
||||
|
||||
formation: 21
|
||||
# Diez enemigos BALLOON1 uno detrás del otro. Izquierda/derecha. Simétricos
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 200
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 150
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 100
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 50
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 200
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 150
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 100
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 50
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0
|
||||
X1_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.2000
|
||||
X1_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1500
|
||||
X1_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.1000
|
||||
X1_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0500
|
||||
X1_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, MEDIUM, 0.0000
|
||||
X1_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.2000
|
||||
X1_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1500
|
||||
X1_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.1000
|
||||
X1_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0500
|
||||
X1_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, MEDIUM, 0.0000
|
||||
|
||||
formation: 22
|
||||
# Diez enemigos BALLOON2. Hacia la derecha/izquierda. Separados. Simétricos
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 500
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 334
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 167
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 500
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 334
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 167
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 6, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 8, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -6, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -8, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 23
|
||||
# Diez enemigos BALLOON2. Hacia la derecha. Juntos. Simétricos
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 667
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 500
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 334
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 167
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 667
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 500
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 334
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 167
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0
|
||||
X2_0, 0, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.6667
|
||||
X2_0, 1, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.5000
|
||||
X2_0, 2, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.3333
|
||||
X2_0, 3, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.1667
|
||||
X2_0, 4, DEFAULT_POS_Y, RIGHT, BALLOON, LARGE, 0.0000
|
||||
X2_100, 0, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.6667
|
||||
X2_100, -1, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.5000
|
||||
X2_100, -2, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.3333
|
||||
X2_100, -3, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.1667
|
||||
X2_100, -4, DEFAULT_POS_Y, LEFT, BALLOON, LARGE, 0.0000
|
||||
|
||||
formation: 24
|
||||
# Treinta enemigos BALLOON0. Del centro hacia los extremos. Juntos. Simétricos
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 83
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 167
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 250
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 334
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 417
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 500
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 584
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 667
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 750
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 834
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 917
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 16700
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 16784
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1167
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 83
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 167
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 250
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 334
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 417
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 500
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 584
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 667
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 750
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 834
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 917
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 16700
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 16784
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1167
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.2500
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.4167
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5833
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.7500
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.9167
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.2500
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.4167
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5833
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.7500
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.9167
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0833
|
||||
X0_50, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||
|
||||
formation: 25
|
||||
# Treinta enemigos BALLOON0. Del centro hacia adentro. Juntos. Simétricos
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1167
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 16784
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 16700
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 917
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 834
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 750
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 667
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 584
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 500
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 417
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 334
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 250
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 167
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 83
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1167
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 16784
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 16700
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 917
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 834
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 750
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 667
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 584
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 500
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 417
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 334
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 250
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 167
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 83
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.1667
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0833
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 1.0000
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.9167
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.8333
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.7500
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.6667
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5833
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.5000
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.4167
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.3333
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.2500
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.1667
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0833
|
||||
X0_50 + 20, 0, DEFAULT_POS_Y, LEFT, BALLOON, SMALL, 0.0000
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.1667
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0833
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 1.0000
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.9167
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.8333
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.7500
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.6667
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5833
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.5000
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.4167
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.3333
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.2500
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.1667
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0833
|
||||
X0_50 - 20, 0, DEFAULT_POS_Y, RIGHT, BALLOON, SMALL, 0.0000
|
||||
@@ -2,7 +2,6 @@
|
||||
# Formato: PARAMETRO VALOR
|
||||
|
||||
# --- GAME ---
|
||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||
game.item_text_outline_color E0E0E0F0 # Color del outline del texto de los items (RGBA hex)
|
||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||
game.height 240 # Alto de la resolución nativa del juego (en píxeles)
|
||||
@@ -10,10 +9,8 @@ game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||
game.play_area.rect.h 200 # Alto de la zona jugable
|
||||
game.name_entry_idle_time 10000 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60000 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
|
||||
# --- FADE ---
|
||||
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
||||
@@ -40,7 +37,7 @@ scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (
|
||||
|
||||
# --- TITLE ---
|
||||
title.press_start_position 180 # Posición Y del texto "Press Start"
|
||||
title.title_duration 14000 # Duración de la pantalla de título (milisegundos)
|
||||
title.title_duration 14 # Duración de la pantalla de título (segundos)
|
||||
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
||||
title.title_c_c_position 80 # Posición Y del título principal
|
||||
title.bg_color 41526F # Color de fondo en la sección titulo
|
||||
@@ -48,15 +45,15 @@ title.bg_color 41526F # Color de fondo en la sección titulo
|
||||
# --- BACKGROUND ---
|
||||
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
||||
|
||||
# --- BALLOONS --- (deltaTime puro: vel en pixels/ms, grav en pixels/ms²)
|
||||
balloon.settings[0].vel 0.165f # Velocidad inicial del globo 1 (pixels/ms)
|
||||
balloon.settings[0].grav 0.00032f # Gravedad aplicada al globo 1 (pixels/ms²)
|
||||
balloon.settings[1].vel 0.222f # Velocidad inicial del globo 2 (pixels/ms)
|
||||
balloon.settings[1].grav 0.00036f # Gravedad aplicada al globo 2 (pixels/ms²)
|
||||
balloon.settings[2].vel 0.282f # Velocidad inicial del globo 3 (pixels/ms)
|
||||
balloon.settings[2].grav 0.00036f # Gravedad aplicada al globo 3 (pixels/ms²)
|
||||
balloon.settings[3].vel 0.327f # Velocidad inicial del globo 4 (pixels/ms)
|
||||
balloon.settings[3].grav 0.00036f # Gravedad aplicada al globo 4 (pixels/ms²)
|
||||
# --- BALLOONS --- (deltaTime en segundos: vel en pixels/s, grav en pixels/s²)
|
||||
balloon.settings[0].vel 165.0f # Velocidad inicial del globo 1 (pixels/s)
|
||||
balloon.settings[0].grav 320.0f # Gravedad aplicada al globo 1 (pixels/s²)
|
||||
balloon.settings[1].vel 222.0f # Velocidad inicial del globo 2 (pixels/s)
|
||||
balloon.settings[1].grav 360.0f # Gravedad aplicada al globo 2 (pixels/s²)
|
||||
balloon.settings[2].vel 282.0f # Velocidad inicial del globo 3 (pixels/s)
|
||||
balloon.settings[2].grav 360.0f # Gravedad aplicada al globo 3 (pixels/s²)
|
||||
balloon.settings[3].vel 327.0f # Velocidad inicial del globo 4 (pixels/s)
|
||||
balloon.settings[3].grav 360.0f # Gravedad aplicada al globo 4 (pixels/s²)
|
||||
|
||||
balloon.color[0] blue # Color de creación del globo normal
|
||||
balloon.color[1] orange # Color del globo normal
|
||||
@@ -93,7 +90,7 @@ service_menu.window_message.text_safety_margin 15.0f # Margen de segu
|
||||
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
|
||||
|
||||
# --- INTRO ---
|
||||
intro.bg_color 4664BD # Color de fondo de la intro
|
||||
intro.bg_color 41526F # Color de fondo de la intro
|
||||
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
||||
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
||||
intro.text_distance_from_bottom 48 # Posicion del texto
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Formato: PARAMETRO VALOR
|
||||
|
||||
# --- GAME ---
|
||||
game.item_size 20 # Tamaño de los items del juego (en píxeles)
|
||||
game.item_text_outline_color E0E0E0F0 # Color del outline del texto de los items (RGBA hex)
|
||||
game.width 320 # Ancho de la resolución nativa del juego (en píxeles)
|
||||
game.height 256 # Alto de la resolución nativa del juego (en píxeles)
|
||||
@@ -10,10 +9,8 @@ game.play_area.rect.x 0 # Posición X de la zona jugable
|
||||
game.play_area.rect.y 0 # Posición Y de la zona jugable
|
||||
game.play_area.rect.w 320 # Ancho de la zona jugable
|
||||
game.play_area.rect.h 216 # Alto de la zona jugable
|
||||
game.name_entry_idle_time 10000 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60000 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
game.hit_stop false # Indica si debe haber un paro cuando el jugador es golpeado por un globo
|
||||
game.hit_stop_ms 500 # Cantidad de milisegundos que dura el hit_stop
|
||||
game.name_entry_idle_time 10 # Segundos para introducir el nombre al finalizar la partida si no se pulsa nada
|
||||
game.name_entry_total_time 60 # Segundos totales para introducir el nombre al finalizar la partida
|
||||
|
||||
# --- FADE ---
|
||||
fade.color 1F2B30 # Color hexadecimal para el efecto de fundido
|
||||
@@ -40,7 +37,7 @@ scoreboard.skip_countdown_value 8 # Valor para saltar la cuenta atrás (
|
||||
|
||||
# --- TITLE ---
|
||||
title.press_start_position 180 # Posición Y del texto "Press Start"
|
||||
title.title_duration 14000 # Duración de la pantalla de título (milisegundos)
|
||||
title.title_duration 14 # Duración de la pantalla de título (segundos)
|
||||
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
|
||||
title.title_c_c_position 80 # Posición Y del título principal
|
||||
title.bg_color 41526F # Color de fondo en la sección titulo
|
||||
@@ -48,15 +45,15 @@ title.bg_color 41526F # Color de fondo en la sección titulo
|
||||
# --- BACKGROUND ---
|
||||
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
|
||||
|
||||
# --- BALLOONS --- (deltaTime puro: vel en pixels/ms, grav en pixels/ms²)
|
||||
balloon.settings[0].vel 0.165f # Velocidad inicial del globo 1 (pixels/ms)
|
||||
balloon.settings[0].grav 0.00032f # Gravedad aplicada al globo 1 (pixels/ms²)
|
||||
balloon.settings[1].vel 0.222f # Velocidad inicial del globo 2 (pixels/ms)
|
||||
balloon.settings[1].grav 0.00036f # Gravedad aplicada al globo 2 (pixels/ms²)
|
||||
balloon.settings[2].vel 0.282f # Velocidad inicial del globo 3 (pixels/ms)
|
||||
balloon.settings[2].grav 0.00036f # Gravedad aplicada al globo 3 (pixels/ms²)
|
||||
balloon.settings[3].vel 0.327f # Velocidad inicial del globo 4 (pixels/ms)
|
||||
balloon.settings[3].grav 0.00036f # Gravedad aplicada al globo 4 (pixels/ms²)
|
||||
# --- BALLOONS --- (deltaTime en segundos: vel en pixels/s, grav en pixels/s²)
|
||||
balloon.settings[0].vel 165.0f # Velocidad inicial del globo 1 (pixels/s)
|
||||
balloon.settings[0].grav 320.0f # Gravedad aplicada al globo 1 (pixels/s²)
|
||||
balloon.settings[1].vel 222.0f # Velocidad inicial del globo 2 (pixels/s)
|
||||
balloon.settings[1].grav 360.0f # Gravedad aplicada al globo 2 (pixels/s²)
|
||||
balloon.settings[2].vel 282.0f # Velocidad inicial del globo 3 (pixels/s)
|
||||
balloon.settings[2].grav 360.0f # Gravedad aplicada al globo 3 (pixels/s²)
|
||||
balloon.settings[3].vel 327.0f # Velocidad inicial del globo 4 (pixels/s)
|
||||
balloon.settings[3].grav 360.0f # Gravedad aplicada al globo 4 (pixels/s²)
|
||||
|
||||
balloon.color[0] blue # Color de creación del globo normal
|
||||
balloon.color[1] orange # Color del globo normal
|
||||
@@ -93,7 +90,7 @@ service_menu.window_message.text_safety_margin 15.0f # Margen de segu
|
||||
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
|
||||
|
||||
# --- INTRO ---
|
||||
intro.bg_color 4664BD # Color de fondo de la intro
|
||||
intro.bg_color 41526F # Color de fondo de la intro
|
||||
intro.card_color CBDBFC # Color de las tarjetas en la intro
|
||||
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
|
||||
intro.text_distance_from_bottom 48 # Posición del texto desde la parte inferior
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
BIN
data/demo/demo3.bin
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -185,7 +185,7 @@
|
||||
# 122 z
|
||||
5
|
||||
# 123 {
|
||||
3
|
||||
7
|
||||
# 124 |
|
||||
2
|
||||
# 125 }
|
||||
|
||||
@@ -3,28 +3,28 @@ frame_height=10
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,28 +3,28 @@ frame_height=16
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,28 +3,28 @@ frame_height=26
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,28 +3,28 @@ frame_height=48
|
||||
|
||||
[animation]
|
||||
name=orange
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=blue
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=10,11,12,13,14,15,16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=green
|
||||
speed=10
|
||||
speed=0.1667
|
||||
loop=0
|
||||
frames=20,21,22,23,24,25,26,27,28,29
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red
|
||||
speed=20
|
||||
speed=0.3333
|
||||
loop=0
|
||||
frames=30,31,32,33,34,35,36,37,38,39
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=10
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=16
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=26
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=48
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6,7,8,9
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=49
|
||||
|
||||
[animation]
|
||||
name=powerball
|
||||
speed=10
|
||||
speed=0.0167
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
@@ -2,43 +2,85 @@ frame_width=12
|
||||
frame_height=12
|
||||
|
||||
[animation]
|
||||
name=normal_up
|
||||
speed=5
|
||||
loop=0
|
||||
frames=0,1,2
|
||||
name=yellow_up
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=0
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=normal_left
|
||||
speed=5
|
||||
loop=0
|
||||
frames=3,4,5,5,4,3
|
||||
name=yellow_left
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=normal_right
|
||||
speed=5
|
||||
loop=0
|
||||
frames=6,7,8,8,7,6
|
||||
name=yellow_right
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=2
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=powered_up
|
||||
speed=5
|
||||
loop=0
|
||||
frames=9,10,11,11,10,9
|
||||
name=green_up
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=3
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=powered_left
|
||||
speed=5
|
||||
loop=0
|
||||
frames=12,13,14,14,13,12
|
||||
name=green_left
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=4
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=powered_right
|
||||
speed=5
|
||||
loop=0
|
||||
frames=15,16,17,17,26,15
|
||||
name=green_right
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=5
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red_up
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=6
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red_left
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=7
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=red_right
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=8
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=purple_up
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=9
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=purple_left
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=10
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=purple_right
|
||||
speed=20
|
||||
loop=-1
|
||||
frames=11
|
||||
[/animation]
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.7 KiB |
9
data/gfx/game/game_grass.ani
Normal file
@@ -0,0 +1,9 @@
|
||||
frame_width=320
|
||||
frame_height=10
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=0.2
|
||||
loop=0
|
||||
frames=0,1,2,1
|
||||
[/animation]
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -2,8 +2,15 @@ frame_width=20
|
||||
frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
name=blink
|
||||
speed=0.2
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=no-blink
|
||||
speed=0
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
@@ -2,8 +2,15 @@ frame_width=20
|
||||
frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
name=blink
|
||||
speed=0.2
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=no-blink
|
||||
speed=0
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=39
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=6
|
||||
speed=0.1
|
||||
loop=0
|
||||
frames=0,1,2,3,4,5,6,7,8
|
||||
[/animation]
|
||||
@@ -2,8 +2,15 @@ frame_width=20
|
||||
frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
name=blink
|
||||
speed=0.2
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=no-blink
|
||||
speed=0
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
@@ -2,8 +2,15 @@ frame_width=20
|
||||
frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
name=blink
|
||||
speed=0.2
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=no-blink
|
||||
speed=0
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
@@ -2,8 +2,15 @@ frame_width=20
|
||||
frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
name=blink
|
||||
speed=0.2
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=no-blink
|
||||
speed=0
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
@@ -2,8 +2,15 @@ frame_width=20
|
||||
frame_height=20
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
name=blink
|
||||
speed=0.2
|
||||
loop=0
|
||||
frames=0,0,1
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=no-blink
|
||||
speed=0
|
||||
loop=-1
|
||||
frames=1
|
||||
[/animation]
|
||||
|
Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 696 B |
|
Before Width: | Height: | Size: 720 B After Width: | Height: | Size: 624 B |
|
Before Width: | Height: | Size: 312 B |
@@ -3,133 +3,133 @@ frame_height=32
|
||||
|
||||
[animation]
|
||||
name=walk
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=0,1,2,3
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand
|
||||
speed=10
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=4,5,6,7
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-fire-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=8,9,10,11
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-recoil-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=12,13,14,15
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-cool-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-fire-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=20
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-recoil-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=21
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-cool-side
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=22
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-fire-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=23,24,25,26
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-recoil-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=27,28,29,30
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-cool-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=31,32,33,34
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-fire-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=35
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-recoil-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=36
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-cool-center
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=37
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=rolling
|
||||
speed=10
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=38,39,40,41
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=celebration
|
||||
speed=10
|
||||
loop=-1
|
||||
frames=42,42,42,42,42,42,43,44,45,46,46,46,46,46,46,45,45,45,46,46,46,45,45,45,44,43,42,42,42
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=42,42,42,43,44,45,44,43,42,43,44,45,44,43,42,43,44,45,44,43,42,46,46,46,46,46,46,47,48,49,50,50,50,50,50,50,49,49,49,50,50,50,49,49,49,48,47,46,46,46
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=dizzy
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=47,48,49,50,51,52,53
|
||||
frames=51,52,53,54,55,56,57
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=recover
|
||||
speed=3
|
||||
speed=0.05
|
||||
loop=-1
|
||||
frames=54,54,54,54,55,56,57,58,58,58,59,60,61,58,59,60,61,58,59,60,61,62,62,62,62
|
||||
frames=58,58,58,58,59,60,61,62,62,62,63,64,65,62,63,64,65,62,63,64,65,66,66,66,66
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=hello
|
||||
speed=3
|
||||
speed=0.05
|
||||
loop=-1
|
||||
frames=63,64,65,66,67,68,69,70,71,72,73,73,73,73,73,73,73,73,73,73,73,73,73,74,75,76,77,78,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,79,80,81,82,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63
|
||||
frames=67,68,69,70,71,72,73,74,75,76,77,77,77,77,77,77,77,77,77,77,77,77,77,78,79,80,81,82,83,84,85,86,86,85,84,83,83,84,85,86,86,85,84,83,83,84,85,86,86,85,84,83,83,84,85,86,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67
|
||||
[/animation]
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
135
data/gfx/player/player2.ani
Normal file
@@ -0,0 +1,135 @@
|
||||
frame_width=32
|
||||
frame_height=32
|
||||
|
||||
[animation]
|
||||
name=walk
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=0,1,2,3
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=4,5,6,7
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-fire-side
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=8,9,10,11
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-recoil-side
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=12,13,14,15
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-cool-side
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=16,17,18,19
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-fire-side
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=20
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-recoil-side
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=21
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-cool-side
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=22
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-fire-center
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=23,24,25,26
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-recoil-center
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=27,28,29,30
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=walk-cool-center
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=31,32,33,34
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-fire-center
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=35
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-recoil-center
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=36
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=stand-cool-center
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=37
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=rolling
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=38,39,40,41
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=celebration
|
||||
speed=0.167
|
||||
loop=0
|
||||
frames=47,47,47,47,47,47,48,49,50,51,51,51,51,51,51,50,50,50,51,51,51,50,50,50,49,48,47,47,47,42,42,42,43,44,45,46,45,46,45,46,45,46,45,46,45,46,45,44,43,42
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=dizzy
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=52,53,54,55,56,57,58
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=recover
|
||||
speed=0.05
|
||||
loop=-1
|
||||
frames=59,59,59,59,60,61,62,63,63,63,64,65,66,63,64,65,66,63,64,65,66,67,67,67,67
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=hello
|
||||
speed=0.05
|
||||
loop=-1
|
||||
frames=68,69,70,71,72,73,74,75,76,77,78,78,78,78,78,78,78,78,78,78,78,78,78,79,80,81,82,83,84,85,86,87,87,86,85,84,84,85,86,87,87,86,85,84,84,85,86,87,87,86,85,84,84,85,86,87,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68
|
||||
[/animation]
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -3,7 +3,7 @@ frame_height=44
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=5
|
||||
speed=0.0833
|
||||
loop=0
|
||||
frames=0,1,2,3
|
||||
[/animation]
|
||||
@@ -3,14 +3,14 @@ frame_height=32
|
||||
|
||||
[animation]
|
||||
name=fly
|
||||
speed=2
|
||||
speed=0.0333
|
||||
loop=0
|
||||
frames=0,1
|
||||
[/animation]
|
||||
|
||||
[animation]
|
||||
name=hit
|
||||
speed=2
|
||||
speed=0.0333
|
||||
loop=0
|
||||
frames=2,3
|
||||
[/animation]
|
||||
@@ -3,7 +3,7 @@ frame_height=16
|
||||
|
||||
[animation]
|
||||
name=default
|
||||
speed=8
|
||||
speed=0.1333
|
||||
loop=-1
|
||||
frames=0,1,2,3,4,5,6
|
||||
[/animation]
|
||||
@@ -21,12 +21,13 @@
|
||||
"[GAME_TEXT] 2": "Queden ",
|
||||
"[GAME_TEXT] 2A": " fases mes!",
|
||||
"[GAME_TEXT] 3": "Ultima fase!",
|
||||
"[GAME_TEXT] 4": "SuperPoder!",
|
||||
"[GAME_TEXT] 4": "Automatic!",
|
||||
"[GAME_TEXT] 5": "+1 Colp",
|
||||
"[GAME_TEXT] 6": "Temps!",
|
||||
"[GAME_TEXT] 7": "Endavant!",
|
||||
"[GAME_TEXT] 8": "1.000.000 de punts!",
|
||||
"[GAME_TEXT] THANK_YOU": "Gracies!",
|
||||
"[GAME_TEXT] NEW_RECORD": "Nou record!",
|
||||
|
||||
"[HIGHSCORE_TABLE] CAPTION": "Millors puntuacions",
|
||||
|
||||
@@ -71,6 +72,7 @@
|
||||
"[NOTIFICATIONS] DISCONNECTED": "desconectat",
|
||||
|
||||
"[RESOURCE] LOADING": "Carregant",
|
||||
"[RESOURCE] PRESS_TO_CONTINUE": "Prem una tecla per continuar",
|
||||
|
||||
"[SERVICE_MENU] TITLE": "Menu de servei",
|
||||
"[SERVICE_MENU] RESET": "Reiniciar",
|
||||
@@ -78,7 +80,10 @@
|
||||
"[SERVICE_MENU] SHUTDOWN": "Apagar el sistema",
|
||||
"[SERVICE_MENU] FULLSCREEN": "Pantalla completa",
|
||||
"[SERVICE_MENU] WINDOW_SIZE": "Tamany de la finestra",
|
||||
"[SERVICE_MENU] SHADERS": "Filtre",
|
||||
"[SERVICE_MENU] SHADER": "Shader",
|
||||
"[SERVICE_MENU] SHADER_DISABLED": "Desactivat",
|
||||
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
||||
"[SERVICE_MENU] SUPERSAMPLING": "Supermostreig",
|
||||
"[SERVICE_MENU] VSYNC": "Sincronisme vertical",
|
||||
"[SERVICE_MENU] INTEGER_SCALE": "Escalat sencer",
|
||||
"[SERVICE_MENU] MAIN_VOLUME": "Volumen general",
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
"[GAME_TEXT] 2": "",
|
||||
"[GAME_TEXT] 2A": " stages left!",
|
||||
"[GAME_TEXT] 3": "Last stage!",
|
||||
"[GAME_TEXT] 4": "PowerUp",
|
||||
"[GAME_TEXT] 4": "AutoFire!",
|
||||
"[GAME_TEXT] 5": "+1 Hit",
|
||||
"[GAME_TEXT] 6": "Stop!",
|
||||
"[GAME_TEXT] 7": "Get Ready!",
|
||||
"[GAME_TEXT] 8": "1,000,000 points!",
|
||||
"[GAME_TEXT] THANK_YOU": "Thank you!",
|
||||
"[GAME_TEXT] NEW_RECORD": "New record!",
|
||||
|
||||
"[HIGHSCORE_TABLE] CAPTION": "Best scores",
|
||||
|
||||
@@ -70,6 +71,7 @@
|
||||
"[NOTIFICATIONS] DISCONNECTED": "disconnected",
|
||||
|
||||
"[RESOURCE] LOADING": "Loading",
|
||||
"[RESOURCE] PRESS_TO_CONTINUE": "Press any key to continue",
|
||||
|
||||
"[SERVICE_MENU] TITLE": "Service Menu",
|
||||
"[SERVICE_MENU] RESET": "Reset",
|
||||
@@ -77,7 +79,10 @@
|
||||
"[SERVICE_MENU] SHUTDOWN": "Shutdown System",
|
||||
"[SERVICE_MENU] FULLSCREEN": "Fullscreen",
|
||||
"[SERVICE_MENU] WINDOW_SIZE": "Window Zoom",
|
||||
"[SERVICE_MENU] SHADERS": "Shaders",
|
||||
"[SERVICE_MENU] SHADER": "Shader",
|
||||
"[SERVICE_MENU] SHADER_DISABLED": "Disabled",
|
||||
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
||||
"[SERVICE_MENU] SUPERSAMPLING": "Supersampling",
|
||||
"[SERVICE_MENU] VSYNC": "V-Sync",
|
||||
"[SERVICE_MENU] INTEGER_SCALE": "Integer Scale",
|
||||
"[SERVICE_MENU] MAIN_VOLUME": "Main Volume",
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
"[GAME_TEXT] 2": "!Quedan ",
|
||||
"[GAME_TEXT] 2A": " fases!",
|
||||
"[GAME_TEXT] 3": "Ultima fase!",
|
||||
"[GAME_TEXT] 4": "Potenciador",
|
||||
"[GAME_TEXT] 4": "Automatico!",
|
||||
"[GAME_TEXT] 5": "+1 Golpe",
|
||||
"[GAME_TEXT] 6": "Tiempo!",
|
||||
"[GAME_TEXT] 7": "Adelante!",
|
||||
"[GAME_TEXT] 8": "1.000.000 de puntos!",
|
||||
"[GAME_TEXT] THANK_YOU": "Gracias!",
|
||||
"[GAME_TEXT] NEW_RECORD": "Nuevo record!",
|
||||
|
||||
"[HIGHSCORE_TABLE] CAPTION": "Mejores puntuaciones",
|
||||
|
||||
@@ -70,6 +71,7 @@
|
||||
"[NOTIFICATIONS] DISCONNECTED": "desconectado",
|
||||
|
||||
"[RESOURCE] LOADING": "Cargando",
|
||||
"[RESOURCE] PRESS_TO_CONTINUE": "Pulsa una tecla para continuar",
|
||||
|
||||
"[SERVICE_MENU] TITLE": "Menu de servicio",
|
||||
"[SERVICE_MENU] RESET": "Reiniciar",
|
||||
@@ -77,7 +79,10 @@
|
||||
"[SERVICE_MENU] SHUTDOWN": "Apagar el sistema",
|
||||
"[SERVICE_MENU] FULLSCREEN": "Pantalla completa",
|
||||
"[SERVICE_MENU] WINDOW_SIZE": "Zoom de ventana",
|
||||
"[SERVICE_MENU] SHADERS": "Filtro grafico",
|
||||
"[SERVICE_MENU] SHADER": "Shader",
|
||||
"[SERVICE_MENU] SHADER_DISABLED": "Desactivado",
|
||||
"[SERVICE_MENU] SHADER_PRESET": "Preset",
|
||||
"[SERVICE_MENU] SUPERSAMPLING": "Supersampling",
|
||||
"[SERVICE_MENU] VSYNC": "Sincronismo vertical",
|
||||
"[SERVICE_MENU] INTEGER_SCALE": "Escalado proporcional",
|
||||
"[SERVICE_MENU] MAIN_VOLUME": "Volumen general",
|
||||
|
||||
BIN
data/music/congratulations.ogg
Normal file
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
crt-pi - A Raspberry Pi friendly CRT shader.
|
||||
|
||||
Copyright (C) 2015-2016 davej
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
This shader is designed to work well on Raspberry Pi GPUs (i.e. 1080P @ 60Hz on a game with a 4:3 aspect ratio). It pushes the Pi's GPU hard and enabling some features will slow it down so that it is no longer able to match 1080P @ 60Hz. You will need to overclock your Pi to the fastest setting in raspi-config to get the best results from this shader: 'Pi2' for Pi2 and 'Turbo' for original Pi and Pi Zero. Note: Pi2s are slower at running the shader than other Pis, this seems to be down to Pi2s lower maximum memory speed. Pi2s don't quite manage 1080P @ 60Hz - they drop about 1 in 1000 frames. You probably won't notice this, but if you do, try enabling FAKE_GAMMA.
|
||||
|
||||
SCANLINES enables scanlines. You'll almost certainly want to use it with MULTISAMPLE to reduce moire effects. SCANLINE_WEIGHT defines how wide scanlines are (it is an inverse value so a higher number = thinner lines). SCANLINE_GAP_BRIGHTNESS defines how dark the gaps between the scan lines are. Darker gaps between scan lines make moire effects more likely.
|
||||
|
||||
GAMMA enables gamma correction using the values in INPUT_GAMMA and OUTPUT_GAMMA. FAKE_GAMMA causes it to ignore the values in INPUT_GAMMA and OUTPUT_GAMMA and approximate gamma correction in a way which is faster than true gamma whilst still looking better than having none. You must have GAMMA defined to enable FAKE_GAMMA.
|
||||
|
||||
CURVATURE distorts the screen by CURVATURE_X and CURVATURE_Y. Curvature slows things down a lot.
|
||||
|
||||
By default the shader uses linear blending horizontally. If you find this too blury, enable SHARPER.
|
||||
|
||||
BLOOM_FACTOR controls the increase in width for bright scanlines.
|
||||
|
||||
MASK_TYPE defines what, if any, shadow mask to use. MASK_BRIGHTNESS defines how much the mask type darkens the screen.
|
||||
|
||||
*/
|
||||
|
||||
#pragma parameter CURVATURE_X "Screen curvature - horizontal" 0.10 0.0 1.0 0.01
|
||||
#pragma parameter CURVATURE_Y "Screen curvature - vertical" 0.15 0.0 1.0 0.01
|
||||
#pragma parameter MASK_BRIGHTNESS "Mask brightness" 0.70 0.0 1.0 0.01
|
||||
#pragma parameter SCANLINE_WEIGHT "Scanline weight" 6.0 0.0 15.0 0.1
|
||||
#pragma parameter SCANLINE_GAP_BRIGHTNESS "Scanline gap brightness" 0.12 0.0 1.0 0.01
|
||||
#pragma parameter BLOOM_FACTOR "Bloom factor" 1.5 0.0 5.0 0.01
|
||||
#pragma parameter INPUT_GAMMA "Input gamma" 2.4 0.0 5.0 0.01
|
||||
#pragma parameter OUTPUT_GAMMA "Output gamma" 2.2 0.0 5.0 0.01
|
||||
|
||||
// Haven't put these as parameters as it would slow the code down.
|
||||
#define SCANLINES
|
||||
#define MULTISAMPLE
|
||||
#define GAMMA
|
||||
//#define FAKE_GAMMA
|
||||
//#define CURVATURE
|
||||
//#define SHARPER
|
||||
// MASK_TYPE: 0 = none, 1 = green/magenta, 2 = trinitron(ish)
|
||||
#define MASK_TYPE 2
|
||||
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
precision mediump float;
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float CURVATURE_X;
|
||||
uniform COMPAT_PRECISION float CURVATURE_Y;
|
||||
uniform COMPAT_PRECISION float MASK_BRIGHTNESS;
|
||||
uniform COMPAT_PRECISION float SCANLINE_WEIGHT;
|
||||
uniform COMPAT_PRECISION float SCANLINE_GAP_BRIGHTNESS;
|
||||
uniform COMPAT_PRECISION float BLOOM_FACTOR;
|
||||
uniform COMPAT_PRECISION float INPUT_GAMMA;
|
||||
uniform COMPAT_PRECISION float OUTPUT_GAMMA;
|
||||
#else
|
||||
#define CURVATURE_X 0.05
|
||||
#define CURVATURE_Y 0.1
|
||||
#define MASK_BRIGHTNESS 0.80
|
||||
#define SCANLINE_WEIGHT 6.0
|
||||
#define SCANLINE_GAP_BRIGHTNESS 0.12
|
||||
#define BLOOM_FACTOR 3.5
|
||||
#define INPUT_GAMMA 2.4
|
||||
#define OUTPUT_GAMMA 2.2
|
||||
#endif
|
||||
|
||||
/* COMPATIBILITY
|
||||
- GLSL compilers
|
||||
*/
|
||||
|
||||
//uniform vec2 TextureSize;
|
||||
#if defined(CURVATURE)
|
||||
varying vec2 screenScale;
|
||||
#endif
|
||||
varying vec2 TEX0;
|
||||
varying float filterWidth;
|
||||
|
||||
#if defined(VERTEX)
|
||||
//uniform mat4 MVPMatrix;
|
||||
//attribute vec4 VertexCoord;
|
||||
//attribute vec2 TexCoord;
|
||||
//uniform vec2 InputSize;
|
||||
//uniform vec2 OutputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(CURVATURE)
|
||||
screenScale = vec2(1.0, 1.0); //TextureSize / InputSize;
|
||||
#endif
|
||||
filterWidth = (768.0 / 240.0) / 3.0;
|
||||
TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
uniform sampler2D Texture;
|
||||
|
||||
#if defined(CURVATURE)
|
||||
vec2 Distort(vec2 coord)
|
||||
{
|
||||
vec2 CURVATURE_DISTORTION = vec2(CURVATURE_X, CURVATURE_Y);
|
||||
// Barrel distortion shrinks the display area a bit, this will allow us to counteract that.
|
||||
vec2 barrelScale = 1.0 - (0.23 * CURVATURE_DISTORTION);
|
||||
coord *= screenScale;
|
||||
coord -= vec2(0.5);
|
||||
float rsq = coord.x * coord.x + coord.y * coord.y;
|
||||
coord += coord * (CURVATURE_DISTORTION * rsq);
|
||||
coord *= barrelScale;
|
||||
if (abs(coord.x) >= 0.5 || abs(coord.y) >= 0.5)
|
||||
coord = vec2(-1.0); // If out of bounds, return an invalid value.
|
||||
else
|
||||
{
|
||||
coord += vec2(0.5);
|
||||
coord /= screenScale;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
#endif
|
||||
|
||||
float CalcScanLineWeight(float dist)
|
||||
{
|
||||
return max(1.0-dist*dist*SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS);
|
||||
}
|
||||
|
||||
float CalcScanLine(float dy)
|
||||
{
|
||||
float scanLineWeight = CalcScanLineWeight(dy);
|
||||
#if defined(MULTISAMPLE)
|
||||
scanLineWeight += CalcScanLineWeight(dy-filterWidth);
|
||||
scanLineWeight += CalcScanLineWeight(dy+filterWidth);
|
||||
scanLineWeight *= 0.3333333;
|
||||
#endif
|
||||
return scanLineWeight;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 TextureSize = vec2(320.0, 240.0);
|
||||
#if defined(CURVATURE)
|
||||
vec2 texcoord = Distort(TEX0);
|
||||
if (texcoord.x < 0.0)
|
||||
gl_FragColor = vec4(0.0);
|
||||
else
|
||||
#else
|
||||
vec2 texcoord = TEX0;
|
||||
#endif
|
||||
{
|
||||
vec2 texcoordInPixels = texcoord * TextureSize;
|
||||
#if defined(SHARPER)
|
||||
vec2 tempCoord = floor(texcoordInPixels) + 0.5;
|
||||
vec2 coord = tempCoord / TextureSize;
|
||||
vec2 deltas = texcoordInPixels - tempCoord;
|
||||
float scanLineWeight = CalcScanLine(deltas.y);
|
||||
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 /= TextureSize;
|
||||
deltas *= signs;
|
||||
vec2 tc = coord + deltas;
|
||||
#else
|
||||
float tempY = floor(texcoordInPixels.y) + 0.5;
|
||||
float yCoord = tempY / TextureSize.y;
|
||||
float dy = texcoordInPixels.y - tempY;
|
||||
float scanLineWeight = CalcScanLine(dy);
|
||||
float signY = sign(dy);
|
||||
dy = dy * dy;
|
||||
dy = dy * dy;
|
||||
dy *= 8.0;
|
||||
dy /= TextureSize.y;
|
||||
dy *= signY;
|
||||
vec2 tc = vec2(texcoord.x, yCoord + dy);
|
||||
#endif
|
||||
|
||||
vec3 colour = texture2D(Texture, tc).rgb;
|
||||
|
||||
#if defined(SCANLINES)
|
||||
#if defined(GAMMA)
|
||||
#if defined(FAKE_GAMMA)
|
||||
colour = colour * colour;
|
||||
#else
|
||||
colour = pow(colour, vec3(INPUT_GAMMA));
|
||||
#endif
|
||||
#endif
|
||||
scanLineWeight *= BLOOM_FACTOR;
|
||||
colour *= scanLineWeight;
|
||||
|
||||
#if defined(GAMMA)
|
||||
#if defined(FAKE_GAMMA)
|
||||
colour = sqrt(colour);
|
||||
#else
|
||||
colour = pow(colour, vec3(1.0/OUTPUT_GAMMA));
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if MASK_TYPE == 0
|
||||
gl_FragColor = vec4(colour, 1.0);
|
||||
#else
|
||||
#if MASK_TYPE == 1
|
||||
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.5);
|
||||
vec3 mask;
|
||||
if (whichMask < 0.5)
|
||||
mask = vec3(MASK_BRIGHTNESS, 1.0, MASK_BRIGHTNESS);
|
||||
else
|
||||
mask = vec3(1.0, MASK_BRIGHTNESS, 1.0);
|
||||
#elif MASK_TYPE == 2
|
||||
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.3333333);
|
||||
vec3 mask = vec3(MASK_BRIGHTNESS, MASK_BRIGHTNESS, MASK_BRIGHTNESS);
|
||||
if (whichMask < 0.3333333)
|
||||
mask.x = 1.0;
|
||||
else if (whichMask < 0.6666666)
|
||||
mask.y = 1.0;
|
||||
else
|
||||
mask.z = 1.0;
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4(colour * mask, 1.0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
crt-pi - A Raspberry Pi friendly CRT shader.
|
||||
|
||||
Copyright (C) 2015-2016 davej
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
This shader is designed to work well on Raspberry Pi GPUs (i.e. 1080P @ 60Hz on a game with a 4:3 aspect ratio). It pushes the Pi's GPU hard and enabling some features will slow it down so that it is no longer able to match 1080P @ 60Hz. You will need to overclock your Pi to the fastest setting in raspi-config to get the best results from this shader: 'Pi2' for Pi2 and 'Turbo' for original Pi and Pi Zero. Note: Pi2s are slower at running the shader than other Pis, this seems to be down to Pi2s lower maximum memory speed. Pi2s don't quite manage 1080P @ 60Hz - they drop about 1 in 1000 frames. You probably won't notice this, but if you do, try enabling FAKE_GAMMA.
|
||||
|
||||
SCANLINES enables scanlines. You'll almost certainly want to use it with MULTISAMPLE to reduce moire effects. SCANLINE_WEIGHT defines how wide scanlines are (it is an inverse value so a higher number = thinner lines). SCANLINE_GAP_BRIGHTNESS defines how dark the gaps between the scan lines are. Darker gaps between scan lines make moire effects more likely.
|
||||
|
||||
GAMMA enables gamma correction using the values in INPUT_GAMMA and OUTPUT_GAMMA. FAKE_GAMMA causes it to ignore the values in INPUT_GAMMA and OUTPUT_GAMMA and approximate gamma correction in a way which is faster than true gamma whilst still looking better than having none. You must have GAMMA defined to enable FAKE_GAMMA.
|
||||
|
||||
CURVATURE distorts the screen by CURVATURE_X and CURVATURE_Y. Curvature slows things down a lot.
|
||||
|
||||
By default the shader uses linear blending horizontally. If you find this too blury, enable SHARPER.
|
||||
|
||||
BLOOM_FACTOR controls the increase in width for bright scanlines.
|
||||
|
||||
MASK_TYPE defines what, if any, shadow mask to use. MASK_BRIGHTNESS defines how much the mask type darkens the screen.
|
||||
|
||||
*/
|
||||
|
||||
#pragma parameter CURVATURE_X "Screen curvature - horizontal" 0.10 0.0 1.0 0.01
|
||||
#pragma parameter CURVATURE_Y "Screen curvature - vertical" 0.15 0.0 1.0 0.01
|
||||
#pragma parameter MASK_BRIGHTNESS "Mask brightness" 0.70 0.0 1.0 0.01
|
||||
#pragma parameter SCANLINE_WEIGHT "Scanline weight" 6.0 0.0 15.0 0.1
|
||||
#pragma parameter SCANLINE_GAP_BRIGHTNESS "Scanline gap brightness" 0.12 0.0 1.0 0.01
|
||||
#pragma parameter BLOOM_FACTOR "Bloom factor" 1.5 0.0 5.0 0.01
|
||||
#pragma parameter INPUT_GAMMA "Input gamma" 2.4 0.0 5.0 0.01
|
||||
#pragma parameter OUTPUT_GAMMA "Output gamma" 2.2 0.0 5.0 0.01
|
||||
|
||||
// Haven't put these as parameters as it would slow the code down.
|
||||
#define SCANLINES
|
||||
#define MULTISAMPLE
|
||||
#define GAMMA
|
||||
//#define FAKE_GAMMA
|
||||
//#define CURVATURE
|
||||
//#define SHARPER
|
||||
// MASK_TYPE: 0 = none, 1 = green/magenta, 2 = trinitron(ish)
|
||||
#define MASK_TYPE 2
|
||||
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
precision mediump float;
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float CURVATURE_X;
|
||||
uniform COMPAT_PRECISION float CURVATURE_Y;
|
||||
uniform COMPAT_PRECISION float MASK_BRIGHTNESS;
|
||||
uniform COMPAT_PRECISION float SCANLINE_WEIGHT;
|
||||
uniform COMPAT_PRECISION float SCANLINE_GAP_BRIGHTNESS;
|
||||
uniform COMPAT_PRECISION float BLOOM_FACTOR;
|
||||
uniform COMPAT_PRECISION float INPUT_GAMMA;
|
||||
uniform COMPAT_PRECISION float OUTPUT_GAMMA;
|
||||
#else
|
||||
#define CURVATURE_X 0.05
|
||||
#define CURVATURE_Y 0.1
|
||||
#define MASK_BRIGHTNESS 0.80
|
||||
#define SCANLINE_WEIGHT 6.0
|
||||
#define SCANLINE_GAP_BRIGHTNESS 0.12
|
||||
#define BLOOM_FACTOR 3.5
|
||||
#define INPUT_GAMMA 2.4
|
||||
#define OUTPUT_GAMMA 2.2
|
||||
#endif
|
||||
|
||||
/* COMPATIBILITY
|
||||
- GLSL compilers
|
||||
*/
|
||||
|
||||
//uniform vec2 TextureSize;
|
||||
#if defined(CURVATURE)
|
||||
varying vec2 screenScale;
|
||||
#endif
|
||||
varying vec2 TEX0;
|
||||
varying float filterWidth;
|
||||
|
||||
#if defined(VERTEX)
|
||||
//uniform mat4 MVPMatrix;
|
||||
//attribute vec4 VertexCoord;
|
||||
//attribute vec2 TexCoord;
|
||||
//uniform vec2 InputSize;
|
||||
//uniform vec2 OutputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(CURVATURE)
|
||||
screenScale = vec2(1.0, 1.0); //TextureSize / InputSize;
|
||||
#endif
|
||||
filterWidth = (768.0 / 256.0) / 3.0;
|
||||
TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
uniform sampler2D Texture;
|
||||
|
||||
#if defined(CURVATURE)
|
||||
vec2 Distort(vec2 coord)
|
||||
{
|
||||
vec2 CURVATURE_DISTORTION = vec2(CURVATURE_X, CURVATURE_Y);
|
||||
// Barrel distortion shrinks the display area a bit, this will allow us to counteract that.
|
||||
vec2 barrelScale = 1.0 - (0.23 * CURVATURE_DISTORTION);
|
||||
coord *= screenScale;
|
||||
coord -= vec2(0.5);
|
||||
float rsq = coord.x * coord.x + coord.y * coord.y;
|
||||
coord += coord * (CURVATURE_DISTORTION * rsq);
|
||||
coord *= barrelScale;
|
||||
if (abs(coord.x) >= 0.5 || abs(coord.y) >= 0.5)
|
||||
coord = vec2(-1.0); // If out of bounds, return an invalid value.
|
||||
else
|
||||
{
|
||||
coord += vec2(0.5);
|
||||
coord /= screenScale;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
#endif
|
||||
|
||||
float CalcScanLineWeight(float dist)
|
||||
{
|
||||
return max(1.0-dist*dist*SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS);
|
||||
}
|
||||
|
||||
float CalcScanLine(float dy)
|
||||
{
|
||||
float scanLineWeight = CalcScanLineWeight(dy);
|
||||
#if defined(MULTISAMPLE)
|
||||
scanLineWeight += CalcScanLineWeight(dy-filterWidth);
|
||||
scanLineWeight += CalcScanLineWeight(dy+filterWidth);
|
||||
scanLineWeight *= 0.3333333;
|
||||
#endif
|
||||
return scanLineWeight;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 TextureSize = vec2(320.0, 256.0);
|
||||
#if defined(CURVATURE)
|
||||
vec2 texcoord = Distort(TEX0);
|
||||
if (texcoord.x < 0.0)
|
||||
gl_FragColor = vec4(0.0);
|
||||
else
|
||||
#else
|
||||
vec2 texcoord = TEX0;
|
||||
#endif
|
||||
{
|
||||
vec2 texcoordInPixels = texcoord * TextureSize;
|
||||
#if defined(SHARPER)
|
||||
vec2 tempCoord = floor(texcoordInPixels) + 0.5;
|
||||
vec2 coord = tempCoord / TextureSize;
|
||||
vec2 deltas = texcoordInPixels - tempCoord;
|
||||
float scanLineWeight = CalcScanLine(deltas.y);
|
||||
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 /= TextureSize;
|
||||
deltas *= signs;
|
||||
vec2 tc = coord + deltas;
|
||||
#else
|
||||
float tempY = floor(texcoordInPixels.y) + 0.5;
|
||||
float yCoord = tempY / TextureSize.y;
|
||||
float dy = texcoordInPixels.y - tempY;
|
||||
float scanLineWeight = CalcScanLine(dy);
|
||||
float signY = sign(dy);
|
||||
dy = dy * dy;
|
||||
dy = dy * dy;
|
||||
dy *= 8.0;
|
||||
dy /= TextureSize.y;
|
||||
dy *= signY;
|
||||
vec2 tc = vec2(texcoord.x, yCoord + dy);
|
||||
#endif
|
||||
|
||||
vec3 colour = texture2D(Texture, tc).rgb;
|
||||
|
||||
#if defined(SCANLINES)
|
||||
#if defined(GAMMA)
|
||||
#if defined(FAKE_GAMMA)
|
||||
colour = colour * colour;
|
||||
#else
|
||||
colour = pow(colour, vec3(INPUT_GAMMA));
|
||||
#endif
|
||||
#endif
|
||||
scanLineWeight *= BLOOM_FACTOR;
|
||||
colour *= scanLineWeight;
|
||||
|
||||
#if defined(GAMMA)
|
||||
#if defined(FAKE_GAMMA)
|
||||
colour = sqrt(colour);
|
||||
#else
|
||||
colour = pow(colour, vec3(1.0/OUTPUT_GAMMA));
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if MASK_TYPE == 0
|
||||
gl_FragColor = vec4(colour, 1.0);
|
||||
#else
|
||||
#if MASK_TYPE == 1
|
||||
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.5);
|
||||
vec3 mask;
|
||||
if (whichMask < 0.5)
|
||||
mask = vec3(MASK_BRIGHTNESS, 1.0, MASK_BRIGHTNESS);
|
||||
else
|
||||
mask = vec3(1.0, MASK_BRIGHTNESS, 1.0);
|
||||
#elif MASK_TYPE == 2
|
||||
float whichMask = fract((gl_FragCoord.x*1.0001) * 0.3333333);
|
||||
vec3 mask = vec3(MASK_BRIGHTNESS, MASK_BRIGHTNESS, MASK_BRIGHTNESS);
|
||||
if (whichMask < 0.3333333)
|
||||
mask.x = 1.0;
|
||||
else if (whichMask < 0.6666666)
|
||||
mask.y = 1.0;
|
||||
else
|
||||
mask.z = 1.0;
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4(colour * mask, 1.0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
BIN
data/sound/bullet2p.wav
Normal file
BIN
data/sound/name_input_accept.wav
Normal file
BIN
data/sound/voice_game_over.wav
Normal file
@@ -1,75 +0,0 @@
|
||||
# Plan de Limpieza Post-Migración DeltaTime
|
||||
|
||||
## Estado Actual
|
||||
✅ Migración básica completada: bullet.cpp, item.cpp, moving_sprite.cpp, game_logo.cpp
|
||||
✅ Magic numbers convertidos a constantes en game_logo.cpp
|
||||
|
||||
## Tareas Pendientes
|
||||
|
||||
### 1. Eliminar Contadores Frame-Based
|
||||
- [ ] Buscar todos los contadores que usen lógica frame-based
|
||||
- [ ] Convertir a timers basados en deltaTime
|
||||
- [ ] Eliminar variables como `counter_`, `frame_counter_`, etc.
|
||||
- [ ] Patrón: `if (counter-- <= 0)` → `if (timer >= DURATION_MS)`
|
||||
- [ ] **IMPORTANTE**: Todos los contadores han de ser crecientes, de cero hasta llegar a la constante que define su tope
|
||||
|
||||
### 2. Revisar Inicializaciones de Aceleraciones MovingSprite
|
||||
- [ ] Buscar todas las llamadas a `setAccelX()`, `setAccelY()`
|
||||
- [ ] Buscar asignaciones directas a `ax_`, `ay_`
|
||||
- [ ] Convertir de `pixels/frame²` a `pixels/ms²`
|
||||
- [ ] Factor de conversión: `valor_original / (16.67)²`
|
||||
|
||||
### 3. Problema Detectado: Demo - Creación Incorrecta de Globos
|
||||
- [ ] Investigar cómo se crean los globos en modo demo
|
||||
- [ ] Verificar si usan timing frame-based obsoleto
|
||||
- [ ] Corregir la lógica de creación para deltaTime
|
||||
|
||||
### 4. Búsqueda de Patrones Problemáticos
|
||||
- [ ] Buscar `frameFactor` residual
|
||||
- [ ] Buscar `1000.0f / 60.0f` hardcodeado
|
||||
- [ ] Buscar `16.67f` hardcodeado
|
||||
- [ ] Buscar comentarios con "frame" o "60fps"
|
||||
- [ ] Localizar magic numbers y convertirlos a constantes con nombres descriptivos
|
||||
- [ ] **IMPORTANTE**: Modificar speed en ficheros .ani - está en frames, hay que pasarlo a milisegundos (multiplicar speed por 1000/60 = 16.67)
|
||||
- [ ] **SmartSprite**: Revisar inicialización de SmartSprites en el código - cambiar setFinishedCounter() a setFinishedDelay() y convertir valores de frames a milisegundos
|
||||
|
||||
### 5. Cambio de Unidades de Tiempo en sections/*
|
||||
- [ ] Cambiar el cálculo de deltatime en source/sections/* para que devuelva segundos (float) en lugar de milisegundos
|
||||
- [ ] Cambiar velocidades de pixeles/ms a pixeles/segundos para evitar valores absurdamente pequeños
|
||||
- [ ] Cambiar aceleraciones de pixeles/ms² a pixeles/segundos²
|
||||
- [ ] Actualizar todas las constantes de tiempo en archivos de sections
|
||||
|
||||
### 6. Archivos Prioritarios a Revisar
|
||||
- [ ] **player.cpp** - puede tener aceleraciones
|
||||
- [ ] **balloon.cpp** - contadores de estado
|
||||
- [ ] **stage.cpp** - timers de nivel
|
||||
- [ ] **credits.cpp** - efectos de texto
|
||||
- [ ] **tabe.cpp** - movimiento del protagonista
|
||||
- [ ] **sections/*.cpp** - transiciones y efectos
|
||||
|
||||
### 7. Validación Final
|
||||
- [ ] Compilar sin warnings
|
||||
- [ ] Probar gameplay normal
|
||||
- [ ] Probar modo demo
|
||||
- [ ] Verificar que no hay saltos de velocidad
|
||||
- [ ] Confirmar que el timing es consistente en diferentes framerates
|
||||
|
||||
## Comandos Útiles de Búsqueda
|
||||
```bash
|
||||
# Buscar contadores frame-based
|
||||
rg "counter.*--|\+\+.*counter|counter.*\+\+|--.*counter"
|
||||
|
||||
# Buscar inicializaciones de aceleración
|
||||
rg "setAccel|\.ax.*=|\.ay.*="
|
||||
|
||||
# Buscar hardcoded framerates
|
||||
rg "60\.0|16\.67|1000\.0.*60"
|
||||
```
|
||||
|
||||
## Notas
|
||||
- **Para archivos sections/***: velocidades en `pixels/segundos`, aceleraciones en `pixels/segundos²`
|
||||
- **Para resto del código**: mantener velocidades en `pixels/ms`, aceleraciones en `pixels/ms²`
|
||||
- Todos los contadores deben ser crecientes (0 → constante_tope)
|
||||
- Documentar las conversiones en comentarios
|
||||
- Crear constantes para valores repetidos
|
||||
- Evitar números mágicos
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SECONDS=0
|
||||
make linux_debug
|
||||
duration=$SECONDS
|
||||
echo "$((duration / 60)) minutes and $((duration % 60)) seconds elapsed."
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCEPATH=../source/
|
||||
|
||||
for i in "$SOURCEPATH"/*.cpp
|
||||
do
|
||||
include-what-you-use -D _DEBUG -std=c++20 -Wall "$i"
|
||||
done
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCEPATH=../source/
|
||||
|
||||
for i in "$SOURCEPATH"/*.cpp
|
||||
do
|
||||
include-what-you-use -D DEBUG -std=c++20 -Wall "$i"
|
||||
read -r -p "Presiona cualquier tecla para continuar..."
|
||||
clear
|
||||
done
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Verifica que se haya proporcionado un archivo como argumento
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Uso: $0 <archivo.cpp>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILE="$1"
|
||||
|
||||
include-what-you-use -D _DEBUG -std=c++20 -Wall "$FILE" \
|
||||
-I../source \
|
||||
-Xiwyu --mapping_file=sdl3_mapping.imp \
|
||||
-Xiwyu --update_comments \
|
||||
-Xiwyu --verbose=3
|
||||
@@ -1,8 +0,0 @@
|
||||
# Per a un fitxer, desde l'arrel del projecte executar:
|
||||
clang-tidy source/fitxer.cpp -p build/ --fix
|
||||
|
||||
# Per a varios fitxers, desde l'arrel:
|
||||
find source/ \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | \
|
||||
xargs -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p build/ --fix'
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/stb*
|
||||
*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/gif.c
|
||||
*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/jail*
|
||||
*:/usr/include/*
|
||||
*:../source/stb*
|
||||
*:../source/gif.c
|
||||
*:../source/jail*
|
||||
*:/usr/include/*
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🏁 Ruta base del proyecto
|
||||
BASE_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition"
|
||||
|
||||
# 📁 Ruta al build
|
||||
BUILD_DIR="$BASE_DIR/build"
|
||||
|
||||
# 📄 Archivo de mapping personalizado
|
||||
MAPPING_FILE="$BASE_DIR/linux_utils/sdl3_mapping.imp"
|
||||
|
||||
# 📦 Generar compile_commands.json
|
||||
echo "🔧 Generando compile_commands.json..."
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR"
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script para ejecutar clang-tidy en múltiples directorios
|
||||
# Uso: ./run_clang-tidy.sh
|
||||
|
||||
# Lista de rutas donde ejecutar clang-tidy
|
||||
PATHS=(
|
||||
"/home/sergio/gitea/coffee_crisis_arcade_edition/source"
|
||||
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/sections"
|
||||
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/ui"
|
||||
)
|
||||
|
||||
# Ruta del directorio build (relativa desde donde se ejecuta el script)
|
||||
BUILD_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition/build/"
|
||||
|
||||
# Función para procesar un directorio
|
||||
process_directory() {
|
||||
local dir="$1"
|
||||
|
||||
echo "=== Procesando directorio: $dir ==="
|
||||
|
||||
# Verificar que el directorio existe
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
echo "Error: El directorio $dir no existe"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Cambiar al directorio y ejecutar find con -maxdepth 1 para un solo nivel
|
||||
cd "$dir" || return 1
|
||||
|
||||
# Buscar archivos .cpp, .h, .hpp solo en el nivel actual (no subdirectorios)
|
||||
find . -maxdepth 1 \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | \
|
||||
xargs -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' --fix'
|
||||
|
||||
echo "=== Completado: $dir ==="
|
||||
echo
|
||||
}
|
||||
|
||||
# Procesar cada directorio en la lista
|
||||
for path in "${PATHS[@]}"; do
|
||||
process_directory "$path"
|
||||
done
|
||||
|
||||
echo "¡Proceso completado para todos los directorios!"
|
||||
@@ -1,54 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Función para mostrar el uso del script
|
||||
mostrar_uso() {
|
||||
echo "Uso: $0 [-o opción]"
|
||||
echo "Opciones:"
|
||||
echo " w Ejecutar cppcheck con warning, style, performance"
|
||||
echo " a Ejecutar cppcheck con todas las opciones habilitadas"
|
||||
echo " u Ejecutar cppcheck para unusedFunction"
|
||||
}
|
||||
|
||||
# Inicializar las variables
|
||||
opcion=""
|
||||
|
||||
# Procesar las opciones
|
||||
while getopts "o:" opt; do
|
||||
case $opt in
|
||||
o)
|
||||
opcion=$OPTARG
|
||||
;;
|
||||
*)
|
||||
mostrar_uso
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Ejecutar según la opción seleccionada
|
||||
case $opcion in
|
||||
w)
|
||||
cppcheck --force --enable=warning,style,performance --std=c++20 \
|
||||
--check-level=exhaustive \
|
||||
--suppressions-list=./cppcheck_suppressions \
|
||||
../source/ \
|
||||
2>./cppcheck-result-warning-style-performance.txt
|
||||
;;
|
||||
a)
|
||||
cppcheck --force --enable=all -I /usr/include --std=c++20 \
|
||||
--suppress=missingIncludeSystem \
|
||||
--suppressions-list=./cppcheck_suppressions \
|
||||
../source/ \
|
||||
2>./cppcheck-result-all.txt
|
||||
;;
|
||||
u)
|
||||
cppcheck --enable=style --std=c++20 \
|
||||
--suppressions-list=./cppcheck_suppressions \
|
||||
../source/ \
|
||||
2>./cppcheck-result-unusedFunction.txt
|
||||
;;
|
||||
*)
|
||||
mostrar_uso
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🏁 Ruta base del proyecto
|
||||
BASE_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition"
|
||||
|
||||
# 📁 Ruta al build
|
||||
BUILD_DIR="$BASE_DIR/build"
|
||||
|
||||
# 📄 Archivo de mapping personalizado
|
||||
MAPPING_FILE="$BASE_DIR/linux_utils/sdl3_mapping.imp"
|
||||
|
||||
# 📦 Generar compile_commands.json
|
||||
echo "🔧 Generando compile_commands.json..."
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR"
|
||||
|
||||
# 🛠️ Ejecutar IWYU con fix_includes.py
|
||||
echo "🚀 Ejecutando IWYU..."
|
||||
iwyu_tool.py -p "$BUILD_DIR" -- -Xiwyu --mapping_file="$MAPPING_FILE" -Xiwyu --verbose=3 \
|
||||
| python3 /usr/bin/fix_includes.py --update_comments --reorder --nosafe_headers
|
||||
|
||||
# 🧹 Reemplazar // for por // Para en líneas de #include
|
||||
echo "✍️ Corrigiendo comentarios en includes..."
|
||||
find "$BASE_DIR" -type f \( -name "*.cpp" -o -name "*.h" \) -exec \
|
||||
sed -i '/^#include .*\/\/ for/s/\/\/ for/\/\/ Para/' {} +
|
||||
|
||||
echo "✅ Script completado."
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🏁 Ruta base del proyecto
|
||||
BASE_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition"
|
||||
|
||||
# 📁 Ruta al build
|
||||
BUILD_DIR="$BASE_DIR/build"
|
||||
|
||||
# 📄 Archivo de mapping personalizado
|
||||
MAPPING_FILE="$BASE_DIR/linux_utils/sdl3_mapping.imp"
|
||||
|
||||
# 📦 Generar compile_commands.json
|
||||
echo "🔧 Generando compile_commands.json..."
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S "$BASE_DIR" -B "$BUILD_DIR"
|
||||
|
||||
# 🛠️ Ejecutar IWYU con fix_includes.py
|
||||
echo "🚀 Ejecutando IWYU..."
|
||||
iwyu_tool.py -p "$BUILD_DIR" -- -Xiwyu --mapping_file="$MAPPING_FILE" -Xiwyu --verbose=3 \
|
||||
| python3 /usr/bin/fix_includes.py --update_comments --reorder --nosafe_headers --dry_run
|
||||
|
||||
# 🧹 Reemplazar // for por // Para en líneas de #include
|
||||
echo "✍️ Corrigiendo comentarios en includes..."
|
||||
find "$BASE_DIR" -type f \( -name "*.cpp" -o -name "*.h" \) -exec \
|
||||
sed -i '/^#include .*\/\/ for/s/\/\/ for/\/\/ Para/' {} +
|
||||
|
||||
echo "✅ Script completado."
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
valgrind --suppressions=valgrind_exceptions \
|
||||
--leak-check=full \
|
||||
~/gitea/coffee_crisis_arcade_edition/coffee_crisis_arcade_edition \
|
||||
> ~/gitea/coffee_crisis_arcade_edition/linux_utils/valgrind_out.txt 2>&1
|
||||
@@ -1,57 +0,0 @@
|
||||
[
|
||||
{ "include": ["<SDL3/SDL_stdinc.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_assert.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_asyncio.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_atomic.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_audio.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_bits.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_blendmode.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_camera.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_clipboard.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_cpuinfo.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_dialog.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_endian.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_error.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_events.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_filesystem.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_gamepad.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_gpu.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_guid.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_haptic.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_hidapi.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_hints.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_init.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_iostream.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_joystick.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_keyboard.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_keycode.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_loadso.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_locale.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_log.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_messagebox.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_metal.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_misc.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_mouse.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_mutex.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_pen.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_pixels.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_platform.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_power.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_process.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_properties.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_rect.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_render.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_scancode.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_sensor.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_storage.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_surface.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_system.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_thread.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_time.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_timer.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_tray.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_touch.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_version.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_video.h>", "private", "<SDL3/SDL.h>", "public"] },
|
||||
{ "include": ["<SDL3/SDL_oldnames.h>", "private", "<SDL3/SDL.h>", "public"] }
|
||||
]
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
@@ -1,12 +0,0 @@
|
||||
{
|
||||
ignore_unversioned_libs
|
||||
Memcheck:Leak
|
||||
...
|
||||
obj:*/lib*/lib*.so
|
||||
}
|
||||
{
|
||||
ignore_versioned_libs
|
||||
Memcheck:Leak
|
||||
...
|
||||
obj:*/lib*/lib*.so.*
|
||||
}
|
||||
BIN
release/arcade/splash.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
@@ -1,106 +0,0 @@
|
||||
# SDL3 CMake configuration file:
|
||||
# This file is meant to be placed in Resources/CMake of a SDL3 framework
|
||||
|
||||
# INTERFACE_LINK_OPTIONS needs CMake 3.12
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
include(FeatureSummary)
|
||||
set_package_properties(SDL3 PROPERTIES
|
||||
URL "https://www.libsdl.org/"
|
||||
DESCRIPTION "low level access to audio, keyboard, mouse, joystick, and graphics hardware"
|
||||
)
|
||||
|
||||
# Copied from `configure_package_config_file`
|
||||
macro(set_and_check _var _file)
|
||||
set(${_var} "${_file}")
|
||||
if(NOT EXISTS "${_file}")
|
||||
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Copied from `configure_package_config_file`
|
||||
macro(check_required_components _NAME)
|
||||
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||
if(NOT ${_NAME}_${comp}_FOUND)
|
||||
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
set(SDL3_FOUND TRUE)
|
||||
|
||||
# Compute the installation prefix relative to this file.
|
||||
set(_sdl3_framework_path "${CMAKE_CURRENT_LIST_DIR}") # > /SDL3.framework/Resources/CMake/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" REALPATH) # > /SDL3.framework/Versions/Current/Resources/CMake
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" REALPATH) # > /SDL3.framework/Versions/A/Resources/CMake/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/Versions/A/Resources/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/Versions/A/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/Versions/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/
|
||||
get_filename_component(_sdl3_framework_parent_path "${_sdl3_framework_path}" PATH) # > /
|
||||
|
||||
|
||||
# All targets are created, even when some might not be requested though COMPONENTS.
|
||||
# This is done for compatibility with CMake generated SDL3-target.cmake files.
|
||||
|
||||
if(NOT TARGET SDL3::Headers)
|
||||
add_library(SDL3::Headers INTERFACE IMPORTED)
|
||||
set_target_properties(SDL3::Headers
|
||||
PROPERTIES
|
||||
INTERFACE_COMPILE_OPTIONS "SHELL:-F \"${_sdl3_framework_parent_path}\""
|
||||
)
|
||||
endif()
|
||||
set(SDL3_Headers_FOUND TRUE)
|
||||
|
||||
if(NOT TARGET SDL3::SDL3-shared)
|
||||
add_library(SDL3::SDL3-shared SHARED IMPORTED)
|
||||
set_target_properties(SDL3::SDL3-shared
|
||||
PROPERTIES
|
||||
FRAMEWORK "TRUE"
|
||||
IMPORTED_LOCATION "${_sdl3_framework_path}/SDL3"
|
||||
INTERFACE_LINK_LIBRARIES "SDL3::Headers"
|
||||
COMPATIBLE_INTERFACE_BOOL "SDL3_SHARED"
|
||||
INTERFACE_SDL3_SHARED "ON"
|
||||
COMPATIBLE_INTERFACE_STRING "SDL_VERSION"
|
||||
INTERFACE_SDL_VERSION "SDL3"
|
||||
)
|
||||
endif()
|
||||
set(SDL3_SDL3-shared_FOUND TRUE)
|
||||
|
||||
set(SDL3_SDL3-static FALSE)
|
||||
|
||||
set(SDL3_SDL3_test FALSE)
|
||||
|
||||
unset(_sdl3_framework_parent_path)
|
||||
unset(_sdl3_framework_path)
|
||||
|
||||
if(SDL3_SDL3-shared_FOUND)
|
||||
set(SDL3_SDL3_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
function(_sdl_create_target_alias_compat NEW_TARGET TARGET)
|
||||
if(CMAKE_VERSION VERSION_LESS "3.18")
|
||||
# Aliasing local targets is not supported on CMake < 3.18, so make it global.
|
||||
add_library(${NEW_TARGET} INTERFACE IMPORTED)
|
||||
set_target_properties(${NEW_TARGET} PROPERTIES INTERFACE_LINK_LIBRARIES "${TARGET}")
|
||||
else()
|
||||
add_library(${NEW_TARGET} ALIAS ${TARGET})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Make sure SDL3::SDL3 always exists
|
||||
if(NOT TARGET SDL3::SDL3)
|
||||
if(TARGET SDL3::SDL3-shared)
|
||||
_sdl_create_target_alias_compat(SDL3::SDL3 SDL3::SDL3-shared)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_required_components(SDL3)
|
||||
|
||||
set(SDL3_LIBRARIES SDL3::SDL3)
|
||||
set(SDL3_STATIC_LIBRARIES SDL3::SDL3-static)
|
||||
set(SDL3_STATIC_PRIVATE_LIBS)
|
||||
|
||||
set(SDL3TEST_LIBRARY SDL3::SDL3_test)
|
||||
@@ -1,57 +0,0 @@
|
||||
# based on the files generated by CMake's write_basic_package_version_file
|
||||
|
||||
# SDL CMake version configuration file:
|
||||
# This file is meant to be placed in Resources/CMake of a SDL3 framework
|
||||
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/../../Headers/SDL_version.h")
|
||||
message(AUTHOR_WARNING "Could not find SDL_version.h. This script is meant to be placed in the Resources/CMake directory of SDL2.framework")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/../../Headers/SDL_version.h" _sdl_version_h)
|
||||
string(REGEX MATCH "#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)" _sdl_major_re "${_sdl_version_h}")
|
||||
set(_sdl_major "${CMAKE_MATCH_1}")
|
||||
string(REGEX MATCH "#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)" _sdl_minor_re "${_sdl_version_h}")
|
||||
set(_sdl_minor "${CMAKE_MATCH_1}")
|
||||
string(REGEX MATCH "#define[ \t]+SDL_MICRO_VERSION[ \t]+([0-9]+)" _sdl_micro_re "${_sdl_version_h}")
|
||||
set(_sdl_micro "${CMAKE_MATCH_1}")
|
||||
if(_sdl_major_re AND _sdl_minor_re AND _sdl_micro_re)
|
||||
set(PACKAGE_VERSION "${_sdl_major}.${_sdl_minor}.${_sdl_micro}")
|
||||
else()
|
||||
message(AUTHOR_WARNING "Could not extract version from SDL_version.h.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
unset(_sdl_major_re)
|
||||
unset(_sdl_major)
|
||||
unset(_sdl_minor_re)
|
||||
unset(_sdl_minor)
|
||||
unset(_sdl_micro_re)
|
||||
unset(_sdl_micro)
|
||||
|
||||
if(PACKAGE_FIND_VERSION_RANGE)
|
||||
# Package version must be in the requested version range
|
||||
if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN)
|
||||
OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX)
|
||||
OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX)))
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
endif()
|
||||
else()
|
||||
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The SDL3.xcframework only contains 64-bit archives
|
||||
if(NOT "${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
endif()
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
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_ */
|
||||
@@ -1,662 +0,0 @@
|
||||
/*
|
||||
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_ */
|
||||
@@ -1,546 +0,0 @@
|
||||
/*
|
||||
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_ */
|
||||
@@ -1,664 +0,0 @@
|
||||
/*
|
||||
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_ */
|
||||