Compare commits
364 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 817c8fc8a0 | |||
| 3fe8fa9b32 | |||
| 65f710bf7a | |||
| 72302554ae | |||
| 03530d0439 | |||
| 705d32e919 | |||
| e420db2896 | |||
| 785700f819 | |||
| 07863577bc | |||
| 8a341be027 | |||
| 93fb914e54 | |||
| 8d659c44e5 | |||
| 5407f66c9e | |||
| dd91b07a14 | |||
| fc8233ef57 | |||
| ef2c13b011 | |||
| 69e337393a | |||
| 56c3f978d3 | |||
| cb958f33ba | |||
| e3d12e6e27 | |||
| 47e9d85708 | |||
| 82027e4975 | |||
| ab06cb32c9 | |||
| 9e7061d8b7 | |||
| b4b95c883f | |||
| a46b93c917 | |||
| 8d18c50aaa | |||
| b412435862 | |||
| 5b90a9a767 | |||
| 5ba562178b | |||
| 55b37ba594 | |||
| 20825c8138 | |||
| 9235e684e8 | |||
| 0350063fb7 | |||
| 56065995fd | |||
| 17e9206d26 | |||
| 462e91d967 | |||
| 3bc87ad652 | |||
| a7233e13df | |||
| 0abd661905 | |||
| a808226481 | |||
| 317e2a3fd9 | |||
| e4f8f586d6 | |||
| 6f29731679 | |||
| d7a9bd4ab2 | |||
| ab5489a080 | |||
| f4567a2e82 | |||
| 4b298ffc1c | |||
| 0f986cbf80 | |||
| 582bd0ee30 | |||
| 2e4030c2f2 | |||
| a9b662840b | |||
| 30bbb37bff | |||
| 2f6d6c405f | |||
| 068f42782b | |||
| 472c543c7b | |||
| 4e67a67ace | |||
| 1e63d3ae9d | |||
| b363efd1f0 | |||
| 0abbaa09f8 | |||
| 455b7a6893 | |||
| 92f76d091d | |||
| c1956e0028 | |||
| 491992a4d7 | |||
| e5b727216c | |||
| f03e337b9a | |||
| 99e99e7e08 | |||
| b93761eb1e | |||
| 4f5421191d | |||
| 71ed9dc24f | |||
| 1a0cc504c4 | |||
| 86775d4642 | |||
| b936f410ce | |||
| ddcd2076a1 | |||
| 9345facaed | |||
| 885caa6bc3 | |||
| a77bbe4420 | |||
| 61a4886e62 | |||
| 164f58c883 | |||
| fbfacb825b | |||
| 5e4d2cf993 | |||
| 97d3749269 | |||
| 0dcecf9a3c | |||
| c75e6406cd | |||
| 0254b44369 | |||
| ff11567471 | |||
| 06e383fe2c | |||
| dc5b31087a | |||
| 9e745dc3fc | |||
| 14b10c663e | |||
| f64c72f9a6 | |||
| 610eaf257e | |||
| b511740d93 | |||
| b0643b6f62 | |||
| 7e8d79222c | |||
| 14295ce859 | |||
| 5ad433e63a | |||
| 61e40e88f4 | |||
| 410955de3c | |||
| 9c0502eefb | |||
| 9b3da3a6e7 | |||
| bc41169176 | |||
| b3a1afce06 | |||
| 4b6dc8a47a | |||
| 3dadd5fc1a | |||
| bea844d51e | |||
| 5fb6c68df4 | |||
| 866a057704 | |||
| da8eab330d | |||
| 39bda0775e | |||
| ed4d3a3915 | |||
| 6447932212 | |||
| 9f278772bb | |||
| 2d073b6055 | |||
| 99b18d208d | |||
| 1321566910 | |||
| cefafe99e4 | |||
| daa7eaf811 | |||
| 3dcf5c3a99 | |||
| 99d0f62ab5 | |||
| 85050c8da4 | |||
| 120c5502fd | |||
| 64a6599e81 | |||
| a4b567588f | |||
| 2e74fea2d5 | |||
| c4933875dd | |||
| 10a54aef91 | |||
| 34be79192c | |||
| fcf13591be | |||
| 3e8f2f35bf | |||
| e5a91825b1 | |||
| b3271b17a2 | |||
| d4117e3505 | |||
| 73c7e4ea76 | |||
| 23cc5ce68d | |||
| e42059e486 | |||
| 00f40d194b | |||
| 31f348328e | |||
| 8c48a9a772 | |||
| bacfbe6eac | |||
| 63d08aef46 | |||
| 87f818ef96 | |||
| 7eafe21623 | |||
| 22827c28fa | |||
| 8c21345f14 | |||
| 56d7d4af52 | |||
| 71c43ec6fe | |||
| 443b461974 | |||
| cc16908b86 | |||
| c4c6881bd6 | |||
| 35d720bb77 | |||
| 274ce1ca63 | |||
| 252e881e93 | |||
| d36ad7d1c5 | |||
| 7305d2f5dc | |||
| 4cfad053f0 | |||
| 807f71ffa7 | |||
| d12f24d798 | |||
| f9d2539a45 | |||
| 87bfccd14f | |||
| e5e3729215 | |||
| 6210985548 | |||
| 20250a0d6d | |||
| e5616f7c3a | |||
| 3b1e469a4f | |||
| 70ca19eb87 | |||
| 7e52eaeddb | |||
| d618b6d561 | |||
| e954d4ea59 | |||
| b1ee23cd20 | |||
| d86b10c14e | |||
| 1ea38d4f6a | |||
| 26bd5a9efa | |||
| 4b0d85c010 | |||
| 149b485a9b | |||
| 6b1f064cda | |||
| 1cef6a2c23 | |||
| 007460dc51 | |||
| 10057a82de | |||
| 73fa5bf1d1 | |||
| c32b564da1 | |||
| 7b9b5ce569 | |||
| f0b3a1fbc4 | |||
| 869b4374ba | |||
| ea192cd9de | |||
| 5d30f6be68 | |||
| a342d79b86 | |||
| 1db7368c9f | |||
| 88b002b277 | |||
| 044a3a3bbf | |||
| 49070aa843 | |||
| 18e05e36e6 | |||
| bf79eecca0 | |||
| b80216dce1 | |||
| 87138f9a1f | |||
| c6560514d8 | |||
| 839f73e1ef | |||
| 2ca2062011 | |||
| 03209ee23b | |||
| c61299f17f | |||
| 880af293ef | |||
| 67c59992c9 | |||
| be3d696f60 | |||
| 6b8f6a267d | |||
| 120b8ada38 | |||
| 8bb052981d | |||
| 7fc8e48596 | |||
| ff518195f8 | |||
| 54d3e683a1 | |||
| a29c2b9cc2 | |||
| 85e7e70767 | |||
| 3f10c61e22 | |||
| 5de9a5003b | |||
| d3076fbdec | |||
| 26c6decd74 | |||
| 54702a5afe | |||
| b45390a8d1 | |||
| 2faa3ede84 | |||
| 85e1933a83 | |||
| 07788ab3b6 | |||
| 2ed7463069 | |||
| e533387ce5 | |||
| b654fd0428 | |||
| 7a3a71e1dc | |||
| 8722a46d06 | |||
| e20bdec470 | |||
| 86708e0ed5 | |||
| 51797e0ea7 | |||
| 20f5b83649 | |||
| ffeff3d69d | |||
| a44748c0c4 | |||
| e678f8d538 | |||
| ccda7113c1 | |||
| 5c8a583e24 | |||
| 07985228b2 | |||
| dc389037f8 | |||
| f30b195778 | |||
| 95ac4606d5 | |||
| 2bc07f8e8d | |||
| ca6f863c0f | |||
| 66faa07c00 | |||
| 72158c7c3f | |||
| 8b32a0a404 | |||
| abb7b8fe8c | |||
| 51308fa25e | |||
| 74d855357d | |||
| a9593a0fd9 | |||
| dec72340de | |||
| 7646daef3d | |||
| 1c1fd1273b | |||
| e6eaf870c6 | |||
| 23eff1585c | |||
| 4d51c13e46 | |||
| 625cb19cba | |||
| ae946b578e | |||
| 8b4683b77b | |||
| 0cc1f7623a | |||
| 56ce1a3236 | |||
| 5aab26f2ca | |||
| 2869c63517 | |||
| 87b96b8226 | |||
| 7505de074c | |||
| ae1d1397b1 | |||
| 0c8a9b744e | |||
| 9b25e875f3 | |||
| e84f555a66 | |||
| 048263a1d0 | |||
| efd18ff852 | |||
| 44aa4e76e2 | |||
| e3af88ea8c | |||
| ff5dfab94d | |||
| 2cf5292b16 | |||
| 7b24bfae94 | |||
| 5cb547db0a | |||
| dc2824a095 | |||
| d169a1997c | |||
| 23bcd0816f | |||
| 93baead066 | |||
| bb21191c5b | |||
| 7139dea7f6 | |||
| 08100f60e8 | |||
| 61ae211dab | |||
| 5d1dae1d86 | |||
| 4252f3327f | |||
| 9a79fb9774 | |||
| 6629e9b9aa | |||
| afc91425bc | |||
| 6259f594c8 | |||
| ac5434fc30 | |||
| d1ca0df1ab | |||
| 9eb8c58d87 | |||
| 470d2b85a4 | |||
| 81330f8432 | |||
| 799a97930c | |||
| 1ef9ca551f | |||
| b10f2da647 | |||
| 6063309932 | |||
| 7c2499cd91 | |||
| e0f8cf78ee | |||
| 20cfadeb0b | |||
| cf4fbf7153 | |||
| 329ae7a38e | |||
| 41ce3fece5 | |||
| fdd34eb943 | |||
| d118218662 | |||
| 2f0b148380 | |||
| ecb41cbc3a | |||
| 5f6d51b6cb | |||
| aa0abd9ae1 | |||
| f777017460 | |||
| a0c1c8342f | |||
| 11e9d6569b | |||
| e4b6d2df6a | |||
| 97c98272c9 | |||
| e1d6cd1bb9 | |||
| e3b0958d10 | |||
| 88bb6afab1 | |||
| 707fd29b97 | |||
| 682c27c07c | |||
| 9e54dde490 | |||
| 15bd480d4c | |||
| bbbb8d47ae | |||
| 4e5ab6be1d | |||
| 6d0df85e5e | |||
| c80212adb9 | |||
| 1214599c4c | |||
| 424d0d2b89 | |||
| c45e524109 | |||
| efbf2457a1 | |||
| d3cb93bdba | |||
| e8c253d953 | |||
| b746578bc8 | |||
| 8c251d2246 | |||
| 89a9f06324 | |||
| 0573022b7c | |||
| 5e82dc880f | |||
| a7aecbadd1 | |||
| 6d7060ceb5 | |||
| 5c9f6e6613 | |||
| 808abb28ea | |||
| a4942fcbae | |||
| 816bc02d9d | |||
| 896a899b0f | |||
| e98b87243b | |||
| fa7da4ca58 | |||
| ba6fd00b54 | |||
| 9993b2d98c | |||
| c50ca23135 | |||
| 27242f54fe | |||
| 2fe22ff911 | |||
| 05740775c2 | |||
| 0fd9360029 | |||
| ed98ef612e | |||
| a4f6a5514f | |||
| 56533caff0 | |||
| bf83f161b0 | |||
| 7ee359b910 | |||
| 5871d29d48 | |||
| ae5cc1cfb4 | |||
| cd38101f99 | |||
| 6cf990bc1d | |||
| cb7b99cab3 | |||
| 21e0ae0c8c | |||
| 851e6d35a2 |
+2
-1
@@ -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
|
||||
|
||||
+87
-76
@@ -1,104 +1,115 @@
|
||||
Checks:
|
||||
# Estrategia: Habilitar checks uno por uno, aplicar fix, compilar, commit
|
||||
# ✅ Check 1: readability-uppercase-literal-suffix (1.0f → 1.0F)
|
||||
# ✅ Check 2: readability-math-missing-parentheses (claridad en ops matemáticas)
|
||||
# ✅ Check 3: readability-identifier-naming (DESHABILITADO temporalmente - cascada de cambios)
|
||||
# ✅ Check 4: readability-const-return-type (código ya cumple)
|
||||
# ✅ Check 5: readability-else-after-return (código ya cumple)
|
||||
# ✅ Check 6: readability-simplify-boolean-expr (código ya cumple)
|
||||
# ✅ Check 7: readability-* (225 fixes aplicados)
|
||||
- readability-*
|
||||
- -readability-identifier-naming # Excluido (cascada de cambios)
|
||||
- -readability-identifier-length # Excluido (nombres cortos son OK)
|
||||
- -readability-magic-numbers # Excluido (muchos falsos positivos)
|
||||
- -readability-convert-member-functions-to-static # Excluido (rompe encapsulación)
|
||||
- -readability-use-anyofallof # Excluido (C++20 ranges - no todos los compiladores)
|
||||
- -readability-function-cognitive-complexity # Excluido (complejidad ciclomática aceptable)
|
||||
- -clang-analyzer-security.insecureAPI.rand # Excluido (rand() es suficiente para juegos)
|
||||
# ✅ Check 8: modernize-* (215 fixes aplicados)
|
||||
- modernize-*
|
||||
- -modernize-use-trailing-return-type # Excluido (estilo controversial)
|
||||
- -modernize-avoid-c-arrays # Excluido (arrays C son OK en algunos contextos)
|
||||
# ✅ Check 9: performance-* (91 fixes aplicados)
|
||||
- performance-*
|
||||
- -performance-enum-size # Excluido (tamaño de enum no crítico)
|
||||
# ✅ Check 10: bugprone-* (0 fixes - todos eran falsos positivos)
|
||||
- bugprone-*
|
||||
- -bugprone-easily-swappable-parameters # Excluido (muchos falsos positivos)
|
||||
- -bugprone-narrowing-conversions # Excluido (conversiones intencionales)
|
||||
- -bugprone-integer-division # Excluido (divisiones enteras OK en contexto)
|
||||
- -bugprone-branch-clone # Excluido (fall-through en switch es intencional)
|
||||
- -bugprone-switch-missing-default-case # Excluido (no todos los switches necesitan default)
|
||||
- -bugprone-implicit-widening-of-multiplication-result # Excluido (valores pequeños, sin overflow)
|
||||
- -bugprone-exception-escape # Excluido (excepciones en main terminan el programa - OK)
|
||||
# ✅ Check 11: llvm-include-order (validar orden de includes - 0 errores)
|
||||
- llvm-include-order
|
||||
# ⏸️ Check 12: misc-include-cleaner (DESHABILITADO temporalmente - requiere refactorización masiva de includes)
|
||||
- -misc-include-cleaner
|
||||
- -readability-identifier-length
|
||||
- -readability-magic-numbers
|
||||
- -bugprone-integer-division
|
||||
- -bugprone-easily-swappable-parameters
|
||||
- -bugprone-narrowing-conversions
|
||||
- -modernize-avoid-c-arrays
|
||||
# No forçar reemplaç de bucles "normals" per std::any_of/std::all_of.
|
||||
# Equivalent a `--suppress=useStlAlgorithm` que ja tenim a cppcheck.
|
||||
- -readability-use-anyofallof
|
||||
# performance-noexcept-move-constructor crashea clang-tidy (LLVM 19.1)
|
||||
# con recursión infinita en ExceptionSpecAnalyzer::analyzeRecord cuando
|
||||
# analiza ciertas instanciaciones de std::set. No es un falso positivo
|
||||
# sobre nuestro código: el check ni siquiera llega a evaluar el patrón.
|
||||
- -performance-noexcept-move-constructor
|
||||
|
||||
WarningsAsErrors: '*'
|
||||
# No usar HeaderFilterRegex - usamos .clang-tidy local en source/core/audio/ para excluir
|
||||
# Headers nostres (excloem source/external/ que conté dependències de tercers no editables)
|
||||
HeaderFilterRegex: 'source/(core|game|utils)/'
|
||||
FormatStyle: file
|
||||
|
||||
CheckOptions:
|
||||
# Variables locales en snake_case
|
||||
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||
# bugprone-empty-catch: aceptar catches vacíos marcados con @INTENTIONAL en un comentario
|
||||
- { key: bugprone-empty-catch.IgnoreCatchWithKeywords, value: '@INTENTIONAL' }
|
||||
|
||||
# Miembros privados en snake_case con sufijo _
|
||||
# =====================================================================
|
||||
# CONSTANTES → UPPER_CASE (compile-time y runtime, en cualquier scope)
|
||||
# =====================================================================
|
||||
# Todo lo que sea const o constexpr se identifica visualmente en UPPER_CASE,
|
||||
# sin importar si es global, local, miembro o static.
|
||||
|
||||
# constexpr en cualquier scope (globales y locales)
|
||||
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE }
|
||||
|
||||
# Constantes globales (const no-constexpr)
|
||||
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||
|
||||
# Constantes locales (const en función)
|
||||
- { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE }
|
||||
|
||||
# Static const a nivel de archivo/namespace
|
||||
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
||||
|
||||
# Miembros static const/constexpr de clase (p.ej. static constexpr int MAX = 100;)
|
||||
- { key: readability-identifier-naming.ClassConstantCase, value: UPPER_CASE }
|
||||
|
||||
# Miembros const no-static de clase (p.ej. const int limit;)
|
||||
- { key: readability-identifier-naming.ConstantMemberCase, value: UPPER_CASE }
|
||||
|
||||
# Valores de enums
|
||||
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
||||
|
||||
# NOTA: Los parámetros const NO se tratan como constantes aquí.
|
||||
# Un parámetro sigue siendo un parámetro aunque sea const → hereda ParameterCase.
|
||||
|
||||
# =====================================================================
|
||||
# VARIABLES NO-CONST
|
||||
# =====================================================================
|
||||
|
||||
# Variables locales
|
||||
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.LocalVariableCase, value: lower_case }
|
||||
|
||||
# Parámetros de función
|
||||
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
|
||||
|
||||
# Variables estáticas no-const (static locales, static file-scope,
|
||||
# y static members no-const de clase como el instance_ de un Singleton).
|
||||
# Sufijo _ para marcar que tienen storage estático.
|
||||
- { key: readability-identifier-naming.StaticVariableCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.StaticVariableSuffix, value: _ }
|
||||
|
||||
# =====================================================================
|
||||
# MIEMBROS DE CLASE NO-CONST
|
||||
# =====================================================================
|
||||
# Privados: 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 _
|
||||
# Protegidos: 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)
|
||||
# Públicos: snake_case sin sufijo
|
||||
- { key: readability-identifier-naming.PublicMemberCase, value: lower_case }
|
||||
|
||||
# Namespaces en CamelCase
|
||||
- { key: readability-identifier-naming.NamespaceCase, value: CamelCase }
|
||||
|
||||
# Variables estáticas privadas como miembros privados
|
||||
- { key: readability-identifier-naming.StaticVariableCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.StaticVariableSuffix, value: _ }
|
||||
|
||||
# Constantes estáticas sin sufijo
|
||||
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
||||
|
||||
# Constantes globales en UPPER_CASE
|
||||
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||
|
||||
# Variables constexpr globales en UPPER_CASE
|
||||
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE }
|
||||
|
||||
# Constantes locales en UPPER_CASE
|
||||
- { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE }
|
||||
|
||||
# Constexpr miembros en UPPER_CASE (sin sufijo)
|
||||
- { key: readability-identifier-naming.ConstexprMemberCase, value: UPPER_CASE }
|
||||
|
||||
# Constexpr miembros privados/protegidos con sufijo _
|
||||
- { key: readability-identifier-naming.ConstexprMethodCase, value: UPPER_CASE }
|
||||
|
||||
# Clases, structs y enums en CamelCase
|
||||
# =====================================================================
|
||||
# TIPOS
|
||||
# =====================================================================
|
||||
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.UnionCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.TypeAliasCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.TypedefCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.TemplateParameterCase, value: CamelCase }
|
||||
|
||||
# Valores de enums en UPPER_CASE
|
||||
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
||||
# Namespaces
|
||||
- { key: readability-identifier-naming.NamespaceCase, value: CamelCase }
|
||||
|
||||
# Métodos en camelBack (sin sufijos)
|
||||
# =====================================================================
|
||||
# FUNCIONES Y MÉTODOS (incluyendo constexpr)
|
||||
# =====================================================================
|
||||
# Un método/función constexpr es un invocable, no una constante → camelBack.
|
||||
- { key: readability-identifier-naming.FunctionCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.ConstexprFunctionCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.MethodCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.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 }
|
||||
|
||||
# misc-include-cleaner: Ignorar SDL (genera falsos positivos)
|
||||
- { key: misc-include-cleaner.IgnoreHeaders, value: 'SDL3/.*' }
|
||||
- { key: readability-identifier-naming.ConstexprMethodCase, value: camelBack }
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(dir \"C:\\mingw\\gitea\\orni_attack\\release\\dll\")",
|
||||
"Bash(make:*)",
|
||||
"Bash(echo:*)",
|
||||
"Bash(objdump:*)",
|
||||
"Bash(unzip:*)",
|
||||
"Bash(\"/Volumes/diskito/diskito.app/Contents/MacOS/diskito\")",
|
||||
"Bash(pkill:*)",
|
||||
"Bash(hdiutil detach:*)",
|
||||
"Bash(cat:*)",
|
||||
"Bash(hdiutil mount:*)",
|
||||
"Bash(open \"/Volumes/Orni Attack/Orni Attack.app\")"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
# Pre-commit hook: aplica clang-format als fitxers C++ staged abans del commit.
|
||||
# - Només toca fitxers staged dins source/ (exclou source/external/ i source/legacy/).
|
||||
# - Avorta el commit si hi ha canvis NO staged en aquests fitxers (per no incloure'ls sense voler).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v clang-format >/dev/null 2>&1; then
|
||||
echo "pre-commit: clang-format no trobat — saltant format check" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mapfile -t STAGED < <(git diff --cached --name-only --diff-filter=ACMR \
|
||||
| grep -E '^source/.*\.(cpp|hpp|h)$' \
|
||||
| grep -vE '^source/(external|legacy)/' || true)
|
||||
|
||||
if [ ${#STAGED[@]} -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
UNSTAGED_DIRTY=()
|
||||
for f in "${STAGED[@]}"; do
|
||||
if ! git diff --quiet -- "$f"; then
|
||||
UNSTAGED_DIRTY+=("$f")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#UNSTAGED_DIRTY[@]} -gt 0 ]; then
|
||||
echo "pre-commit: aquests fitxers tenen canvis NO staged i estan al commit." >&2
|
||||
echo " Fes 'git add' o 'git stash' abans de continuar:" >&2
|
||||
printf ' %s\n' "${UNSTAGED_DIRTY[@]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
clang-format -i "${STAGED[@]}"
|
||||
git add -- "${STAGED[@]}"
|
||||
|
||||
# --- clang-tidy només sobre els fitxers staged ---
|
||||
if ! command -v clang-tidy >/dev/null 2>&1; then
|
||||
echo "pre-commit: clang-tidy no trobat — saltant tidy" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
BUILD_DIR="$REPO_ROOT/build"
|
||||
|
||||
if [ ! -f "$BUILD_DIR/compile_commands.json" ]; then
|
||||
echo "pre-commit: generant compile_commands.json (build dir buit)..." >&2
|
||||
cmake -S "$REPO_ROOT" -B "$BUILD_DIR" >/dev/null
|
||||
fi
|
||||
|
||||
echo "pre-commit: clang-tidy sobre ${#STAGED[@]} fitxer(s)..." >&2
|
||||
if ! clang-tidy -p "$BUILD_DIR" --quiet "${STAGED[@]}"; then
|
||||
echo "pre-commit: clang-tidy ha trobat errors — commit avortat" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- cppcheck només sobre els .cpp staged ---
|
||||
if ! command -v cppcheck >/dev/null 2>&1; then
|
||||
echo "pre-commit: cppcheck no trobat — saltant cppcheck" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CPP_STAGED=()
|
||||
for f in "${STAGED[@]}"; do
|
||||
[[ "$f" == *.cpp ]] && CPP_STAGED+=("$f")
|
||||
done
|
||||
|
||||
if [ ${#CPP_STAGED[@]} -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "pre-commit: cppcheck sobre ${#CPP_STAGED[@]} fitxer(s)..." >&2
|
||||
# Nota: el path d'inclusió ha d'anar en relatiu. Amb path absolut, cppcheck
|
||||
# falla a parsejar "enum class X : std::uint8_t" (no resol <cstdint> bé) i
|
||||
# emet un syntaxError fals. Els hooks de git s'executen sempre des de la
|
||||
# rel del repo, així que "source" relatiu és prou.
|
||||
if ! cppcheck \
|
||||
--enable=warning,style,performance,portability \
|
||||
--std=c++20 \
|
||||
--language=c++ \
|
||||
--inline-suppr \
|
||||
--suppress=missingIncludeSystem \
|
||||
--suppress=toomanyconfigs \
|
||||
--suppress='*:*source/external/*' \
|
||||
--suppress='*:*source/legacy/*' \
|
||||
--suppress=normalCheckLevelMaxBranches \
|
||||
--suppress=useStlAlgorithm \
|
||||
-D_DEBUG \
|
||||
-DLINUX_BUILD \
|
||||
--quiet \
|
||||
--error-exitcode=1 \
|
||||
-I source \
|
||||
"${CPP_STAGED[@]}"; then
|
||||
echo "pre-commit: cppcheck ha trobat errors — commit avortat" >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -24,9 +24,11 @@ tools/pack_resources/pack_resources.exe
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.dmg
|
||||
dist/
|
||||
|
||||
# Generated resources
|
||||
resources.pack
|
||||
release/windows/*.res
|
||||
|
||||
# Compiled Object files
|
||||
*.o
|
||||
@@ -100,3 +102,7 @@ ehthumbs_vista.db
|
||||
*.bak
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
.cache/
|
||||
.claude/lint-reports/
|
||||
lint-reports/
|
||||
|
||||
+207
-99
@@ -1,122 +1,245 @@
|
||||
# CMakeLists.txt
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(orni VERSION 0.8.1 LANGUAGES CXX)
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(orni VERSION 0.7.2)
|
||||
|
||||
# Info del proyecto
|
||||
# Info del projecte (font de veritat per a project.h)
|
||||
set(PROJECT_LONG_NAME "Orni Attack")
|
||||
set(PROJECT_COPYRIGHT_ORIGINAL "© 1999 Visente i Sergi")
|
||||
set(PROJECT_COPYRIGHT_PORT "© 2025 JailDesigner")
|
||||
set(PROJECT_COPYRIGHT "${PROJECT_COPYRIGHT_ORIGINAL}, ${PROJECT_COPYRIGHT_PORT}")
|
||||
set(PROJECT_COPYRIGHT "© 2026 JailDesigner")
|
||||
|
||||
# Establecer estándar de C++
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# Exportar comandos de compilación para herramientas de análisis
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# --- GENERACIÓN DE VERSIÓN AUTOMÁTICA ---
|
||||
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
|
||||
)
|
||||
else()
|
||||
set(GIT_HASH "unknown")
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# --- GENERACIÓ DEL project.h AMB GIT HASH ---
|
||||
# Si GIT_HASH ve passat des de fora (Makefile), l'usem; si no, el resolem amb git.
|
||||
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/project.h.in ${CMAKE_BINARY_DIR}/project.h @ONLY)
|
||||
|
||||
# --- LISTA DE FUENTES (AUTO-DESCUBRIMIENTO) ---
|
||||
# Buscar automáticamente todos los archivos .cpp en core/, game/ y main.cpp
|
||||
file(GLOB_RECURSE CORE_SOURCES "${CMAKE_SOURCE_DIR}/source/core/*.cpp")
|
||||
file(GLOB_RECURSE GAME_SOURCES "${CMAKE_SOURCE_DIR}/source/game/*.cpp")
|
||||
# --- LLISTA DE FONTS (AUTO-DESCOBRIMENT) ---
|
||||
# Cerquem tots els .cpp dins core/ i game/, més main.cpp. Exclou legacy/.
|
||||
file(GLOB_RECURSE CORE_SOURCES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/source/core/*.cpp")
|
||||
file(GLOB_RECURSE GAME_SOURCES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/source/game/*.cpp")
|
||||
file(GLOB_RECURSE EXTERNAL_SOURCES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/source/external/*.cpp")
|
||||
|
||||
set(APP_SOURCES
|
||||
${CORE_SOURCES}
|
||||
${GAME_SOURCES}
|
||||
${EXTERNAL_SOURCES}
|
||||
source/main.cpp
|
||||
)
|
||||
|
||||
# Excluir archivos legacy (código Pascal de referencia)
|
||||
list(FILTER APP_SOURCES EXCLUDE REGEX ".*/legacy/.*")
|
||||
|
||||
# Log de archivos encontrados (útil para debug)
|
||||
list(LENGTH APP_SOURCES APP_SOURCES_COUNT)
|
||||
message(STATUS "Archivos .cpp encontrados: ${APP_SOURCES_COUNT}")
|
||||
message(STATUS "Fonts .cpp trobades: ${APP_SOURCES_COUNT}")
|
||||
|
||||
# Configuración de SDL3
|
||||
# --- SDL3 ---
|
||||
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
|
||||
message(STATUS "SDL3 encontrado: ${SDL3_INCLUDE_DIRS}")
|
||||
|
||||
# --- AÑADIR EJECUTABLE ---
|
||||
add_executable(${PROJECT_NAME} ${APP_SOURCES})
|
||||
|
||||
# --- DIRECTORIOS DE INCLUSIÓN ---
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}/source"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
)
|
||||
|
||||
# Enlazar las librerías SDL3
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3)
|
||||
|
||||
# --- CONFIGURACIÓN PLATAFORMAS Y COMPILADOR ---
|
||||
# Configuración de flags de compilación
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wall)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE $<$<CONFIG:RELEASE>:-O2 -ffunction-sections -fdata-sections>)
|
||||
# Silencia warnings de codi de tercers (mateixa filosofia que el
|
||||
# .clang-tidy a source/external/). Només afecta aquests TUs concrets;
|
||||
# la resta del codi continua compilant amb -Wall -Wextra -Wpedantic.
|
||||
if(EXTERNAL_SOURCES)
|
||||
set_source_files_properties(
|
||||
${EXTERNAL_SOURCES}
|
||||
PROPERTIES COMPILE_OPTIONS "-Wno-missing-field-initializers;-Wno-deprecated-declarations;-Wno-tautological-compare"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Definir _DEBUG en modo Debug y RELEASE_BUILD en modo Release
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:DEBUG>:_DEBUG>)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:RELEASE>:RELEASE_BUILD>)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:-O2 -ffunction-sections -fdata-sections>
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:_DEBUG>
|
||||
$<$<CONFIG:Release>:RELEASE_BUILD>
|
||||
)
|
||||
|
||||
# Definir MACOS_BUNDLE si es un bundle de macOS
|
||||
if(APPLE AND MACOSX_BUNDLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUNDLE)
|
||||
endif()
|
||||
|
||||
# Configuración específica para cada plataforma
|
||||
if(WIN32)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE WINDOWS_BUILD)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE mingw32)
|
||||
# Static linking for libgcc and libstdc++ (avoid DLL dependencies for distribution)
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
-static
|
||||
)
|
||||
# Añadir icono en Windows (se configurará desde el Makefile con windres)
|
||||
elseif(APPLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE MACOS_BUILD)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LINUX_BUILD)
|
||||
endif()
|
||||
|
||||
# Especificar la ubicación del ejecutable
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
# --- EINA STANDALONE: pack_resources ---
|
||||
# Executable auxiliar que empaqueta `data/` a `build/resources.pack`.
|
||||
# EXCLUDE_FROM_ALL: només es compila quan algun target en depèn (ho fa
|
||||
# `resource_pack`). Build manual: `cmake --build build --target pack_resources`.
|
||||
add_executable(pack_resources EXCLUDE_FROM_ALL
|
||||
tools/pack_resources/pack_resources.cpp
|
||||
source/core/resources/resource_pack.cpp
|
||||
)
|
||||
target_include_directories(pack_resources PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}/source"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
)
|
||||
target_compile_options(pack_resources PRIVATE -Wall -Wextra -Wpedantic)
|
||||
|
||||
# --- STATIC ANALYSIS TARGETS ---
|
||||
# Buscar herramientas de análisis estático
|
||||
find_program(CLANG_FORMAT_EXE NAMES clang-format)
|
||||
# --- REGENERACIÓ AUTOMÀTICA DE build/resources.pack ---
|
||||
# A cada build re-empaquetem data/ si algun fitxer dins ha canviat. Evita
|
||||
# debugar amb un pack obsolet. CONFIGURE_DEPENDS força CMake a re-globbar
|
||||
# a la pròxima invocació (recull fitxers nous afegits a data/).
|
||||
file(GLOB_RECURSE DATA_FILES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/data/*")
|
||||
set(RESOURCE_PACK "${CMAKE_BINARY_DIR}/resources.pack")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${RESOURCE_PACK}
|
||||
COMMAND $<TARGET_FILE:pack_resources>
|
||||
"${CMAKE_SOURCE_DIR}/data"
|
||||
"${RESOURCE_PACK}"
|
||||
DEPENDS pack_resources ${DATA_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Empaquetant data/ → build/resources.pack"
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(resource_pack ALL DEPENDS ${RESOURCE_PACK})
|
||||
add_dependencies(${PROJECT_NAME} resource_pack)
|
||||
|
||||
# --- COMPILACIÓ DE SHADERS GLSL → SPIR-V (headers C++ embedits) ---
|
||||
# Compila els shaders .glsl a SPIR-V i els converteix en headers C++ embedits
|
||||
# (source/core/rendering/gpu/spv/*.h). Aquests headers es commiteen al repo,
|
||||
# així que glslc només és necessari quan canvien els .glsl o falten headers.
|
||||
#
|
||||
# Per a macOS hi ha a més els headers MSL escrits a mà a source/core/rendering/gpu/msl/.
|
||||
set(SHADERS_DIR "${CMAKE_SOURCE_DIR}/shaders")
|
||||
set(HEADERS_DIR "${CMAKE_SOURCE_DIR}/source/core/rendering/gpu/spv")
|
||||
set(ALL_SHADER_HEADERS
|
||||
"${HEADERS_DIR}/line_vert_spv.h"
|
||||
"${HEADERS_DIR}/line_frag_spv.h"
|
||||
"${HEADERS_DIR}/postfx_vert_spv.h"
|
||||
"${HEADERS_DIR}/postfx_frag_spv.h"
|
||||
"${HEADERS_DIR}/bloom_frag_spv.h"
|
||||
)
|
||||
set(ALL_SHADER_SOURCES
|
||||
"${SHADERS_DIR}/line.vert.glsl"
|
||||
"${SHADERS_DIR}/line.frag.glsl"
|
||||
"${SHADERS_DIR}/postfx.vert.glsl"
|
||||
"${SHADERS_DIR}/postfx.frag.glsl"
|
||||
"${SHADERS_DIR}/bloom.frag.glsl"
|
||||
)
|
||||
set(ALL_SHADER_HEADERS_PRESENT TRUE)
|
||||
foreach(_spv_header IN LISTS ALL_SHADER_HEADERS)
|
||||
if(NOT EXISTS "${_spv_header}")
|
||||
set(ALL_SHADER_HEADERS_PRESENT FALSE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
find_program(GLSLC_EXE NAMES glslc HINTS ${Vulkan_GLSLC_EXECUTABLE})
|
||||
if(GLSLC_EXE)
|
||||
add_custom_command(
|
||||
OUTPUT ${ALL_SHADER_HEADERS}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D GLSLC=${GLSLC_EXE}
|
||||
-D SHADERS_DIR=${SHADERS_DIR}
|
||||
-D HEADERS_DIR=${HEADERS_DIR}
|
||||
-P ${CMAKE_SOURCE_DIR}/tools/shaders/compile_spirv.cmake
|
||||
DEPENDS ${ALL_SHADER_SOURCES} ${CMAKE_SOURCE_DIR}/tools/shaders/compile_spirv.cmake
|
||||
COMMENT "Compilant shaders GLSL → headers SPIR-V embedits"
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(shaders DEPENDS ${ALL_SHADER_HEADERS})
|
||||
add_dependencies(${PROJECT_NAME} shaders)
|
||||
message(STATUS "Shaders: glslc trobat (${GLSLC_EXE}); headers SPV es regeneraran si canvia el GLSL")
|
||||
elseif(ALL_SHADER_HEADERS_PRESENT)
|
||||
message(STATUS "Shaders: glslc no trobat — s'usaran els headers SPV ja commiteats al repo")
|
||||
else()
|
||||
message(FATAL_ERROR "glslc no trobat i falten headers SPV: instal·la 'shaderc' o 'vulkan-sdk' per generar-los")
|
||||
endif()
|
||||
|
||||
# --- STATIC ANALYSIS / FORMAT TARGETS ---
|
||||
find_program(CLANG_TIDY_EXE NAMES clang-tidy)
|
||||
find_program(CLANG_FORMAT_EXE NAMES clang-format)
|
||||
find_program(CPPCHECK_EXE NAMES cppcheck)
|
||||
|
||||
# Recopilar todos los archivos fuente para formateo
|
||||
file(GLOB_RECURSE ALL_SOURCE_FILES
|
||||
"${CMAKE_SOURCE_DIR}/source/*.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/source/*.hpp"
|
||||
"${CMAKE_SOURCE_DIR}/source/*.h"
|
||||
)
|
||||
# Excluir directorios con checks deshabilitados
|
||||
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX ".*/audio/.*")
|
||||
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX ".*/external/.*")
|
||||
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX ".*/legacy/.*")
|
||||
|
||||
# Targets de clang-format
|
||||
set(CPPCHECK_SOURCES ${ALL_SOURCE_FILES})
|
||||
list(FILTER CPPCHECK_SOURCES INCLUDE REGEX ".*\\.cpp$")
|
||||
|
||||
if(CLANG_TIDY_EXE)
|
||||
# En macOS, obtenir la ruta del SDK perquè clang-tidy trobe els headers del sistema.
|
||||
set(CLANG_TIDY_EXTRA_ARGS "")
|
||||
if(APPLE)
|
||||
execute_process(
|
||||
COMMAND xcrun --show-sdk-path
|
||||
OUTPUT_VARIABLE MACOS_SDK_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(MACOS_SDK_PATH)
|
||||
set(CLANG_TIDY_EXTRA_ARGS "--extra-arg=-isysroot${MACOS_SDK_PATH}")
|
||||
message(STATUS "clang-tidy usarà SDK de macOS: ${MACOS_SDK_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_target(tidy
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
-p ${CMAKE_BINARY_DIR}
|
||||
${CLANG_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}
|
||||
${CLANG_TIDY_EXTRA_ARGS}
|
||||
--fix
|
||||
${ALL_SOURCE_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Running clang-tidy with fixes..."
|
||||
)
|
||||
else()
|
||||
message(STATUS "clang-tidy no trobat - targets 'tidy' i 'tidy-fix' no disponibles")
|
||||
endif()
|
||||
|
||||
if(CLANG_FORMAT_EXE)
|
||||
add_custom_target(format
|
||||
COMMAND ${CLANG_FORMAT_EXE}
|
||||
@@ -135,45 +258,30 @@ if(CLANG_FORMAT_EXE)
|
||||
COMMENT "Checking clang-format..."
|
||||
)
|
||||
else()
|
||||
message(STATUS "clang-format no encontrado - targets 'format' y 'format-check' no disponibles")
|
||||
message(STATUS "clang-format no trobat - targets 'format' i 'format-check' no disponibles")
|
||||
endif()
|
||||
|
||||
# Targets de clang-tidy
|
||||
if(CLANG_TIDY_EXE)
|
||||
# En macOS, obtener la ruta del SDK para que clang-tidy encuentre los headers del sistema
|
||||
set(CLANG_TIDY_EXTRA_ARGS "")
|
||||
if(APPLE)
|
||||
execute_process(
|
||||
COMMAND xcrun --show-sdk-path
|
||||
OUTPUT_VARIABLE MACOS_SDK_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(MACOS_SDK_PATH)
|
||||
set(CLANG_TIDY_EXTRA_ARGS "--extra-arg=-isysroot${MACOS_SDK_PATH}")
|
||||
message(STATUS "clang-tidy usará SDK de macOS: ${MACOS_SDK_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_target(tidy
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
-p ${CMAKE_BINARY_DIR}
|
||||
${CLANG_TIDY_EXTRA_ARGS}
|
||||
--fix
|
||||
--fix-errors
|
||||
${ALL_SOURCE_FILES}
|
||||
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
|
||||
--suppress=*:*source/external/*
|
||||
--suppress=*:*source/legacy/*
|
||||
--suppress=normalCheckLevelMaxBranches
|
||||
--suppress=useStlAlgorithm
|
||||
-D_DEBUG
|
||||
-DLINUX_BUILD
|
||||
--quiet
|
||||
-I ${CMAKE_SOURCE_DIR}/source
|
||||
${CPPCHECK_SOURCES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Running clang-tidy with auto-fix..."
|
||||
)
|
||||
|
||||
add_custom_target(tidy-check
|
||||
COMMAND ${CLANG_TIDY_EXE}
|
||||
-p ${CMAKE_BINARY_DIR}
|
||||
${CLANG_TIDY_EXTRA_ARGS}
|
||||
--warnings-as-errors='*'
|
||||
${ALL_SOURCE_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Checking clang-tidy..."
|
||||
COMMENT "Running cppcheck..."
|
||||
)
|
||||
else()
|
||||
message(STATUS "clang-tidy no encontrado - targets 'tidy' y 'tidy-check' no disponibles")
|
||||
message(STATUS "cppcheck no trobat - target 'cppcheck' no disponible")
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,838 @@
|
||||
# Arquitectura de Orni Attack
|
||||
|
||||
> Documento de orientación para alguien que llega nuevo al proyecto. Cada
|
||||
> afirmación está anclada a código real (fichero/clase/función con su ruta).
|
||||
> Cuando algo no se ha podido verificar o no existe, se indica explícitamente.
|
||||
> El objetivo no es vender una arquitectura ideal, sino describir lo que **este**
|
||||
> proyecto hace, incluso donde es poco convencional.
|
||||
|
||||
## Índice
|
||||
|
||||
1. [Visión general](#1-visión-general)
|
||||
2. [Punto de entrada y el Director](#2-punto-de-entrada-y-el-director)
|
||||
3. [Bucle principal](#3-bucle-principal)
|
||||
4. [Sistema de escenas](#4-sistema-de-escenas)
|
||||
5. [Renderizado: de la lógica al píxel](#5-renderizado-de-la-lógica-al-píxel)
|
||||
6. [Entrada](#6-entrada)
|
||||
7. [Audio](#7-audio)
|
||||
8. [Recursos](#8-recursos)
|
||||
9. [Comunicación entre módulos](#9-comunicación-entre-módulos)
|
||||
10. [Lógica del juego](#10-lógica-del-juego)
|
||||
11. [IA del modo demo (attract)](#11-ia-del-modo-demo-attract)
|
||||
12. [Efectos visuales](#12-efectos-visuales)
|
||||
13. [Configuración, constantes y convenciones](#13-configuración-constantes-y-convenciones)
|
||||
14. [Guía de navegación](#14-guía-de-navegación)
|
||||
|
||||
---
|
||||
|
||||
## 1. Visión general
|
||||
|
||||
Orni Attack es un arcade vectorial (estética CRT de líneas con bloom) construido
|
||||
sobre **SDL3**, usando la **GPU API de SDL3** (`SDL_gpu`) para el render — **no**
|
||||
`SDL_Renderer`. El código está partido en dos grandes mundos:
|
||||
|
||||
- **`source/core/`** — el "motor": ventana, GPU, audio, input, recursos, i18n,
|
||||
overlays de sistema. No conoce nada del juego concreto. Por ejemplo,
|
||||
[audio.hpp](source/core/audio/audio.hpp) recibe un struct de configuración y no
|
||||
lee YAML, e [input.hpp](source/core/input/input.hpp) no incluye nada de `game/`.
|
||||
- **`source/game/`** — la lógica concreta de Orni Attack: escenas, entidades
|
||||
(naves, enemigos, balas), sistemas (colisiones, IA), stages/oleadas y efectos.
|
||||
|
||||
El punto de indirección entre ambos mundos para el render es
|
||||
[render_context.hpp](source/core/rendering/render_context.hpp): el juego habla con
|
||||
un `Rendering::Renderer*` opaco que es un alias de `GPU::GpuFrameRenderer`. Esto
|
||||
permite cambiar de backend sin tocar las firmas del juego.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph entry["Punto de entrada"]
|
||||
MAIN["main.cpp<br/>SDL_MAIN_USE_CALLBACKS"]
|
||||
end
|
||||
MAIN -->|posee| DIR["Director<br/>(es el programa)"]
|
||||
|
||||
subgraph core["source/core (motor)"]
|
||||
SDLM["SDLManager<br/>ventana + GPU"]
|
||||
GE["GlobalEvents<br/>F1-F7/F12/ESC/hotplug"]
|
||||
INPUT["Input (singleton)"]
|
||||
AUDIO["Audio (singleton)"]
|
||||
RES["Resource::Loader / Pack"]
|
||||
LOC["Locale (i18n)"]
|
||||
OVL["Notifier · ServiceMenu<br/>DebugOverlay · DefineInputs"]
|
||||
end
|
||||
|
||||
subgraph game["source/game (juego)"]
|
||||
SCN["Scenes<br/>Logo · Title · Game"]
|
||||
ENT["Entities<br/>Ship · Enemy · Bullet"]
|
||||
SYS["Systems<br/>Collision · EnemyAi · DemoPilot"]
|
||||
STG["StageManager / WaveRunner"]
|
||||
FX["Effects<br/>debris · firework · score · trail"]
|
||||
end
|
||||
|
||||
DIR --> SDLM
|
||||
DIR --> GE
|
||||
DIR --> OVL
|
||||
DIR --> SCN
|
||||
SCN --> ENT
|
||||
SCN --> SYS
|
||||
SCN --> STG
|
||||
SCN --> FX
|
||||
GE --> INPUT
|
||||
SCN -.usa.-> AUDIO
|
||||
SCN -.usa.-> RES
|
||||
OVL -.usa.-> LOC
|
||||
```
|
||||
|
||||
**Patrón dominante de comunicación:** singletons globales (`Input::get()`,
|
||||
`Audio::get()`, `Locale::get()`, `Notifier`, `ServiceMenu`) más paso por
|
||||
referencia de un `Rendering::Renderer*` y un `SceneContext&`. **No hay** un bus de
|
||||
eventos genérico ni un ECS — las entidades viven en `std::array` de tamaño fijo
|
||||
dentro de `GameScene` y los sistemas operan sobre un struct `Context` de punteros
|
||||
(ver [§10](#10-lógica-del-juego)).
|
||||
|
||||
**Rasgo de diseño destacable:** gran parte de la lógica es *data-driven*. Los
|
||||
enemigos, balas y el jugador se describen en **YAML declarativo**
|
||||
(`data/entities/*/*.yaml`: physics/ai/animation/events), los stages en
|
||||
`data/stages/stages.yaml` (oleadas), y las figuras vectoriales en ficheros `.shp`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Punto de entrada y el Director
|
||||
|
||||
El `main` real está en [main.cpp](source/main.cpp) y usa el modo de callbacks de
|
||||
SDL3 (`#define SDL_MAIN_USE_CALLBACKS 1`). En lugar de un bucle `while` clásico,
|
||||
SDL llama a cuatro funciones, y todas son pura fontanería que delega en un
|
||||
`Director`:
|
||||
|
||||
```cpp
|
||||
// main.cpp
|
||||
auto SDL_AppInit(void** appstate, int argc, char* argv[]) -> SDL_AppResult {
|
||||
System::Relaunch::setArgv(argc, argv);
|
||||
auto director = std::make_unique<Director>(argc, argv);
|
||||
*appstate = director.release(); // SDL guarda el puntero
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
auto SDL_AppEvent(void* s, SDL_Event* e) { return ((Director*)s)->handleEvent(*e); }
|
||||
auto SDL_AppIterate(void* s) { return ((Director*)s)->iterate(); }
|
||||
void SDL_AppQuit(void* s, ...) { /* reabsorbe y destruye el Director */ }
|
||||
```
|
||||
|
||||
La filosofía está escrita en el propio comentario de cabecera de
|
||||
[director.hpp](source/core/system/director.hpp):
|
||||
|
||||
> *El Director és EL programa: posseeix la configuració, els subsistemes i
|
||||
> l'estat.*
|
||||
|
||||
Como con `SDL_MAIN_USE_CALLBACKS` no hay un `scope` que envuelva todo el bucle,
|
||||
el estado que antes vivía en un `run()` ahora es **miembro** del Director:
|
||||
`sdl_` (SDLManager), `context_` (SceneContext), `debug_overlay_` y
|
||||
`current_scene_` (todos `std::unique_ptr`, ver
|
||||
[director.hpp:45-48](source/core/system/director.hpp#L45-L48)).
|
||||
|
||||
### Orden de arranque (constructor)
|
||||
|
||||
El constructor [Director::Director](source/core/system/director.cpp#L46) ejecuta el
|
||||
bootstrap completo, en este orden:
|
||||
|
||||
1. `ConfigYaml::init()` — valores por defecto de configuración.
|
||||
2. Parseo de argumentos (`--console`, `--reset-config`) en
|
||||
[checkProgramArguments](source/core/system/director.cpp#L241).
|
||||
3. `Utils::initializePathSystem()` + sistema de recursos
|
||||
([§8](#8-recursos)): en *release* el `resources.pack` es obligatorio; en *dev*
|
||||
hay fallback a `data/`.
|
||||
4. Crea la carpeta de sistema (`~/.config/jailgames/<NAME>` en Linux) y carga/crea
|
||||
`config.yaml` ([createSystemFolder](source/core/system/director.cpp#L260)).
|
||||
5. Carga el `locale` ([§7](#7-audio) usa lo mismo: i18n).
|
||||
6. `Input::init()` con el `gamecontrollerdb.txt` (autoasigna mandos a P1/P2 la
|
||||
primera vez).
|
||||
7. Crea `SDLManager` (ventana + GPU), oculta el cursor, inicializa `Audio`.
|
||||
8. **Precarga bloqueante** de todos los recursos (música, sonidos, shapes) para
|
||||
evitar tirones de I/O en las transiciones
|
||||
([director.cpp:187-195](source/core/system/director.cpp#L187-L195)).
|
||||
9. Crea el `SceneContext` y fija la escena inicial: `TITLE` en `_DEBUG`, `LOGO`
|
||||
en el resto ([director.cpp:200-205](source/core/system/director.cpp#L200-L205)).
|
||||
10. Inicializa los overlays de sistema: `DebugOverlay`, `Notifier`, `ServiceMenu`,
|
||||
`DefineInputs`.
|
||||
|
||||
El destructor [Director::~Director](source/core/system/director.cpp#L218) guarda
|
||||
la config y destruye los subsistemas **en orden inverso** a la construcción (el
|
||||
`Notifier` referencia el renderer, así que debe morir antes que `sdl_`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Bucle principal
|
||||
|
||||
Cada frame, SDL llama a `SDL_AppIterate`, que delega en
|
||||
[Director::iterate()](source/core/system/director.cpp#L383). Su estructura es:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SDL
|
||||
participant Dir as Director::iterate()
|
||||
participant Scene
|
||||
participant SDLM as SDLManager
|
||||
participant GPU as GpuFrameRenderer
|
||||
|
||||
SDL->>Dir: iterate()
|
||||
Note over Dir: si wants_quit_ → SDL_APP_SUCCESS
|
||||
Dir->>Dir: si !scene o scene.isFinished() → advanceScene()
|
||||
Dir->>Dir: delta_time = (now - last) capeado a 50 ms
|
||||
Dir->>Dir: Input::update()
|
||||
Dir->>Scene: update(dt)
|
||||
Dir->>Dir: overlays.update(dt) + Audio::update()
|
||||
Dir->>SDLM: clear() (= GPU.beginFrame)
|
||||
alt swapchain no disponible
|
||||
SDLM-->>Dir: false → saltar draw+present
|
||||
end
|
||||
Dir->>SDLM: updateRenderingContext()
|
||||
Dir->>Scene: draw()
|
||||
Dir->>Dir: overlays.draw() (capas)
|
||||
Dir->>SDLM: present() (= GPU.endFrame → bloom + postfx)
|
||||
```
|
||||
|
||||
Puntos concretos a tener en cuenta:
|
||||
|
||||
- **Pivot de escena**: si no hay escena o la actual reporta `isFinished()`, se
|
||||
llama a [advanceScene()](source/core/system/director.cpp#L338), que destruye la
|
||||
actual y construye la siguiente con
|
||||
[buildScene()](source/core/system/director.cpp#L323) según
|
||||
`context_->nextScene()`.
|
||||
- **Delta time**: se mide con `SDL_GetTicks()` y se **capea a 50 ms** para evitar
|
||||
saltos grandes tras un stall ([director.cpp:397-400](source/core/system/director.cpp#L397-L400)).
|
||||
- **Orden de update**: `Input::update()` → `current_scene_->update(dt)` →
|
||||
`debug_overlay_` → `Notifier` → `ServiceMenu` → `DefineInputs` → `Audio::update()`.
|
||||
- **Render por capas** (de abajo arriba, entre `clear` y `present`):
|
||||
escena → `debug_overlay_` → `Notifier` (toasts) → `ServiceMenu` → `DefineInputs`
|
||||
(modal de rebinding). Si el overlay de rebinding está activo, el menú de servicio
|
||||
no se pinta ([director.cpp:432-439](source/core/system/director.cpp#L432-L439)).
|
||||
- **Salto de frame**: si `sdl_->clear()` devuelve `false` (swapchain no disponible,
|
||||
p. ej. ventana minimizada), se omiten `draw` y `present` ese frame.
|
||||
|
||||
El bucle de eventos vive aparte, en
|
||||
[Director::handleEvent()](source/core/system/director.cpp#L354), que enruta cada
|
||||
`SDL_Event` por la cadena: **ventana → GlobalEvents → F11 (debug overlay) →
|
||||
escena** (ver [§9](#9-comunicación-entre-módulos)).
|
||||
|
||||
---
|
||||
|
||||
## 4. Sistema de escenas
|
||||
|
||||
La interfaz base es [scene.hpp](source/core/system/scene.hpp). Como dice su
|
||||
cabecera, *el frame loop vive en el Director, no en cada escena*. Cada escena
|
||||
implementa cuatro métodos puros:
|
||||
|
||||
```cpp
|
||||
virtual void handleEvent(const SDL_Event&) = 0; // eventos no-globales
|
||||
virtual void update(float delta_time) = 0; // lógica
|
||||
virtual void draw() = 0; // pintado (entre clear y present)
|
||||
virtual auto isFinished() const -> bool = 0; // ¿transición pendiente?
|
||||
```
|
||||
|
||||
Una escena pide transición vía `context_.setNextScene(...)`; en el siguiente frame
|
||||
`isFinished()` devuelve `true` y el Director la destruye para construir la
|
||||
siguiente.
|
||||
|
||||
### SceneContext
|
||||
|
||||
[scene_context.hpp](source/core/system/scene_context.hpp) es el "buzón" de
|
||||
transición que el Director posee y va pasando a cada escena por referencia. Tiene:
|
||||
|
||||
- `SceneType` (enum): `LOGO`, `TITLE`, `GAME`, `EXIT`.
|
||||
- `Option` (p. ej. `JUMP_TO_TITLE_MAIN`) consumible con `consumeOption()`.
|
||||
- `MatchConfig` (jugadores activos, modo NORMAL/DEMO) para pasar a `GAME`.
|
||||
- El **índice del escenario de demo** (`demoScenarioIndex()` / `advanceDemoScenario()`),
|
||||
que persiste entre escenas para que cada entrada al attract mode muestre el
|
||||
siguiente escenario curado (ver [§11](#11-ia-del-modo-demo-attract)).
|
||||
|
||||
Existe además una variable global `SceneManager::actual` que el Director mantiene
|
||||
sincronizada con la escena en curso (compatibilidad hacia atrás).
|
||||
|
||||
### Las tres escenas (FSM jerárquica)
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> LOGO
|
||||
LOGO --> TITLE
|
||||
TITLE --> GAME : START (1P/2P)
|
||||
TITLE --> GAME : idle timeout (DEMO)
|
||||
GAME --> TITLE : game over / fin demo (input)
|
||||
GAME --> LOGO : fin demo (timeout/muerte)
|
||||
TITLE --> [*] : EXIT
|
||||
```
|
||||
|
||||
Cada escena tiene además su **propia** máquina de estados interna:
|
||||
|
||||
- **[LogoScene](source/game/scenes/logo_scene.hpp)** — `AnimationState`:
|
||||
`PRE_ANIMATION → ANIMATION → POST_ANIMATION → EXPLOSION → POST_EXPLOSION`. Anima
|
||||
el logo JAILGAMES y lo hace explotar en fragmentos (debris).
|
||||
- **[TitleScene](source/game/scenes/title_scene.hpp)** — `TitleState`:
|
||||
`STARFIELD_FADE_IN → STARFIELD → MAIN → PLAYER_JOIN_PHASE → BLACK_SCREEN →
|
||||
DEMO_DIVE → DEMO_CURTAIN`. Naves 3D flotantes (vía
|
||||
[ShipAnimator](source/game/title/ship_animator.hpp)), selección 1P/2P, y un
|
||||
`idle_timer_` en el estado `MAIN` que dispara el attract mode por inactividad.
|
||||
- **[GameScene](source/game/scenes/game_scene.hpp)** — es el núcleo del juego y se
|
||||
detalla en [§10](#10-lógica-del-juego).
|
||||
|
||||
---
|
||||
|
||||
## 5. Renderizado: de la lógica al píxel
|
||||
|
||||
Este es el subsistema más denso. La idea central: **toda la geometría son líneas**
|
||||
(la estética es vectorial). El juego acumula líneas en CPU durante `draw()`, y al
|
||||
final del frame se envían a la GPU en un único batch, se rasterizan a una textura
|
||||
*offscreen*, y un par de pases de post-procesado (bloom + flicker/fondo) componen
|
||||
la imagen final sobre la swapchain.
|
||||
|
||||
### 5.1 Capas del subsistema
|
||||
|
||||
| Fichero | Rol |
|
||||
|---|---|
|
||||
| [sdl_manager.hpp/.cpp](source/core/rendering/sdl_manager.hpp) | Crea la ventana SDL, posee el `GpuFrameRenderer`, gestiona zoom/fullscreen/letterbox. Expone `clear()` / `present()` / `getRenderer()`. |
|
||||
| [gpu/gpu_frame_renderer.hpp/.cpp](source/core/rendering/gpu/gpu_frame_renderer.hpp) | Orquestador del frame GPU: `beginFrame` → `pushLine`/`pushRect` → `endFrame` (`flushBatch` + `bloomPass` + `compositePass`). |
|
||||
| [gpu/gpu_device](source/core/rendering/gpu/gpu_device.hpp) | Wrapper del `SDL_GPUDevice` (claim de ventana, formato de swapchain). |
|
||||
| [gpu/gpu_line_pipeline](source/core/rendering/gpu/gpu_line_pipeline.hpp) | Pipeline de líneas: dibuja cada línea como un quad (2 triángulos) con antialias geométrico. |
|
||||
| [gpu/gpu_bloom_pipeline](source/core/rendering/gpu/gpu_bloom_pipeline.hpp) | Blur gaussiano separable (pase H + pase V) sobre dos texturas ping-pong. |
|
||||
| [gpu/gpu_postfx_pipeline](source/core/rendering/gpu/gpu_postfx_pipeline.hpp) | Composite final: mezcla escena + bloom + flicker + fondo pulsante. |
|
||||
| [line_renderer.hpp/.cpp](source/core/rendering/line_renderer.hpp) | API que usa el juego: `Rendering::linea(...)` y `lineaGlow(...)`. |
|
||||
| [shape_renderer.hpp/.cpp](source/core/rendering/shape_renderer.hpp) | `renderShape(...)`: dibuja una `Shape` aplicando transformación y, opcionalmente, glow multipase. |
|
||||
|
||||
### 5.2 Una `Shape` y cómo se carga
|
||||
|
||||
Una "shape" es una figura vectorial: un conjunto de **polilíneas** y **líneas**
|
||||
([shape.hpp](source/core/graphics/shape.hpp)). Los ficheros viven en `data/shapes/`
|
||||
con extensión `.shp` y un formato de texto tipo clave:valor. Ejemplo real
|
||||
([data/shapes/ship/arrow.shp](data/shapes/ship/arrow.shp)):
|
||||
|
||||
```
|
||||
name: arrow
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
polyline: 0,-12 8.49,8.49 0,4 -8.49,8.49 0,-12
|
||||
```
|
||||
|
||||
> Nota: el formato real usa directivas `name:`, `scale:`, `center:`,
|
||||
> `polyline:` y `line:` (Y negativo = arriba). No es la sintaxis
|
||||
> `POLYLINE: (x,y)` que podría suponerse de otros motores.
|
||||
|
||||
La carga la centraliza [shape_loader.hpp](source/core/graphics/shape_loader.hpp)
|
||||
(`Graphics::ShapeLoader::load(filename)`), con caché de `std::shared_ptr<Shape>`.
|
||||
Todas las shapes se precargan en el boot del Director.
|
||||
|
||||
### 5.3 El flujo de un frame de render
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A["Scene::draw()<br/>(acumula en CPU)"] --> B["Rendering::linea / renderShape"]
|
||||
B --> C["GpuFrameRenderer::pushLine()<br/>extruye quad → vertices_ / indices_"]
|
||||
C -.repetido N veces.-> C
|
||||
A --> D["SDLManager::present()<br/>= GpuFrameRenderer::endFrame()"]
|
||||
D --> E["flushBatch()<br/>sube VBO/IBO, dibuja sobre OFFSCREEN"]
|
||||
E --> F["bloomPass()<br/>H: high-pass+blur → bloom_a<br/>V: blur → bloom_b"]
|
||||
F --> G["compositePass()<br/>offscreen + bloom_b + flicker + fondo<br/>→ swapchain (letterbox)"]
|
||||
G --> H["SubmitGPUCommandBuffer + present"]
|
||||
```
|
||||
|
||||
Paso a paso, con anclas reales:
|
||||
|
||||
1. **Emisión (juego).** Durante `current_scene_->draw()`, el juego llama a
|
||||
[Rendering::linea()](source/core/rendering/line_renderer.hpp#L33) (y
|
||||
`renderShape`, `VectorText`, `Playfield`, etc.). Las coordenadas son **lógicas
|
||||
(1280×720)**. El color por defecto si `alpha==0` es el verde fósforo CRT
|
||||
`DEFAULT_LINE_COLOR = {100,255,100,255}`.
|
||||
2. **Acumulación (CPU).** `linea()` pre-multiplica el brillo y llama a
|
||||
[GpuFrameRenderer::pushLine()](source/core/rendering/gpu/gpu_frame_renderer.hpp#L88),
|
||||
que **extruye** la línea en un quad (4 vértices, 6 índices) y lo acumula en
|
||||
`vertices_` / `indices_`. Si el antialias está activo, añade ~0.5 px de padding y
|
||||
marca `edge_dist` para el fade del fragment shader.
|
||||
3. **Flush (GPU).** En `endFrame()`, `flushBatch()` sube el batch a un VBO/IBO,
|
||||
abre un render pass sobre el `offscreen_texture_` (R8G8B8A8, tamaño físico
|
||||
configurable, independiente del lógico) y dibuja con el `line_pipeline_`. El
|
||||
vertex shader transforma píxeles lógicos → NDC; el fragment shader aplica
|
||||
`smoothstep` sobre `edge_dist` para el suavizado.
|
||||
4. **Bloom.** `bloomPass()` hace un blur separable: pase H (high-pass por
|
||||
luminancia + blur horizontal → `bloom_texture_a_`) y pase V (blur vertical →
|
||||
`bloom_texture_b_`). Parámetros en `PostFxParams`
|
||||
([gpu_frame_renderer.hpp:33-51](source/core/rendering/gpu/gpu_frame_renderer.hpp#L33-L51)).
|
||||
5. **Composite.** `compositePass()` dibuja un triángulo *fullscreen* sobre la
|
||||
swapchain, muestreando offscreen + bloom, aplicando flicker temporal y un fondo
|
||||
verde pulsante. Aquí se aplica el **letterbox** vía el viewport físico
|
||||
(`setViewport`).
|
||||
|
||||
El interruptor maestro de post-proceso es **F6** (`setPostFxEnabled`): cuando está
|
||||
OFF, la escena offscreen sale tal cual (passthrough), útil para A/B testing.
|
||||
|
||||
### 5.4 Texto, 3D y elementos de escena
|
||||
|
||||
- **[VectorText](source/core/graphics/vector_text.hpp)** — renderiza texto donde
|
||||
cada carácter es una `Shape` precargada.
|
||||
- **[Camera3D](source/core/graphics/camera3d.hpp)** + **[Wireframe3D](source/core/graphics/wireframe3d.hpp)**
|
||||
— proyección perspectiva en CPU de mallas 3D (vértices + aristas) a líneas 2D.
|
||||
Lo usan el starfield 3D y las naves del título.
|
||||
- **[Starfield](source/core/graphics/starfield.hpp)** (campo de estrellas 3D que
|
||||
vienen hacia la cámara) y **[StarfieldParallax](source/core/graphics/starfield_parallax.hpp)**
|
||||
(capas 2D de fondo con parallax).
|
||||
- **[Playfield](source/core/graphics/playfield.hpp)** — rejilla de fondo con
|
||||
animación de construcción y *ripples* (ondas) que reaccionan a la nave y a las
|
||||
explosiones.
|
||||
- **[Border](source/core/graphics/border.hpp)** — marco de 4 lados que se desplaza
|
||||
al recibir impactos.
|
||||
- **[Curtain](source/core/graphics/curtain.hpp)** — cortinilla negra para
|
||||
transiciones; se pinta siempre la última.
|
||||
|
||||
### 5.5 Shaders: fuentes, compilación y selección
|
||||
|
||||
Las fuentes GLSL viven en [shaders/](shaders/): `line.vert.glsl`, `line.frag.glsl`,
|
||||
`postfx.vert.glsl`, `postfx.frag.glsl`, `bloom.frag.glsl`. **No se cargan de disco en
|
||||
runtime**: se embeben como arrays/strings en el binario.
|
||||
|
||||
**Pipeline de compilación (SPIR-V, Linux/Windows).** Lo orquesta
|
||||
[CMakeLists.txt:139-187](CMakeLists.txt#L139). La lógica clave:
|
||||
|
||||
- Para cada `.glsl` hay un header destino en
|
||||
[gpu/spv/](source/core/rendering/gpu/spv/) (p. ej. `line_vert_spv.h`).
|
||||
- CMake busca `glslc` (`find_program(GLSLC_EXE ...)`). Hay **tres caminos**:
|
||||
1. `glslc` presente → un `add_custom_command` regenera los headers SPV cuando
|
||||
cambian los `.glsl`, vía el target `shaders` del que depende el ejecutable.
|
||||
2. `glslc` ausente pero **los headers ya están commiteados** → se usan tal cual
|
||||
(los `.spv.h` están versionados en el repo).
|
||||
3. `glslc` ausente **y** faltan headers → `FATAL_ERROR` pidiendo instalar
|
||||
`shaderc`/`vulkan-sdk`.
|
||||
- La conversión binario→header la hace el script
|
||||
[tools/shaders/compile_spirv.cmake](tools/shaders/compile_spirv.cmake): invoca
|
||||
`glslc -O -fshader-stage=<vert|frag>` para producir el `.spv`, lee el binario como
|
||||
hex (`file(READ ... HEX)`) y escribe un header con
|
||||
`static const uint8_t LINE_VERT_SPV[] = { 0x.., ... };` y su `_SIZE`. Es
|
||||
multiplataforma puro CMake (no necesita `bash` ni `xxd`).
|
||||
|
||||
**MSL (macOS).** Los headers Metal en [gpu/msl/](source/core/rendering/gpu/msl/)
|
||||
(`line_vert.msl.h`, etc.) están **escritos a mano** (no los genera CMake), como
|
||||
strings literales C++.
|
||||
|
||||
**Selección SPV vs MSL: es _compile-time_, no runtime.** La hace
|
||||
[shader_factory.hpp](source/core/rendering/gpu/shader_factory.hpp) con `#ifdef __APPLE__`:
|
||||
en Apple expone `createShaderMSL(...)` (`SDL_GPU_SHADERFORMAT_MSL`), y en el resto
|
||||
`createShaderSPIRV(...)` (`SDL_GPU_SHADERFORMAT_SPIRV`). Cada pipeline llama al helper
|
||||
disponible con el header embebido correspondiente. (Es decir: no es `GpuDevice` quien
|
||||
elige el backend de shader, sino el preprocesador al compilar.)
|
||||
|
||||
---
|
||||
|
||||
## 6. Entrada
|
||||
|
||||
El subsistema de input ([core/input/](source/core/input/)) es un **singleton**
|
||||
(`Input::init()` / `Input::get()` / `Input::destroy()`) que unifica teclado,
|
||||
gamepads y ratón.
|
||||
|
||||
- **Acciones**: enum `InputAction` (`LEFT`, `RIGHT`, `THRUST`, `SHOOT`, `START`,
|
||||
`MENU`, ...) en [input_types.hpp](source/core/input/input_types.hpp).
|
||||
- **Bindings por jugador**: hay bindings separados de teclado y de gamepad para P1
|
||||
y P2, que se cargan de la config con `applyPlayer1Bindings()` /
|
||||
`applyPlayer2Bindings()` (llamados desde el constructor del Director).
|
||||
- **Captura por frame**: `Input::update()` lee `SDL_GetKeyboardState()` y los ejes
|
||||
y botones del gamepad, y hace *edge-detection* para distinguir `just_pressed` de
|
||||
`is_held`. La consulta es `checkAction(...)` / `checkActionPlayer1/2(...)`.
|
||||
- **Hotplug**: `Input::handleEvent()` procesa `SDL_EVENT_GAMEPAD_ADDED/REMOVED`
|
||||
(`addGamepad` / `removeGamepad`) y notifica con un toast vía `Notifier`.
|
||||
- **Ratón**: [mouse.hpp](source/core/input/mouse.hpp) auto-oculta el cursor.
|
||||
- **Rebinding en runtime**: [define_inputs.hpp](source/core/input/define_inputs.hpp)
|
||||
es un modal singleton que captura una secuencia de acciones, persiste en config y
|
||||
reaplica bindings sin reiniciar.
|
||||
|
||||
El enrutado de input ocurre en dos sitios: los eventos **globales** pasan por
|
||||
`GlobalEvents::handle()` (que primero deja a `Input` procesar el hotplug), y la
|
||||
lógica de juego consulta directamente `Input::get()->checkAction...` durante
|
||||
`update()` (p. ej. [Ship::processInput](source/game/entities/ship.hpp)).
|
||||
|
||||
---
|
||||
|
||||
## 7. Audio
|
||||
|
||||
[core/audio/](source/core/audio/) es otro singleton (`Audio::init/get/destroy`)
|
||||
con un motor de bajo nivel propio:
|
||||
|
||||
- **[Audio](source/core/audio/audio.hpp)** — capa lógica: `playMusic()`,
|
||||
`playSound()`, volúmenes por grupo (`GAME`, `INTERFACE`), `playSoundWithEcho/Reverb`.
|
||||
- **[jail_audio.hpp](source/core/audio/jail_audio.hpp)** (`Ja::Engine`) — motor
|
||||
sobre SDL3 audio: streaming de **OGG** (vía `stb_vorbis`) para música, **WAV**
|
||||
descomprimido para efectos, mezcla en N canales.
|
||||
- **[audio_adapter.hpp](source/core/audio/audio_adapter.hpp)** —
|
||||
`AudioResource::getMusic/getSound`: caché *lazy* que carga bytes vía
|
||||
`Resource::Helper` y los decodifica una sola vez.
|
||||
- **[audio_effects.hpp](source/core/audio/audio_effects.hpp)** — DSP de echo y
|
||||
reverb; presets en `data/config/sounds.yaml`
|
||||
([sound_effects_config.hpp](source/core/audio/sound_effects_config.hpp)).
|
||||
|
||||
El Director precarga toda la música y todos los sonidos en el boot, y llama a
|
||||
`Audio::update()` una vez por frame.
|
||||
|
||||
---
|
||||
|
||||
## 8. Recursos
|
||||
|
||||
[core/resources/](source/core/resources/) abstrae de dónde salen los bytes:
|
||||
|
||||
- **[resource_pack](source/core/resources/resource_pack.hpp)** (`Resource::Pack`)
|
||||
— lee un fichero empaquetado con cabecera *magic* `"ORNI"` y entradas con CRC32
|
||||
para validación de integridad.
|
||||
- **[resource_loader](source/core/resources/resource_loader.hpp)**
|
||||
(`Resource::Loader`, singleton Meyers) — `loadResource()`, `resourceExists()`,
|
||||
`listResources(prefix)`, `validatePack()`.
|
||||
- **[resource_helper](source/core/resources/resource_helper.hpp)** — wrappers de
|
||||
conveniencia (`initializeResourceSystem`, `listResources`, `loadFile`).
|
||||
|
||||
**Estrategia dual** (decidida en el constructor del Director,
|
||||
[director.cpp:64-93](source/core/system/director.cpp#L64-L93)):
|
||||
|
||||
- **Release** (`RELEASE_BUILD`): `resources.pack` es **obligatorio** y se valida su
|
||||
integridad; si falla, el juego aborta. No hay fallback (ver memoria de proyecto
|
||||
*"No fallback a SDL_Renderer"* — aquí es la política equivalente para recursos).
|
||||
- **Dev**: intenta el pack; si no está, hace **fallback al directorio `data/`** del
|
||||
filesystem, escaneándolo según prefijo (`music/`, `sounds/`, `shapes/`).
|
||||
|
||||
El formato de datos de juego:
|
||||
|
||||
- **Entidades** (`data/entities/<nombre>/<nombre>.yaml`) — YAML declarativo con
|
||||
`shape`, `physics`, `ai`, `animation`, `wounded`, `spawn`, `colors`, `score`,
|
||||
`events`. Ejemplo: [data/entities/square/square.yaml](data/entities/square/square.yaml).
|
||||
- **Stages** (`data/stages/stages.yaml`) — oleadas (`waves`) con `spawn`,
|
||||
`spawn_interval`, `next` y multiplicadores de dificultad por stage.
|
||||
- **Shapes** (`data/shapes/**/*.shp`) — figuras vectoriales (ver [§5.2](#52-una-shape-y-cómo-se-carga)).
|
||||
|
||||
El parser YAML usado es [fkyaml](source/external/fkyaml_node.hpp) (cabecera única),
|
||||
envuelto por [config_yaml](source/game/config_yaml.hpp).
|
||||
|
||||
---
|
||||
|
||||
## 9. Comunicación entre módulos
|
||||
|
||||
No hay un sistema de mensajería desacoplado. La comunicación es:
|
||||
|
||||
1. **Eventos SDL → cadena del Director.** Por cada `SDL_Event`,
|
||||
[Director::handleEvent](source/core/system/director.cpp#L354) intenta, en orden:
|
||||
`SDLManager::handleWindowEvent` → `GlobalEvents::handle` → F11 (debug overlay) →
|
||||
`current_scene_->handleEvent`.
|
||||
|
||||
2. **GlobalEvents** ([global_events.cpp](source/core/system/global_events.cpp)) es
|
||||
el orquestador de la entrada global. Su `handle()` hace, en orden:
|
||||
`Input::get()->handleEvent` (hotplug) → `consumeIfDefineActive` (si el modal de
|
||||
rebinding está activo, **engulle todo**) → `SDL_EVENT_QUIT` → ratón → botón MENU
|
||||
del mando → reenvío al `ServiceMenu` si está abierto → teclas de función:
|
||||
|
||||
| Tecla | Acción |
|
||||
|---|---|
|
||||
| F1 / F2 | reducir / aumentar tamaño de ventana |
|
||||
| F3 | fullscreen |
|
||||
| F4 | VSync |
|
||||
| F5 | antialias geométrico |
|
||||
| F6 | post-procesado (bloom/flicker/fondo) |
|
||||
| F7 | idioma ca ↔ en (hot-swap de `Locale`) |
|
||||
| F11 | debug overlay (gestionado en el Director, no en GlobalEvents) |
|
||||
| F12 | menú de servicio |
|
||||
| ESC | doble pulsación para salir (la 1ª muestra un toast de confirmación) |
|
||||
|
||||
3. **Singletons compartidos.** `Input`, `Audio`, `Locale`, `Notifier`,
|
||||
`ServiceMenu`, `DefineInputs` se acceden globalmente vía `::get()`. Muchos
|
||||
comprueban `nullptr` para degradar con elegancia (p. ej. el hotplug notifica
|
||||
solo si `Notifier::get() != nullptr`).
|
||||
|
||||
4. **Paso por referencia.** Las escenas reciben `SDLManager&` y `SceneContext&`; el
|
||||
render se propaga como `Rendering::Renderer*`. Los sistemas de juego reciben un
|
||||
struct `Context` con punteros a los pools (ver [§10](#10-lógica-del-juego)).
|
||||
|
||||
**Overlays de sistema** (todos singletons, todos por encima de la escena):
|
||||
|
||||
- **[Notifier](source/core/system/notifier.hpp)** — toasts deslizantes centrados
|
||||
(`notifyInfo/Warn/Exit`), con máquina de animación HIDDEN/ENTERING/HOLDING/EXITING.
|
||||
- **[ServiceMenu](source/core/system/service_menu.hpp)** — menú de configuración
|
||||
(F12) con pila de páginas (vídeo, audio, controles, sistema...).
|
||||
- **[DebugOverlay](source/core/system/debug_overlay.hpp)** — HUD de FPS/VSync (F11).
|
||||
- **[Relaunch](source/core/system/relaunch.hpp)** — reinicio en caliente vía
|
||||
`execv` (lo solicita el ServiceMenu, lo ejecuta `SDL_AppQuit`).
|
||||
|
||||
**Lo que NO existe** (verificado): no hay event bus genérico, ni cola de mensajes
|
||||
desacoplada, ni un FSM genérico reutilizable fuera de las máquinas de estado
|
||||
concretas de cada escena/sistema, ni un ECS.
|
||||
|
||||
---
|
||||
|
||||
## 10. Lógica del juego
|
||||
|
||||
Toda la partida vive en [GameScene](source/game/scenes/game_scene.hpp). Es la clase
|
||||
más grande del juego y actúa como orquestador. Posee:
|
||||
|
||||
- El mundo físico [Physics::PhysicsWorld](source/core/physics/physics_world.hpp)
|
||||
(integración cinemática + colisiones físicas).
|
||||
- Pools de tamaño **fijo**: `std::array<Ship, 2>`,
|
||||
`std::array<Enemy, MAX_ORNIS>` (15), `std::array<Bullet, MAX_BULLETS_TOTAL>` (6:
|
||||
P1=[0,1,2], P2=[3,4,5]).
|
||||
- Estado de partida: vidas, score y *death timers* por jugador, máquina de
|
||||
game over (`GameOverState`: `NONE/CONTINUE/GAME_OVER`), continues usados.
|
||||
- El stage system, los efectos visuales, y los `DemoPilot` (uno por nave).
|
||||
|
||||
### 10.1 Orquestación por frame
|
||||
|
||||
[GameScene::update()](source/game/scenes/game_scene.cpp) es un orquestador delgado;
|
||||
cada paso es una función privada (descompuesto para reducir complejidad cognitiva):
|
||||
|
||||
```cpp
|
||||
void GameScene::update(float dt) {
|
||||
if (ServiceMenu abierto) return; // pausa global (draw sí sigue)
|
||||
stepPhysics(dt);
|
||||
if (mode == DEMO) { if (stepDemo(dt)) return; }
|
||||
else if (game_over_state_ == NONE) { stepShootingInput(); stepMidGameJoin(); }
|
||||
if (stepContinueScreen(dt)) return;
|
||||
if (stepGameOver(dt)) return;
|
||||
stepDeathSequence(dt);
|
||||
stepStageStateMachine(dt);
|
||||
}
|
||||
```
|
||||
|
||||
El corazón del gameplay es
|
||||
[stepStageStateMachine](source/game/scenes/game_scene.hpp#L166), que despacha según
|
||||
el estado del stage; en `PLAYING`,
|
||||
[runStagePlaying](source/game/scenes/game_scene.hpp#L169) ejecuta: WaveRunner
|
||||
(spawns) → IA de cada enemigo → control de naves
|
||||
([updateShipsControl](source/game/scenes/game_scene.cpp), que en demo usa
|
||||
`applyMovement` con el control del pilot y fuera de demo usa `processInput`) →
|
||||
detección de colisiones ([runCollisionDetections](source/game/scenes/game_scene.hpp#L176)).
|
||||
|
||||
`draw()` despacha de forma análoga según `GameOverState` y el estado del stage, y
|
||||
siempre pinta la cortinilla al final.
|
||||
|
||||
### 10.2 Entidades
|
||||
|
||||
Las tres heredan de `Entities::Entity` ([entity.hpp](source/core/entities/entity.hpp)):
|
||||
|
||||
- **[Ship](source/game/entities/ship.hpp)** — nave del jugador. `processInput()`
|
||||
(humano) y `applyMovement()` (usado por la IA demo). Estados: activa,
|
||||
invulnerable (parpadeo tras spawn), herida (`hurt`). Al morir genera debris con
|
||||
la inercia heredada.
|
||||
- **[Enemy](source/game/entities/enemy.hpp)** — 5 tipos (`EnemyType`: `PENTAGON`,
|
||||
`SQUARE`, `PINWHEEL`, `STAR`, `ORB`). Toda su config (físicas, IA, animación,
|
||||
eventos) viene del **YAML** vía [EnemyRegistry](source/game/entities/enemy_registry.hpp).
|
||||
Tiene salud (la mayoría HP=1; `ORB` HP=10) y estado *wounded* (parpadeo).
|
||||
- **[Bullet](source/game/entities/bullet.hpp)** — con `owner_id` (0=P1, 1=P2,
|
||||
≥16=enemigo) y `prev_position` para colisión *swept* (la bala que cruza un enemigo
|
||||
entre dos frames). Config en [BulletRegistry](source/game/entities/bullet_registry.hpp).
|
||||
|
||||
### 10.3 IA de enemigos: declarativa
|
||||
|
||||
Los enemigos **no** tienen comportamiento hardcoded. El YAML describe:
|
||||
|
||||
- Una **primitiva de movimiento** (`MovementType` en
|
||||
[enemy_ai.hpp](source/game/entities/enemy_ai.hpp)): `ZIGZAG`, `TRACKING`,
|
||||
`RECTILINEAR_PROXIMITY`, `WANDER`, `CHASE`, `FLEE`.
|
||||
- **Acciones de tick** periódicas (p. ej. `SHOOT`).
|
||||
- **Eventos** (`on_hit`, `on_no_health`, `on_hurt_end`, `on_destroy`) con acciones
|
||||
(`APPLY_IMPULSE`, `DECREASE_HEALTH`, `CREATE_DEBRIS`, `ADD_SCORE`, `FLASH`,
|
||||
`FIRE_BULLET`, `DESTROY`, ...).
|
||||
|
||||
Dos sistemas los ejecutan:
|
||||
|
||||
- **[EnemyAiSystem](source/game/systems/enemy_ai_system.hpp)** — `move()` aplica la
|
||||
primitiva de movimiento; `tick()` añade las acciones periódicas. Helper
|
||||
`findNearestShipPosition()` para las primitivas que buscan al jugador.
|
||||
- **[EnemyEventDispatcher](source/game/systems/enemy_event_dispatcher.hpp)** —
|
||||
ejecuta las acciones declarativas cuando se dispara un evento.
|
||||
|
||||
### 10.4 Colisiones
|
||||
|
||||
[CollisionSystem](source/game/systems/collision_system.hpp) recibe un struct
|
||||
`Context` (punteros a ships/enemies/bullets, managers de efectos, timers, scores,
|
||||
vidas y un callback `on_player_hit`) que GameScene construye en
|
||||
[buildCollisionContext](source/game/scenes/game_scene.hpp#L174). Detecta:
|
||||
bala↔enemigo, nave↔enemigo, bala↔jugador (fuego amigo / autodisparo), bala
|
||||
enemiga↔nave, y balas fuera del área. Reglas observadas: el primer impacto deja al
|
||||
enemigo *wounded*; el segundo lo destruye y suma score. La nave entra en `hurt` al
|
||||
primer toque y muere al segundo durante ese estado.
|
||||
|
||||
### 10.5 Stages y oleadas
|
||||
|
||||
- **[StageManager](source/game/stage_system/stage_manager.hpp)** — FSM del stage
|
||||
(`EstatStage`): `INIT_HUD` (anima el HUD, 3 s) → `LEVEL_START` ("ENEMY INCOMING",
|
||||
3 s, arranca `game.ogg`) → `PLAYING` → `LEVEL_COMPLETED` ("GOOD JOB COMMANDER!",
|
||||
3 s) → siguiente stage. `initDemo(stage_id)` arranca directamente en `PLAYING`
|
||||
para el attract mode.
|
||||
- **[WaveRunner](source/game/stage_system/wave_runner.hpp)** — emite los enemigos de
|
||||
cada oleada según `spawn_interval` y avanza cuando se cumple `next` (`all_dead`,
|
||||
`timeout`, o ambos).
|
||||
- **[StageConfig](source/game/stage_system/stage_config.hpp)** /
|
||||
[StageLoader](source/game/stage_system/stage_loader.hpp) — modelo y carga del
|
||||
YAML de stages.
|
||||
|
||||
### 10.6 Dos capas de colisión: física vs gameplay
|
||||
|
||||
Conviene no confundirlas, porque conviven:
|
||||
|
||||
**1. Física** — [PhysicsWorld](source/core/physics/physics_world.hpp) /
|
||||
[physics_world.cpp](source/core/physics/physics_world.cpp). Es un mundo 2D
|
||||
minimalista de arcade. Cada frame, `update(dt)` hace tres pasos:
|
||||
|
||||
1. **Integración** semi-implícita de Euler con damping exponencial
|
||||
(`v += (F·invMass)·dt; v *= exp(-damping·dt); x += v·dt`) sobre cada
|
||||
[RigidBody](source/core/physics/rigid_body.hpp) no estático. Un cuerpo con
|
||||
`mass=0` (`inverse_mass=0`) es estático (masa infinita).
|
||||
2. **Rebote contra los bordes** del `PLAYAREA` (`resolveBoundsCollisions`): reposiciona
|
||||
el cuerpo dentro del rect y refleja la componente normal de la velocidad por su
|
||||
`restitution`. Antes de reflejar, invoca un `BoundsHitCallback` opcional con la
|
||||
velocidad de impacto entrante (lo usa GameScene para los efectos de borde).
|
||||
3. **Colisiones cuerpo-cuerpo** (`resolveBodyCollisions`): broadphase trivial
|
||||
**O(n²)** (suficiente para ~23 cuerpos), círculo-círculo, con corrección posicional
|
||||
de penetración + **impulso elástico** `j = -(1+e)(v_rel·n) / (1/mₐ + 1/m_b)`
|
||||
(referencia Box2D / Chris Hecker, en `resolveBodyPair`). Los cuerpos con `radius=0`
|
||||
(las balas, cinemáticas puras) **no** participan aquí.
|
||||
|
||||
Los `RigidBody` los poseen las entidades; el mundo solo guarda punteros no-owning
|
||||
(`addBody`/`removeBody`).
|
||||
|
||||
**2. Gameplay** — [collision_system.cpp](source/game/systems/collision_system.cpp)
|
||||
(ver [§10.4](#104-colisiones)), que decide *qué pasa* (daño, score, muerte). Usa los
|
||||
helpers de [collision.hpp](source/core/physics/collision.hpp): `checkCollision`
|
||||
(círculo-círculo discreto, distancia al cuadrado sin `sqrt`) y `checkCollisionSwept`
|
||||
(segment-círculo, para que una bala rápida no atraviese un enemigo entre frames —
|
||||
*anti-tunneling*). Estos checks usan el `collision_radius` de la **entidad**
|
||||
(con amplificador opcional de hitbox), no el `radius` del body.
|
||||
|
||||
En resumen: la **física** mueve y rebota los cuerpos; el **gameplay** detecta los
|
||||
contactos relevantes para las reglas. Una bala no rebota físicamente (radius 0) pero sí
|
||||
provoca daño vía el check *swept*.
|
||||
|
||||
---
|
||||
|
||||
## 11. IA del modo demo (attract)
|
||||
|
||||
El attract mode es una partida que se juega sola para atraer al jugador. Se activa
|
||||
desde [TitleScene](source/game/scenes/title_scene.hpp) cuando el `idle_timer_` en el
|
||||
estado `MAIN` supera el umbral de inactividad, y desde
|
||||
[GameScene](source/game/scenes/game_scene.hpp) cuando `match_config_.mode == DEMO`.
|
||||
|
||||
La IA vive en [DemoPilot](source/game/systems/demo_pilot.hpp) /
|
||||
[demo_pilot.cpp](source/game/systems/demo_pilot.cpp). Su diseño es explícito en la
|
||||
cabecera: busca **parecer humano, no ser óptimo**. Características clave:
|
||||
|
||||
- **Solo lectura**: `DemoPilot::compute(ship, enemies, bullets, play_area, dt)`
|
||||
devuelve un `Control{left,right,thrust,shoot}`. No lee `Input` ni muta entidades;
|
||||
GameScene aplica el resultado vía `Ship::applyMovement` + `fireBullet`.
|
||||
- **Escenarios curados**: hay 4 (`SCENARIOS` en
|
||||
[demo_pilot.hpp:36-42](source/game/systems/demo_pilot.hpp#L36-L42)): stages
|
||||
`{5,8,6,10}` con 1 o 2 naves IA. El `SceneContext` recuerda el índice y rota al
|
||||
siguiente en cada entrada al demo.
|
||||
|
||||
**Lógica de decisión por prioridad** (verificado en `demo_pilot.cpp`, con sus
|
||||
constantes):
|
||||
|
||||
1. **Esquiva de bala** — si una bala enemiga entrante está dentro de
|
||||
`DODGE_SCAN_RADIUS = 190 px` y viene hacia la nave (`DODGE_HEADING_MIN = 0.25`),
|
||||
maniobra perpendicular a la bala con sesgo al centro (`WALL_BIAS = 0.6`); no
|
||||
dispara mientras esquiva.
|
||||
2. **Sin enemigos** — deriva tranquila (giro lento).
|
||||
3. **Peligro cercano** — si el objetivo está a menos de `DANGER_RADIUS = 95 px`, se
|
||||
aleja con sesgo al centro.
|
||||
4. **Combate** — apuntado con *lead* (`LEAD_TIME = 0.30 s`) más un error humano
|
||||
(`AIM_JITTER_MAX = 0.10 rad`); dispara si el error es menor que
|
||||
`FIRE_TOLERANCE = 0.18 rad` y el cooldown (`FIRE_COOLDOWN = 0.32 s`) lo permite;
|
||||
se acerca si está más lejos que `APPROACH_RADIUS = 250 px`.
|
||||
|
||||
Temporización "humana": reevalúa el objetivo cada `RETARGET_INTERVAL = 0.15 s` y usa
|
||||
una zona muerta de rotación (`ROTATE_DEADZONE = 0.05 rad`) para no oscilar. La demo
|
||||
se rompe con cualquier input (vuelve a TITLE) o por timeout/muerte (vuelve a LOGO),
|
||||
gestionado en [stepDemo](source/game/scenes/game_scene.hpp#L157).
|
||||
|
||||
---
|
||||
|
||||
## 12. Efectos visuales
|
||||
|
||||
Viven en [game/effects/](source/game/effects/) y son managers con pools:
|
||||
|
||||
- **[DebrisManager](source/game/effects/debris_manager.hpp)** — rompe una shape en
|
||||
fragmentos que vuelan radialmente, heredando inercia del cuerpo y, opcionalmente,
|
||||
el impulso de la bala que causó la muerte. Notifica al `Border` (bump) y al
|
||||
`Playfield` (ripple). Lo usan muerte de nave/enemigo, balas fuera de área y las
|
||||
explosiones del logo.
|
||||
- **[FireworkManager](source/game/effects/firework_manager.hpp)** — bursts de fuegos
|
||||
artificiales.
|
||||
- **[FloatingScoreManager](source/game/effects/floating_score_manager.hpp)** —
|
||||
números de puntuación flotantes ("+150").
|
||||
- **[TrailManager](source/game/effects/trail_manager.hpp)** — estela tras las naves.
|
||||
|
||||
---
|
||||
|
||||
## 13. Configuración, constantes y convenciones
|
||||
|
||||
**Configuración:**
|
||||
|
||||
- **[EngineConfig](source/core/config/engine_config.hpp)** — struct POD con
|
||||
ventana, rendering, audio, bindings de jugadores, locale, console. Es la config
|
||||
persistente (`config.yaml`), gestionada por
|
||||
[config_yaml](source/game/config_yaml.hpp) (`ConfigYaml::engine_config`,
|
||||
`loadFromFile`/`saveToFile`).
|
||||
- **[PostFxConfig](source/core/config/postfx_config.hpp)** — carga los `PostFxParams`
|
||||
(bloom/flicker/fondo) desde YAML.
|
||||
- **[GameConfig::MatchConfig](source/core/system/game_config.hpp)** — config no
|
||||
persistente de la partida (jugadores activos, modo NORMAL/DEMO).
|
||||
|
||||
**Constantes y tipos:**
|
||||
|
||||
- **[core/types.hpp](source/core/types.hpp)** — `Vec2` / `Vec3` (agregados con
|
||||
operadores y helpers como `length()`, `normalized()`, `dot()`, `cross()`).
|
||||
- **[core/defaults/](source/core/defaults/)** — un fichero por dominio
|
||||
(`window.hpp`, `rendering.hpp`, `audio.hpp`, `entities.hpp`, `notifier.hpp`...)
|
||||
con todas las constantes por defecto. `game/constants.hpp` reexporta varias como
|
||||
alias (`MAX_ORNIS`, `MAX_BULLETS`, `PI`) y añade helpers de área de juego.
|
||||
|
||||
**Convenciones de código** (de `.clang-tidy`, confirmadas en memoria de proyecto):
|
||||
|
||||
- Métodos en `camelBack`, tipos en `CamelCase`, constantes en `UPPER_CASE`.
|
||||
- Comentarios mayormente en **catalán** (algunos en castellano); el código y los
|
||||
identificadores mezclan catalán/castellano/inglés.
|
||||
- Patrón recurrente: **singletons** con `init/get/destroy` y comprobación de
|
||||
`nullptr` para degradación elegante.
|
||||
- Patrón recurrente: descomposición de funciones grandes (`update`/`draw`) en
|
||||
sub-pasos privados (`stepX`/`runX`/`drawXState`) para mantener baja la complejidad
|
||||
cognitiva.
|
||||
- Análisis estático (cppcheck/clang-tidy) corre vía git hooks
|
||||
([.githooks/](.githooks/)); la política es **arreglar la causa**, no suprimir el
|
||||
diagnóstico.
|
||||
|
||||
---
|
||||
|
||||
## 14. Guía de navegación
|
||||
|
||||
| Si quieres tocar… | Mira… |
|
||||
|---|---|
|
||||
| El arranque, orden de init, o el bucle de frame | [director.cpp](source/core/system/director.cpp) (`Director::iterate` / `handleEvent`) |
|
||||
| Las callbacks de SDL | [main.cpp](source/main.cpp) |
|
||||
| Añadir/cambiar una escena o una transición | [scene.hpp](source/core/system/scene.hpp), [scene_context.hpp](source/core/system/scene_context.hpp), `Director::buildScene` |
|
||||
| Cómo se dibuja una línea / el frame de render | [line_renderer.cpp](source/core/rendering/line_renderer.cpp) → [gpu_frame_renderer.cpp](source/core/rendering/gpu/gpu_frame_renderer.cpp) |
|
||||
| Bloom / flicker / fondo (post-proceso) | [gpu_postfx_pipeline](source/core/rendering/gpu/gpu_postfx_pipeline.hpp), [gpu_bloom_pipeline](source/core/rendering/gpu/gpu_bloom_pipeline.hpp), shaders en [shaders/](shaders/) |
|
||||
| Crear/editar una figura vectorial | `data/shapes/**/*.shp` + [shape_loader.hpp](source/core/graphics/shape_loader.hpp) |
|
||||
| El texto en pantalla | [vector_text.hpp](source/core/graphics/vector_text.hpp) |
|
||||
| Eventos globales (teclas F, ESC, hotplug) | [global_events.cpp](source/core/system/global_events.cpp) |
|
||||
| Controles, bindings, rebinding | [input.cpp](source/core/input/input.cpp), [define_inputs.cpp](source/core/input/define_inputs.cpp) |
|
||||
| Reproducir música/efectos | [audio.hpp](source/core/audio/audio.hpp), [audio_adapter.hpp](source/core/audio/audio_adapter.hpp) |
|
||||
| Cómo se cargan los recursos / el pack | [resource_loader.cpp](source/core/resources/resource_loader.cpp), [resource_pack.cpp](source/core/resources/resource_pack.cpp) |
|
||||
| Reglas de la partida, vidas, game over | [game_scene.cpp](source/game/scenes/game_scene.cpp) |
|
||||
| Comportamiento de un enemigo | su YAML en `data/entities/<tipo>/` + [enemy_ai_system.cpp](source/game/systems/enemy_ai_system.cpp) |
|
||||
| Definir oleadas / dificultad de un nivel | [data/stages/stages.yaml](data/stages/stages.yaml) + [stage_manager.cpp](source/game/stage_system/stage_manager.cpp) |
|
||||
| Colisiones | [collision_system.cpp](source/game/systems/collision_system.cpp) |
|
||||
| La IA del modo demo | [demo_pilot.cpp](source/game/systems/demo_pilot.cpp) |
|
||||
| Explosiones / partículas | [debris_manager.cpp](source/game/effects/debris_manager.cpp) |
|
||||
| El menú de servicio (F12) | [service_menu.cpp](source/core/system/service_menu.cpp) |
|
||||
| Textos traducibles | `data/locale/*.yaml` + [locale.cpp](source/core/locale/locale.cpp) |
|
||||
| Constantes por defecto | [core/defaults/](source/core/defaults/) |
|
||||
|
||||
---
|
||||
|
||||
### Notas de honestidad sobre la cobertura
|
||||
|
||||
- Todas las secciones se verificaron leyendo directamente los ficheros y firmas
|
||||
citados, incluyendo el **pipeline de compilación de shaders**
|
||||
([§5.5](#55-shaders-fuentes-compilación-y-selección): `CMakeLists.txt` +
|
||||
`tools/shaders/compile_spirv.cmake` + `shader_factory.hpp`) y el interior de la
|
||||
**física** ([§10.6](#106-dos-capas-de-colisión-física-vs-gameplay):
|
||||
`physics_world.cpp` + `collision.hpp` + `rigid_body.hpp`).
|
||||
- Lo que **no** se ha trazado a fondo y queda como lectura directa del código si hace
|
||||
falta: los detalles finos de animación de cada overlay (curvas de easing del
|
||||
`Notifier`/`ServiceMenu`) y la coreografía interna completa de `LogoScene` y
|
||||
`TitleScene` (más allá de sus estados). Son descriptivos, no estructurales.
|
||||
</content>
|
||||
</invoke>
|
||||
@@ -1,380 +1,367 @@
|
||||
# ==============================================================================
|
||||
# DIRECTORIES
|
||||
# ==============================================================================
|
||||
DIR_ROOT := $(dir $(abspath $(MAKEFILE_LIST)))
|
||||
DIR_SOURCES := $(addprefix $(DIR_ROOT), source/)
|
||||
DIR_BIN := $(DIR_ROOT)
|
||||
PROJECT := orni
|
||||
BUILDDIR := build
|
||||
|
||||
# ==============================================================================
|
||||
# TARGET NAMES
|
||||
# ==============================================================================
|
||||
# Detecció de plataforma. En Windows CMake defaulteja a "NMake Makefiles"
|
||||
# (que requereix Visual Studio); forcem MinGW Makefiles per usar el g++ de
|
||||
# MinGW. nproc tampoc existeix en cmd.exe → fem servir NUMBER_OF_PROCESSORS.
|
||||
ifeq ($(OS),Windows_NT)
|
||||
TARGET_NAME := $(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'project\s*\x28(\w+)').Matches.Groups[1].Value")
|
||||
LONG_NAME := $(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'PROJECT_LONG_NAME\s+\x22(.+?)\x22').Matches.Groups[1].Value")
|
||||
ifneq ($(MSYSTEM),)
|
||||
NULDEV := /dev/null
|
||||
else
|
||||
NULDEV := NUL
|
||||
endif
|
||||
JOBS ?= $(NUMBER_OF_PROCESSORS)
|
||||
HAS_NINJA := $(shell ninja --version 2>$(NULDEV))
|
||||
ifneq ($(HAS_NINJA),)
|
||||
CMAKE_GEN := -G "Ninja"
|
||||
else
|
||||
CMAKE_GEN := -G "MinGW Makefiles"
|
||||
endif
|
||||
else
|
||||
TARGET_NAME := $(shell awk '/^project/ {gsub(/[)(]/, " "); print $$2}' CMakeLists.txt)
|
||||
LONG_NAME := $(shell grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/')
|
||||
NULDEV := /dev/null
|
||||
JOBS ?= $(shell nproc 2>/dev/null || echo 4)
|
||||
HAS_NINJA := $(shell ninja --version 2>/dev/null)
|
||||
ifneq ($(HAS_NINJA),)
|
||||
CMAKE_GEN := -G "Ninja"
|
||||
else
|
||||
CMAKE_GEN :=
|
||||
endif
|
||||
endif
|
||||
|
||||
TARGET_FILE := $(DIR_BIN)$(TARGET_NAME)
|
||||
RELEASE_FOLDER := $(TARGET_NAME)_release
|
||||
RELEASE_FILE := $(RELEASE_FOLDER)/$(TARGET_NAME)
|
||||
|
||||
# ==============================================================================
|
||||
# VERSION
|
||||
# ==============================================================================
|
||||
# VERSION (única font de veritat: CMakeLists.txt project(...) VERSION ...).
|
||||
# Lazy (=): només es calcula quan s'invoca un target que la usa.
|
||||
ifeq ($(OS),Windows_NT)
|
||||
VERSION := v$(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'project.*VERSION\s+([0-9.]+)').Matches.Groups[1].Value")
|
||||
VERSION = v$(shell powershell -Command "(Select-String -Path 'CMakeLists.txt' -Pattern 'project.*VERSION\s+([0-9.]+)').Matches.Groups[1].Value")
|
||||
else
|
||||
VERSION := v$(shell grep "^project" CMakeLists.txt | tr -cd 0-9.)
|
||||
VERSION = v$(shell grep '^project' CMakeLists.txt | sed -E 's/.*VERSION[[:space:]]+([0-9.]+).*/\1/')
|
||||
endif
|
||||
|
||||
# Release file names (depend on VERSION, so must come after)
|
||||
ifeq ($(OS),Windows_NT)
|
||||
RAW_VERSION := $(shell powershell -Command "\"$(VERSION)\" -replace '^v', ''")
|
||||
else
|
||||
RAW_VERSION := $(shell echo $(VERSION) | sed 's/^v//')
|
||||
# GIT_HASH calculat al host i passat a CMake (evita problemes si CMake corre en
|
||||
# entorns sense accés a git).
|
||||
GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>$(NULDEV))
|
||||
ifeq ($(GIT_HASH),)
|
||||
GIT_HASH := unknown
|
||||
endif
|
||||
WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-windows-x64.zip
|
||||
MACOS_ARM_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-arm64.dmg
|
||||
MACOS_INTEL_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-x64.dmg
|
||||
LINUX_RELEASE := $(TARGET_NAME)-$(VERSION)-linux-x64.tar.gz
|
||||
RPI_RELEASE := $(TARGET_NAME)-$(VERSION)-rpi-arm64.tar.gz
|
||||
APP_NAME := $(LONG_NAME)
|
||||
|
||||
CMAKE_DEFS := -DGIT_HASH=$(GIT_HASH)
|
||||
|
||||
# ==============================================================================
|
||||
# SOURCE FILES
|
||||
# RELEASE — variables d'empaquetat per distribució
|
||||
# ==============================================================================
|
||||
# Note: Source files are now auto-discovered by CMake using GLOB_RECURSE
|
||||
# No need to maintain this list manually anymore!
|
||||
APP_NAME := Orni Attack
|
||||
DIST_DIR := dist
|
||||
RELEASE_FOLDER := $(DIST_DIR)/_tmp
|
||||
TARGET_FILE := $(BUILDDIR)/$(PROJECT)
|
||||
RELEASE_FILE := $(RELEASE_FOLDER)/$(PROJECT)
|
||||
|
||||
# ==============================================================================
|
||||
# PLATFORM-SPECIFIC UTILITIES
|
||||
# ==============================================================================
|
||||
# Use Unix commands always (MinGW Make uses bash even on Windows)
|
||||
RMFILE := rm -f
|
||||
RMDIR := rm -rf
|
||||
MKDIR := mkdir -p
|
||||
# Noms dels artefactes finals (amb VERSION i PROJECT)
|
||||
WINDOWS_RELEASE := $(DIST_DIR)/$(PROJECT)-$(VERSION)-win32-x64.zip
|
||||
MACOS_APPLE_SILICON_RELEASE := $(DIST_DIR)/$(PROJECT)-$(VERSION)-macos-apple-silicon.dmg
|
||||
LINUX_RELEASE := $(DIST_DIR)/$(PROJECT)-$(VERSION)-linux.tar.gz
|
||||
|
||||
# Variables específiques de Windows (PowerShell). El subst escapa apòstrofs.
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Windows-specific: Force cmd.exe shell for PowerShell commands
|
||||
SHELL := cmd.exe
|
||||
WIN_TARGET_FILE := $(BUILDDIR)/$(APP_NAME)
|
||||
WIN_RELEASE_FILE := $(RELEASE_FOLDER)/$(APP_NAME)
|
||||
WIN_RELEASE_FILE_PS := $(subst ','',$(WIN_RELEASE_FILE))
|
||||
UNAME_S :=
|
||||
else
|
||||
# Unix-specific
|
||||
UNAME_S := $(shell uname -s)
|
||||
WIN_TARGET_FILE := $(TARGET_FILE)
|
||||
WIN_RELEASE_FILE := $(RELEASE_FILE)
|
||||
WIN_RELEASE_FILE_PS := $(WIN_RELEASE_FILE)
|
||||
UNAME_S := $(shell uname -s)
|
||||
endif
|
||||
|
||||
# Helpers cross-platform.
|
||||
ifeq ($(OS),Windows_NT)
|
||||
RMFILE := del /Q
|
||||
RMDIR := rmdir /S /Q
|
||||
MKDIR := mkdir
|
||||
else
|
||||
RMFILE := rm -f
|
||||
RMDIR := rm -rdf
|
||||
MKDIR := mkdir -p
|
||||
endif
|
||||
|
||||
.PHONY: all debug release _windows-release _macos-release _linux-release \
|
||||
run run-debug clean rebuild show-version pack controllerdb \
|
||||
format format-check tidy tidy-fix cppcheck hooks-install help
|
||||
|
||||
# Còpia del gamecontrollerdb.txt (si existeix) al directori de build, perquè
|
||||
# director.cpp el resolgui via resource_base = directori de l'executable.
|
||||
# Silenciós si el fitxer no existeix (l'usuari encara no ha fet `make controllerdb`).
|
||||
ifeq ($(OS),Windows_NT)
|
||||
CP_CONTROLLERDB = @powershell -Command "if (Test-Path 'gamecontrollerdb.txt') { Copy-Item 'gamecontrollerdb.txt' -Destination '$(BUILDDIR)' -Force }"
|
||||
else
|
||||
CP_CONTROLLERDB = @if [ -f gamecontrollerdb.txt ]; then cp gamecontrollerdb.txt $(BUILDDIR)/; fi
|
||||
endif
|
||||
|
||||
# ==============================================================================
|
||||
# PACKING TOOL
|
||||
# COMPILACIÓ
|
||||
# ==============================================================================
|
||||
PACK_TOOL := tools/pack_resources/pack_resources
|
||||
|
||||
# ==============================================================================
|
||||
# DEFAULT GOAL
|
||||
# ==============================================================================
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
.PHONY: pack_tool resources.pack
|
||||
|
||||
pack_tool:
|
||||
@make -C tools/pack_resources
|
||||
|
||||
resources.pack: pack_tool
|
||||
@echo "Creating resources.pack..."
|
||||
@./$(PACK_TOOL) data resources.pack
|
||||
|
||||
# ==============================================================================
|
||||
# TARGETS
|
||||
# ==============================================================================
|
||||
.PHONY: all clean debug help backup
|
||||
|
||||
# ==============================================================================
|
||||
# BUILD TARGETS (delegate to CMake)
|
||||
# make → Release (binari d'ús normal)
|
||||
# make debug → Debug
|
||||
# make release → Release + empaquetat per a distribució (zip/dmg/tar.gz segons SO)
|
||||
# ==============================================================================
|
||||
|
||||
# Default target: build with CMake + resources
|
||||
all: resources.pack $(TARGET_FILE)
|
||||
all:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) -j$(JOBS)
|
||||
$(CP_CONTROLLERDB)
|
||||
|
||||
$(TARGET_FILE):
|
||||
@cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
@echo "Build successful: $(TARGET_FILE)"
|
||||
debug:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Debug $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) -j$(JOBS)
|
||||
$(CP_CONTROLLERDB)
|
||||
|
||||
# Debug build
|
||||
debug: resources.pack
|
||||
@cmake -B build -DCMAKE_BUILD_TYPE=Debug
|
||||
@cmake --build build
|
||||
@echo "Debug build successful: $(TARGET_FILE)"
|
||||
run: all
|
||||
@./$(BUILDDIR)/$(PROJECT)
|
||||
|
||||
run-debug: debug
|
||||
@./$(BUILDDIR)/$(PROJECT)
|
||||
|
||||
# Release + empaquetat: detecta el SO i delega al sub-target corresponent.
|
||||
release:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@"$(MAKE)" _windows-release
|
||||
else
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
@$(MAKE) _macos-release
|
||||
else
|
||||
@$(MAKE) _linux-release
|
||||
endif
|
||||
endif
|
||||
|
||||
# ==============================================================================
|
||||
# RELEASE PACKAGING TARGETS
|
||||
# RELEASE — Linux (.tar.gz)
|
||||
# ==============================================================================
|
||||
_linux-release:
|
||||
@echo "Creando release para Linux - Version: $(VERSION)"
|
||||
|
||||
# macOS Release (Apple Silicon)
|
||||
.PHONY: macos_release
|
||||
macos_release: pack_tool resources.pack
|
||||
@echo "Creating macOS release - Version: $(VERSION)"
|
||||
# Compila Release (genera resources.pack i binari)
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) -j$(JOBS)
|
||||
|
||||
# Check/install create-dmg
|
||||
@command -v create-dmg >/dev/null || (echo "Installing create-dmg..." && brew install create-dmg)
|
||||
|
||||
# Clean previous releases
|
||||
# Recrea la carpeta temporal
|
||||
@$(MKDIR) "$(DIST_DIR)" 2>/dev/null || true
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true
|
||||
@$(RMDIR) Frameworks 2>/dev/null || true
|
||||
@$(RMFILE) "$(MACOS_ARM_RELEASE)" 2>/dev/null || true
|
||||
$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Create .app structure
|
||||
@$(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
|
||||
# Còpia de fitxers
|
||||
cp $(BUILDDIR)/resources.pack "$(RELEASE_FOLDER)"
|
||||
cp gamecontrollerdb.txt "$(RELEASE_FOLDER)"
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
@[ -f LICENSE ] && cp LICENSE "$(RELEASE_FOLDER)" || true
|
||||
cp "$(TARGET_FILE)" "$(RELEASE_FILE)"
|
||||
strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded
|
||||
|
||||
# Copy resources.pack to Resources
|
||||
@cp resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources/"
|
||||
@ditto release/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework"
|
||||
@ditto release/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework Frameworks/SDL3.framework
|
||||
# Empaqueta a .tar.gz
|
||||
$(RMFILE) "$(LINUX_RELEASE)"
|
||||
tar -czvf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
||||
@echo "Release creado: $(LINUX_RELEASE)"
|
||||
|
||||
# Recreate framework symlinks (may be broken)
|
||||
@cd Frameworks/SDL3.framework && rm -f SDL3 Headers Resources && \
|
||||
ln -s Versions/Current/SDL3 SDL3 && \
|
||||
ln -s Versions/Current/Headers Headers && \
|
||||
ln -s Versions/Current/Resources Resources
|
||||
@cd Frameworks/SDL3.framework/Versions && rm -f Current && ln -s A Current
|
||||
@cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework" && rm -f SDL3 Headers Resources && \
|
||||
ln -s Versions/Current/SDL3 SDL3 && \
|
||||
ln -s Versions/Current/Headers Headers && \
|
||||
ln -s Versions/Current/Resources Resources
|
||||
@cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework/Versions" && rm -f Current && ln -s A Current
|
||||
# Neteja la carpeta temporal
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
@cp release/icon.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources/"
|
||||
@cp release/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/"
|
||||
@cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found"
|
||||
@cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found"
|
||||
|
||||
# Update Info.plist version and names
|
||||
@echo "Updating Info.plist with version $(RAW_VERSION) and names..."
|
||||
@sed -i '' '/<key>CFBundleShortVersionString<\/key>/{n;s|<string>.*</string>|<string>$(RAW_VERSION)</string>|;}' \
|
||||
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
|
||||
@sed -i '' '/<key>CFBundleVersion<\/key>/{n;s|<string>.*</string>|<string>$(RAW_VERSION)</string>|;}' \
|
||||
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
|
||||
@sed -i '' '/<key>CFBundleExecutable<\/key>/{n;s|<string>.*</string>|<string>$(TARGET_NAME)</string>|;}' \
|
||||
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
|
||||
@sed -i '' '/<key>CFBundleName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' \
|
||||
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
|
||||
@sed -i '' '/<key>CFBundleDisplayName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' \
|
||||
"$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
|
||||
|
||||
# Compile for Apple Silicon using CMake
|
||||
@cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64
|
||||
@cmake --build build
|
||||
@cp $(TARGET_FILE) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(TARGET_NAME)"
|
||||
|
||||
# Code sign
|
||||
@codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app" || echo "Warning: Code signing failed"
|
||||
|
||||
# Create DMG
|
||||
@echo "Creating DMG for Apple Silicon..."
|
||||
@create-dmg \
|
||||
--volname "$(APP_NAME)" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 720 300 \
|
||||
--icon-size 96 \
|
||||
--text-size 12 \
|
||||
--icon "$(APP_NAME).app" 278 102 \
|
||||
--icon "LICENSE" 441 102 \
|
||||
--icon "README.md" 604 102 \
|
||||
--app-drop-link 115 102 \
|
||||
--hide-extension "$(APP_NAME).app" \
|
||||
"$(MACOS_ARM_RELEASE)" \
|
||||
"$(RELEASE_FOLDER)" || true
|
||||
@echo "✓ macOS release created: $(MACOS_ARM_RELEASE)"
|
||||
|
||||
# Cleanup
|
||||
@$(RMDIR) Frameworks
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Linux Release
|
||||
.PHONY: linux_release
|
||||
linux_release: pack_tool resources.pack
|
||||
@echo "Creating Linux release - Version: $(VERSION)"
|
||||
@echo "Note: SDL3 must be installed on the target system (libsdl3-dev)"
|
||||
|
||||
# Clean previous
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
@$(RMFILE) "$(LINUX_RELEASE)"
|
||||
|
||||
# Create folder
|
||||
@$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Copy resources
|
||||
@cp resources.pack "$(RELEASE_FOLDER)/"
|
||||
@cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found"
|
||||
@cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found"
|
||||
|
||||
# Compile with CMake
|
||||
@cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
@cp $(TARGET_FILE) "$(RELEASE_FILE)"
|
||||
@strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded || strip "$(RELEASE_FILE)"
|
||||
|
||||
# Package
|
||||
@tar -czf "$(LINUX_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
||||
@echo "✓ Linux release created: $(LINUX_RELEASE)"
|
||||
|
||||
# Cleanup
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
|
||||
# Windows Release (requires MinGW on Windows or cross-compiler on Linux)
|
||||
.PHONY: windows_release
|
||||
windows_release: pack_tool resources.pack
|
||||
# ==============================================================================
|
||||
# RELEASE — Windows (.zip)
|
||||
# ==============================================================================
|
||||
_windows-release:
|
||||
@echo off
|
||||
@echo Creating Windows release - Version: $(VERSION)
|
||||
@powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||
@powershell if (Test-Path "$(WINDOWS_RELEASE)") {Remove-Item "$(WINDOWS_RELEASE)"}
|
||||
@powershell if (-not (Test-Path "$(RELEASE_FOLDER)")) {New-Item "$(RELEASE_FOLDER)" -ItemType Directory}
|
||||
@powershell Copy-Item -Path "resources.pack" -Destination "$(RELEASE_FOLDER)"
|
||||
@powershell Copy-Item "release\dll\SDL3.dll" -Destination "$(RELEASE_FOLDER)"
|
||||
@powershell Copy-Item "release\dll\libwinpthread-1.dll" -Destination "$(RELEASE_FOLDER)"
|
||||
@powershell if (Test-Path "LICENSE") {Copy-Item "LICENSE" -Destination "$(RELEASE_FOLDER)"}
|
||||
@powershell if (Test-Path "README.md") {Copy-Item "README.md" -Destination "$(RELEASE_FOLDER)"}
|
||||
@windres release/$(TARGET_NAME).rc -O coff -o release/$(TARGET_NAME).res 2>nul || echo Warning: windres failed
|
||||
@cmake -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
|
||||
@cmake --build build
|
||||
@powershell if (Test-Path "$(TARGET_FILE).exe") {Copy-Item "$(TARGET_FILE).exe" -Destination "$(RELEASE_FILE).exe"} else {Copy-Item "$(TARGET_FILE)" -Destination "$(RELEASE_FILE).exe"}
|
||||
@strip "$(RELEASE_FILE).exe" 2>nul || echo Warning: strip not available
|
||||
@powershell Compress-Archive -Path "$(RELEASE_FOLDER)\*" -DestinationPath "$(WINDOWS_RELEASE)" -Force
|
||||
@echo Release created: $(WINDOWS_RELEASE)
|
||||
@powershell if (Test-Path "$(RELEASE_FOLDER)") {Remove-Item "$(RELEASE_FOLDER)" -Recurse -Force}
|
||||
@echo Creando release para Windows - Version: $(VERSION)
|
||||
|
||||
# Raspberry Pi Release (cross-compilation from Linux/macOS)
|
||||
.PHONY: rpi_release
|
||||
rpi_release:
|
||||
@echo "Creating Raspberry Pi ARM64 release - Version: $(VERSION)"
|
||||
@echo "Note: Requires aarch64-linux-gnu-g++ cross-compiler"
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) -j$(JOBS)
|
||||
|
||||
# Check for cross-compiler
|
||||
@command -v aarch64-linux-gnu-g++ >/dev/null || (echo "Error: aarch64-linux-gnu-g++ not found" && exit 1)
|
||||
@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}"
|
||||
|
||||
# Clean previous
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
@$(RMFILE) "$(RPI_RELEASE)"
|
||||
@powershell -Command "Copy-Item -Path '$(BUILDDIR)/resources.pack' -Destination '$(RELEASE_FOLDER)'"
|
||||
@powershell -Command "Copy-Item 'gamecontrollerdb.txt' -Destination '$(RELEASE_FOLDER)'"
|
||||
@powershell -Command "if (Test-Path 'LICENSE') { Copy-Item 'LICENSE' -Destination '$(RELEASE_FOLDER)' }"
|
||||
@powershell -Command "Copy-Item 'README.md' -Destination '$(RELEASE_FOLDER)'"
|
||||
@powershell -Command "if (Test-Path 'release\windows\dll') { Copy-Item 'release\windows\dll\*.dll' -Destination '$(RELEASE_FOLDER)' }"
|
||||
@powershell -Command "Copy-Item -Path '$(TARGET_FILE).exe' -Destination '$(WIN_RELEASE_FILE_PS).exe'"
|
||||
strip -s -R .comment -R .gnu.version "$(WIN_RELEASE_FILE).exe" --strip-unneeded
|
||||
|
||||
# Create folder
|
||||
@$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
@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)
|
||||
|
||||
# Copy resources
|
||||
@cp resources.pack "$(RELEASE_FOLDER)/"
|
||||
@cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found"
|
||||
@cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found"
|
||||
@powershell -Command "if (Test-Path '$(RELEASE_FOLDER)') {Remove-Item '$(RELEASE_FOLDER)' -Recurse -Force}"
|
||||
|
||||
# Note: Cross-compilation with CMake is complex, would need toolchain file
|
||||
@echo "Warning: RPI cross-compilation requires manual setup with CMake toolchain file"
|
||||
@echo "Falling back to direct g++ compilation..."
|
||||
@aarch64-linux-gnu-g++ -std=c++20 -Wall -O2 -DLINUX_BUILD -DRPI_BUILD \
|
||||
-Isource -Ibuild \
|
||||
$$(find source/core source/game -name "*.cpp") source/main.cpp \
|
||||
-lSDL3 -o "$(RELEASE_FILE)" || echo "Error: Compilation failed"
|
||||
@aarch64-linux-gnu-strip -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded || true
|
||||
# ==============================================================================
|
||||
# RELEASE — macOS (.dmg per Apple Silicon)
|
||||
# ==============================================================================
|
||||
_macos-release:
|
||||
@echo "Creando release para macOS - Version: $(VERSION)"
|
||||
|
||||
# Package
|
||||
@tar -czf "$(RPI_RELEASE)" -C "$(RELEASE_FOLDER)" .
|
||||
@echo "✓ Raspberry Pi release created: $(RPI_RELEASE)"
|
||||
# Verificar/instal·lar create-dmg si cal
|
||||
@which create-dmg > /dev/null || (echo "Instalando create-dmg..." && brew install create-dmg)
|
||||
|
||||
# Cleanup
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
# Compila la versió Apple Silicon
|
||||
@cmake -S . -B $(BUILDDIR)/arm $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=13.3 \
|
||||
-DMACOS_BUNDLE=ON $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR)/arm -j$(JOBS)
|
||||
|
||||
# Windows Cross-compilation (from Linux/macOS)
|
||||
.PHONY: windows_cross
|
||||
windows_cross:
|
||||
@echo "Cross-compiling for Windows from $(UNAME_S) - Version: $(VERSION)"
|
||||
# Neteja artefactes anteriors
|
||||
@$(MKDIR) "$(DIST_DIR)" 2>/dev/null || true
|
||||
$(RMDIR) "$(RELEASE_FOLDER)" 2>/dev/null || true
|
||||
$(RMFILE) "$(DIST_DIR)"/rw.* 2>/dev/null || true
|
||||
$(RMFILE) "$(MACOS_APPLE_SILICON_RELEASE)"
|
||||
|
||||
# Check for cross-compiler
|
||||
@command -v x86_64-w64-mingw32-g++ >/dev/null || (echo "Error: x86_64-w64-mingw32-g++ not found" && exit 1)
|
||||
# Crea l'estructura del bundle .app
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS"
|
||||
$(MKDIR) "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
|
||||
# Clean previous
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
@$(RMFILE) "$(WINDOWS_RELEASE)"
|
||||
# Còpia de recursos i metadades del bundle
|
||||
cp $(BUILDDIR)/arm/resources.pack "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
cp gamecontrollerdb.txt "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
cp -R release/macos/frameworks/SDL3.xcframework/macos-arm64_x86_64/SDL3.framework "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks"
|
||||
cp release/icons/icon.icns "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Resources"
|
||||
cp release/macos/Info.plist "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents"
|
||||
@[ -f LICENSE ] && cp LICENSE "$(RELEASE_FOLDER)" || true
|
||||
cp README.md "$(RELEASE_FOLDER)"
|
||||
|
||||
# Create folder
|
||||
@$(MKDIR) "$(RELEASE_FOLDER)"
|
||||
# Recreate framework symlinks (Versions/Current i top-level)
|
||||
@cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework" && \
|
||||
rm -f SDL3 Headers Resources && \
|
||||
ln -s Versions/Current/SDL3 SDL3 && \
|
||||
ln -s Versions/Current/Headers Headers && \
|
||||
ln -s Versions/Current/Resources Resources
|
||||
@cd "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Frameworks/SDL3.framework/Versions" && \
|
||||
rm -f Current && ln -s A Current
|
||||
|
||||
# Copy resources
|
||||
@cp resources.pack "$(RELEASE_FOLDER)/"
|
||||
@cp release/dll/SDL3.dll release/dll/libwinpthread-1.dll "$(RELEASE_FOLDER)/"
|
||||
@cp LICENSE "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: LICENSE not found"
|
||||
@cp README.md "$(RELEASE_FOLDER)/" 2>/dev/null || echo "Warning: README.md not found"
|
||||
# Actualitza Info.plist amb VERSION i metadades
|
||||
@echo "Actualizando Info.plist con versión $(VERSION)..."
|
||||
@RAW_VERSION=$$(echo "$(VERSION)" | sed 's/^v//'); \
|
||||
sed -i '' '/<key>CFBundleShortVersionString<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
|
||||
sed -i '' '/<key>CFBundleVersion<\/key>/{n;s|<string>.*</string>|<string>'"$$RAW_VERSION"'</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
|
||||
sed -i '' '/<key>CFBundleExecutable<\/key>/{n;s|<string>.*</string>|<string>$(PROJECT)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
|
||||
sed -i '' '/<key>CFBundleName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"; \
|
||||
sed -i '' '/<key>CFBundleDisplayName<\/key>/{n;s|<string>.*</string>|<string>$(APP_NAME)</string>|;}' "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/Info.plist"
|
||||
|
||||
# Compile resource file
|
||||
@x86_64-w64-mingw32-windres release/$(TARGET_NAME).rc -O coff -o release/$(TARGET_NAME).res 2>/dev/null || echo "Warning: windres failed"
|
||||
# Còpia del binari al bundle
|
||||
cp "$(BUILDDIR)/arm/$(PROJECT)" "$(RELEASE_FOLDER)/$(APP_NAME).app/Contents/MacOS/$(PROJECT)"
|
||||
|
||||
# Cross-compile
|
||||
@echo "Compiling with MinGW cross-compiler..."
|
||||
@x86_64-w64-mingw32-g++ -std=c++20 -Wall -O2 -DWINDOWS_BUILD -DRELEASE_BUILD \
|
||||
-static-libstdc++ -static-libgcc -Wl,-subsystem,windows \
|
||||
-Isource -Ibuild \
|
||||
$$(find source/core source/game -name "*.cpp") source/main.cpp \
|
||||
release/$(TARGET_NAME).res \
|
||||
-lmingw32 -lSDL3 -o "$(RELEASE_FILE).exe" || echo "Error: Compilation failed"
|
||||
@x86_64-w64-mingw32-strip "$(RELEASE_FILE).exe" || true
|
||||
# Firma ad-hoc del bundle
|
||||
codesign --deep --force --sign - --timestamp=none "$(RELEASE_FOLDER)/$(APP_NAME).app"
|
||||
|
||||
# Package
|
||||
@cd "$(RELEASE_FOLDER)" && zip -r ../$(WINDOWS_RELEASE) *
|
||||
@echo "✓ Windows cross-compiled release created: $(WINDOWS_RELEASE)"
|
||||
# Empaqueta el .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)"
|
||||
|
||||
# Cleanup
|
||||
@$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
# Neteja temporals
|
||||
$(RMDIR) "$(RELEASE_FOLDER)"
|
||||
$(RMDIR) $(BUILDDIR)/arm
|
||||
$(RMFILE) "$(DIST_DIR)"/rw.* 2>/dev/null || true
|
||||
|
||||
show-version:
|
||||
@echo "$(PROJECT) $(VERSION) ($(GIT_HASH))"
|
||||
|
||||
# Clean build artifacts
|
||||
clean:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@if exist $(call FixPath,$(TARGET_FILE).exe) $(RMFILE) $(call FixPath,$(TARGET_FILE).exe)
|
||||
@if exist $(call FixPath,$(TARGET_FILE)_debug.exe) $(RMFILE) $(call FixPath,$(TARGET_FILE)_debug.exe)
|
||||
@if exist build $(RMDIR) build
|
||||
@if exist $(RELEASE_FOLDER) $(RMDIR) $(RELEASE_FOLDER)
|
||||
else
|
||||
@$(RMFILE) $(TARGET_FILE) $(TARGET_FILE)_debug
|
||||
@$(RMDIR) build $(RELEASE_FOLDER)
|
||||
@$(RMFILE) *.dmg *.zip *.tar.gz 2>/dev/null || true
|
||||
@$(RMFILE) resources.pack 2>/dev/null || true
|
||||
@make -C tools/pack_resources clean 2>/dev/null || true
|
||||
endif
|
||||
@echo "Clean complete"
|
||||
@rm -rf $(BUILDDIR) $(DIST_DIR)
|
||||
|
||||
# Backup to remote server
|
||||
backup:
|
||||
@echo "Backing up project to maverick:/home/sergio/git-backup/orni..."
|
||||
rsync -a --delete \
|
||||
--exclude='build/' \
|
||||
--exclude='*.o' \
|
||||
--exclude='*.exe' \
|
||||
--exclude='orni' \
|
||||
--exclude='orni_debug' \
|
||||
--exclude='*_release/' \
|
||||
$(DIR_ROOT) maverick:/home/sergio/git-backup/orni/
|
||||
@echo "Backup completed successfully"
|
||||
rebuild: clean all
|
||||
|
||||
# Help target
|
||||
# Empaqueta data/ a $(BUILDDIR)/resources.pack. Força un rebuild del pack encara
|
||||
# que res no hagi canviat dins data/. L'empaquetat també es fa automàticament a
|
||||
# cada `make`/`make debug` via el target CMake `resource_pack`.
|
||||
pack:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) --target pack_resources
|
||||
@./$(BUILDDIR)/pack_resources data $(BUILDDIR)/resources.pack
|
||||
|
||||
# ==============================================================================
|
||||
# DESCÀRREGA DE GAMECONTROLLERDB
|
||||
# ==============================================================================
|
||||
# Descarrega l'última versió de gamecontrollerdb.txt (mappings de gamepads
|
||||
# mantinguts per la comunitat) a l'arrel del projecte. SDL el carrega via
|
||||
# filesystem real (no dins resources.pack) i s'ha de copiar al costat del binari
|
||||
# en cada build (gestionat per CP_CONTROLLERDB a `all`/`debug` i pels release targets).
|
||||
controllerdb:
|
||||
@echo "Descargando gamecontrollerdb.txt..."
|
||||
curl -fsSL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt \
|
||||
-o gamecontrollerdb.txt
|
||||
@echo "gamecontrollerdb.txt actualizado"
|
||||
|
||||
# ==============================================================================
|
||||
# CODE QUALITY (delegats a cmake)
|
||||
# ==============================================================================
|
||||
format:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) --target format
|
||||
|
||||
format-check:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) --target format-check
|
||||
|
||||
tidy:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) --target tidy
|
||||
|
||||
tidy-fix:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) --target tidy-fix
|
||||
|
||||
cppcheck:
|
||||
@cmake -S . -B $(BUILDDIR) $(CMAKE_GEN) -DCMAKE_BUILD_TYPE=Release $(CMAKE_DEFS)
|
||||
@cmake --build $(BUILDDIR) --target cppcheck
|
||||
|
||||
# ==============================================================================
|
||||
# GIT HOOKS
|
||||
# ==============================================================================
|
||||
hooks-install:
|
||||
@git config core.hooksPath .githooks
|
||||
@echo "Git hooks activats: $(shell pwd)/.githooks"
|
||||
|
||||
# ==============================================================================
|
||||
# AJUDA
|
||||
# ==============================================================================
|
||||
help:
|
||||
@echo "Available targets:"
|
||||
@echo "Makefile per a $(PROJECT)"
|
||||
@echo ""
|
||||
@echo "Build:"
|
||||
@echo " all - Build the game (default, delegates to CMake)"
|
||||
@echo " debug - Build with debug symbols"
|
||||
@echo " clean - Remove build artifacts and release packages"
|
||||
@echo " Compilació:"
|
||||
@echo " make - Compilar amb cmake (Release)"
|
||||
@echo " make debug - Compilar amb cmake (Debug)"
|
||||
@echo ""
|
||||
@echo "Release Packaging:"
|
||||
@echo " macos_release - Create macOS .app bundle + .dmg (Apple Silicon)"
|
||||
@echo " linux_release - Create Linux .tar.gz"
|
||||
@echo " windows_release - Create Windows .zip (requires MinGW on Windows)"
|
||||
@echo " windows_cross - Cross-compile Windows from Linux/macOS (requires MinGW)"
|
||||
@echo " rpi_release - Cross-compile for Raspberry Pi ARM64"
|
||||
@echo " Execució:"
|
||||
@echo " make run - Compilar (Release) i executar"
|
||||
@echo " make run-debug - Compilar (Debug) i executar"
|
||||
@echo ""
|
||||
@echo "Other:"
|
||||
@echo " backup - Backup project to remote server"
|
||||
@echo " help - Show this help message"
|
||||
@echo " Release:"
|
||||
@echo " make release - Release + empaquetat (zip/dmg/tar.gz segons SO)"
|
||||
@echo ""
|
||||
@echo "Current configuration:"
|
||||
@echo " Project: $(LONG_NAME)"
|
||||
@echo " Target: $(TARGET_NAME)"
|
||||
@echo " Version: $(VERSION)"
|
||||
@echo " Platform: $(UNAME_S)"
|
||||
@echo " Recursos:"
|
||||
@echo " make pack - Empaquetar data/ a $(BUILDDIR)/resources.pack"
|
||||
@echo ""
|
||||
@echo " Qualitat de codi:"
|
||||
@echo " make format - Formatar codi amb clang-format"
|
||||
@echo " make format-check - Verificar format sense modificar"
|
||||
@echo " make tidy - Anàlisi estàtic amb clang-tidy"
|
||||
@echo " make tidy-fix - Anàlisi estàtic amb auto-fix"
|
||||
@echo " make cppcheck - Anàlisi estàtic amb cppcheck"
|
||||
@echo ""
|
||||
@echo " Altres:"
|
||||
@echo " make clean - Esborrar $(BUILDDIR)/ i $(DIST_DIR)/"
|
||||
@echo " make rebuild - clean + all"
|
||||
@echo " make show-version - Mostrar versió"
|
||||
@echo " make hooks-install - Activar git hooks del projecte"
|
||||
@echo ""
|
||||
@echo " Versió actual: $(VERSION) ($(GIT_HASH))"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# postfx.yaml - Parámetros del shader de postprocesado
|
||||
#
|
||||
# Este archivo configura el pase final del renderer (bloom + flicker +
|
||||
# background pulse). Se carga al iniciar el juego desde resources.pack.
|
||||
# Si falta o tiene errores, se usan los valores por defecto de
|
||||
# Defaults::PostFx (defaults.hpp).
|
||||
#
|
||||
# Tip de tuning:
|
||||
# - Para más "neón vector", sube bloom.intensity y bloom.radius_px.
|
||||
# - Para más "CRT viejo", sube flicker.amplitude (riesgo de mareo si >0.3).
|
||||
# - Background es muy sutil; pasa los componentes G a 0.15-0.20 para
|
||||
# un fondo verde-tenue más marcado.
|
||||
|
||||
# Bloom / glow: separable gaussian blur de dues passes (H + V).
|
||||
# Equivalent matemàtic d'un kernel 15×15 dens (225 mostres) però només cosTa
|
||||
# 30 mostres per píxel. Sense moiré: sigma_px controla l'amplada del halo.
|
||||
bloom:
|
||||
enabled: true
|
||||
intensity: 1.8 # 0..2 — cuanto del bloom se suma a la imagen
|
||||
threshold: 0.20 # 0..1 — luminància mínima que aporta al bloom
|
||||
sigma_px: 5.0 # sigma de la gaussiana en texels (~1.5..6 raonable;
|
||||
# halo ≈ 3·sigma a cada banda. 3.5 → halo de ~10 px)
|
||||
|
||||
# Flicker: modulación global de brillo (efecto fósforo CRT).
|
||||
# Sustituye a la antigua oscilación CPU del ColorOscillator.
|
||||
# Solo afecta a `(lines + bloom)` en el shader; NO toca el fondo, así que
|
||||
# los píxeles negros siguen siendo negros (no pulsan).
|
||||
flicker:
|
||||
enabled: true
|
||||
amplitude: 0.18 # 0..1 — profundidad del flicker
|
||||
frequency_hz: 6.0 # Hz — velocidad de la pulsación
|
||||
|
||||
# Background pulse: color de fondo oscilante (suma aditiva).
|
||||
# Desactivado: fondo negro puro. Se mantienen los valores por si queremos
|
||||
# reactivar más adelante un tinte verdoso muy tenue al estilo CRT.
|
||||
background:
|
||||
enabled: false
|
||||
color_min: [0, 0, 0] # negro puro
|
||||
color_max: [0, 0, 0] # negro puro
|
||||
pulse_frequency_hz: 6.0 # Hz — sincronizado con flicker por defecto
|
||||
@@ -0,0 +1,22 @@
|
||||
name: bullet
|
||||
|
||||
# Shape de la bala. El bounding_radius del .shp dóna el hitbox base (~3 px);
|
||||
# scale el modula visualment i pel hitbox.
|
||||
shape:
|
||||
path: bullet/basic.shp
|
||||
scale: 1.0
|
||||
collision_factor: 1.0
|
||||
|
||||
# Cinemàtica pura: la bala no col·lisiona físicament al PhysicsWorld
|
||||
# (body_.radius = 0 al spawn), però sí participa al gameplay via
|
||||
# checkCollisionSwept. La mass i l'impact_momentum_factor es fan servir
|
||||
# només per calcular l'impuls que rep l'enemic en impactar.
|
||||
physics:
|
||||
mass: 0.5
|
||||
restitution: 0.0 # irrelevant (no rebota)
|
||||
linear_damping: 0.0 # movement rectilini uniforme
|
||||
angular_damping: 0.0
|
||||
impact_momentum_factor: 3.0 # factor de transferència de moment bala→enemic
|
||||
|
||||
colors:
|
||||
normal: [155, 255, 175] # verd laser
|
||||
@@ -0,0 +1,21 @@
|
||||
name: bullet_double
|
||||
|
||||
# Variant de bala "anular" (dos cercles concèntrics, aspecte d'aura de plasma).
|
||||
# Pensada per a contra-atacs d'enemic (ex: orb dispara una bullet_double al
|
||||
# jugador quan rep un impacte). Mateixa física que la bala bàsica del player;
|
||||
# canvien la forma (cercle doble) i el color per llegir-se com a tret enemic
|
||||
# distintiu (groc verdós vs. el verd laser del player o el roig de bullet_long).
|
||||
shape:
|
||||
path: bullet/double.shp
|
||||
scale: 1.5
|
||||
collision_factor: 1.0
|
||||
|
||||
physics:
|
||||
mass: 0.5
|
||||
restitution: 0.0
|
||||
linear_damping: 0.0
|
||||
angular_damping: 0.0
|
||||
impact_momentum_factor: 4.0
|
||||
|
||||
colors:
|
||||
normal: [200, 255, 80] # groc verdós (chartreuse) — contra-atac de l'orb
|
||||
@@ -0,0 +1,19 @@
|
||||
name: bullet_long
|
||||
|
||||
# Variant de bala més llarga, pensada per a bales d'enemic: més visible per al
|
||||
# jugador i amb prou marge per reaccionar. La velocitat NO viu aquí: es passa
|
||||
# a Bullet::fire() i la decideix qui dispara (l'AiTickAction).
|
||||
shape:
|
||||
path: bullet/long.shp
|
||||
scale: 1.0
|
||||
collision_factor: 0.5
|
||||
|
||||
physics:
|
||||
mass: 0.5
|
||||
restitution: 0.0
|
||||
linear_damping: 0.0
|
||||
angular_damping: 0.0
|
||||
impact_momentum_factor: 3.0
|
||||
|
||||
colors:
|
||||
normal: [255, 100, 100] # roig clar — diferencia visualment del verd laser del player
|
||||
@@ -0,0 +1,86 @@
|
||||
name: orb
|
||||
ai_type: orb # Validat contra el directori; mapeja a EnemyType::ORB.
|
||||
|
||||
# Shape circular pròpia (anell exterior + anell interior + 6 radis + nucli),
|
||||
# pensada per llegir-se com a "reactor / orb" amb més detall que els enemics
|
||||
# petits.
|
||||
shape:
|
||||
path: enemy/orb.shp
|
||||
scale: 1.0
|
||||
collision_factor: 1.0
|
||||
|
||||
physics:
|
||||
mass: 50.0 # Molt pesat: una bala el frena un poc però no el "envia a passejar".
|
||||
speed: 50.0 # Avança decidit cap al ship (no és lent passiu, és amenaça constant).
|
||||
rotation_delta_min: 0.3
|
||||
rotation_delta_max: 1.5
|
||||
restitution: 1.0
|
||||
linear_damping: 0.0
|
||||
angular_damping: 0.0
|
||||
|
||||
ai:
|
||||
# Persecució contínua del ship més proper. chase_strength alt (1.0 = ~1s
|
||||
# per realinear-se) perquè, encara que una bala l'empentja lateralment,
|
||||
# ràpidament torna a posar la seua proa cap al jugador.
|
||||
movement:
|
||||
type: chase
|
||||
chase_strength: 1.0
|
||||
|
||||
animation:
|
||||
pulse:
|
||||
trigger_prob_per_second: 0.01
|
||||
duration_min: 1.0
|
||||
duration_max: 3.0
|
||||
amplitude_min: 0.08
|
||||
amplitude_max: 0.20
|
||||
frequency_min: 1.5
|
||||
frequency_max: 3.0
|
||||
rotation_accel:
|
||||
trigger_prob_per_second: 0.02
|
||||
duration_min: 3.0
|
||||
duration_max: 8.0
|
||||
multiplier_min: 0.3
|
||||
multiplier_max: 4.0
|
||||
|
||||
wounded:
|
||||
duration: 1.5 # Una mica més llarg que els altres (és un boss).
|
||||
blink_hz: 10.0
|
||||
|
||||
spawn:
|
||||
invulnerability_duration: 3.0
|
||||
invulnerability_brightness_start: 0.3
|
||||
invulnerability_brightness_end: 0.7
|
||||
invulnerability_scale_start: 0.0
|
||||
invulnerability_scale_end: 1.0
|
||||
safety_distance: 54.0 # 1.5× del normal (alineat amb scale 1.5).
|
||||
|
||||
colors:
|
||||
normal: [255, 140, 110] # taronja rosat (coral) — distintiu del boss orb.
|
||||
wounded: [255, 220, 60]
|
||||
|
||||
score: 500 # 5x un enemic normal: aguanta 10x més.
|
||||
|
||||
# Estrenant el sistema HP: 10 unitats. Cada bala fa decrease_health + flash
|
||||
# + create_debris_partial (xip a 0.3x) + create_fireworks_small (espurna).
|
||||
# Al 10è hit (HP=0), on_no_health encadena destroy directe — sense passar
|
||||
# per wounded (com Star). 10 HP ja és prou dificultat sense afegir un hit
|
||||
# extra.
|
||||
health: 10
|
||||
|
||||
events:
|
||||
on_hit:
|
||||
- action: fire_bullet # contra-atac: dispara bullet_double dirigida al jugador
|
||||
bullet: bullet_double
|
||||
bullet_speed: 200.0
|
||||
aim_mode: aimed
|
||||
- action: decrease_health # primer: si arriba a 0 dispara on_no_health
|
||||
#- action: flash # feedback visual de damage parcial
|
||||
- action: create_debris_partial # xip a 0.3x mida (sense ser letal)
|
||||
#- action: create_fireworks_small # espurna a cada hit (12 punts, lent)
|
||||
- action: apply_impulse # empenta el cos (skip si will_die)
|
||||
on_no_health:
|
||||
- action: destroy # mort directa, sense wounded
|
||||
on_destroy:
|
||||
- action: add_score
|
||||
- action: create_debris # explosió completa
|
||||
- action: create_fireworks
|
||||
@@ -0,0 +1,72 @@
|
||||
name: pentagon
|
||||
ai_type: pentagon # Validat contra el directori; mapeja a EnemyType::PENTAGON.
|
||||
|
||||
shape:
|
||||
path: enemy/pentagon.shp
|
||||
scale: 1.0 # multiplicador visual + hitbox sobre la mida nativa del .shp
|
||||
collision_factor: 1.0 # ajust opcional del hitbox (default 1.0)
|
||||
|
||||
physics:
|
||||
mass: 5.0
|
||||
speed: 35.0 # px/s (esquivador lent)
|
||||
rotation_delta_min: 0.75 # rad/s — rotació visual mínima
|
||||
rotation_delta_max: 3.75 # rad/s — rotació visual màxima
|
||||
restitution: 1.0 # rebot elàstic perfecte contra parets
|
||||
linear_damping: 0.0 # manté velocitat (sense fricció)
|
||||
angular_damping: 0.0
|
||||
|
||||
behavior:
|
||||
# Pentagon: zigzag esquivador (canvi de direcció probabilístic per segon).
|
||||
angle_change_max: 1.0 # rad — magnitud del canvi de direcció
|
||||
zigzag_prob_per_second: 0.8
|
||||
|
||||
animation:
|
||||
pulse: # respiració d'escala aleatòria
|
||||
trigger_prob_per_second: 0.01
|
||||
duration_min: 1.0
|
||||
duration_max: 3.0
|
||||
amplitude_min: 0.08
|
||||
amplitude_max: 0.20
|
||||
frequency_min: 1.5
|
||||
frequency_max: 3.0
|
||||
rotation_accel: # acceleració/desacceleració de rotació visual
|
||||
trigger_prob_per_second: 0.02
|
||||
duration_min: 3.0
|
||||
duration_max: 8.0
|
||||
multiplier_min: 0.3
|
||||
multiplier_max: 4.0
|
||||
|
||||
wounded:
|
||||
duration: 1.0 # segons en estat ferit abans d'explotar
|
||||
blink_hz: 10.0 # parpelleig color normal ↔ wounded
|
||||
|
||||
spawn:
|
||||
invulnerability_duration: 3.0
|
||||
invulnerability_brightness_start: 0.3
|
||||
invulnerability_brightness_end: 0.7
|
||||
invulnerability_scale_start: 0.0
|
||||
invulnerability_scale_end: 1.0
|
||||
safety_distance: 36.0 # px mínim respecte al player al spawn
|
||||
|
||||
colors:
|
||||
normal: [0, 255, 255] # Cyan pur "esquivador"
|
||||
wounded: [255, 220, 60] # Daurat (parpelleig al rebre impacte)
|
||||
|
||||
score: 100
|
||||
|
||||
events:
|
||||
# HP=1 (default): decrement → on_no_health → set_hurt → wounded → mort.
|
||||
# decrease_health primer perquè si la mort cau aquí (segon hit durant wounded),
|
||||
# el dispatcher salta la resta del chain (incloent apply_impulse) sobre el
|
||||
# cos ja destruït.
|
||||
on_hit:
|
||||
- action: decrease_health
|
||||
- action: apply_impulse
|
||||
on_no_health:
|
||||
- action: set_hurt
|
||||
on_hurt_end:
|
||||
- action: destroy
|
||||
on_destroy:
|
||||
- action: add_score
|
||||
- action: create_debris
|
||||
- action: create_fireworks
|
||||
@@ -0,0 +1,69 @@
|
||||
name: pinwheel
|
||||
ai_type: pinwheel # Validat contra el directori; mapeja a EnemyType::PINWHEEL.
|
||||
|
||||
shape:
|
||||
path: enemy/pinwheel.shp
|
||||
scale: 1.0 # multiplicador visual + hitbox sobre la mida nativa del .shp
|
||||
collision_factor: 1.0 # ajust opcional del hitbox (default 1.0)
|
||||
|
||||
physics:
|
||||
mass: 4.0 # Més lleuger — àgil
|
||||
speed: 50.0 # px/s (el més ràpid)
|
||||
rotation_delta_min: 3.0 # rad/s — rotació base elevada
|
||||
rotation_delta_max: 6.0
|
||||
restitution: 1.0
|
||||
linear_damping: 0.0
|
||||
angular_damping: 0.0
|
||||
|
||||
behavior:
|
||||
# Pinwheel: movement rectilíniauniforme + boost de rotació visual prop de la nau.
|
||||
rotation_proximity_multiplier: 3.0 # Multiplicador de rotació quan és prop de la nau
|
||||
proximity_distance: 100.0 # Llindar de distància (px)
|
||||
|
||||
animation:
|
||||
pulse:
|
||||
trigger_prob_per_second: 0.01
|
||||
duration_min: 1.0
|
||||
duration_max: 3.0
|
||||
amplitude_min: 0.08
|
||||
amplitude_max: 0.20
|
||||
frequency_min: 1.5
|
||||
frequency_max: 3.0
|
||||
rotation_accel:
|
||||
trigger_prob_per_second: 0.02
|
||||
duration_min: 3.0
|
||||
duration_max: 8.0
|
||||
multiplier_min: 0.3
|
||||
multiplier_max: 4.0
|
||||
|
||||
wounded:
|
||||
duration: 1.0
|
||||
blink_hz: 10.0
|
||||
|
||||
spawn:
|
||||
invulnerability_duration: 3.0
|
||||
invulnerability_brightness_start: 0.3
|
||||
invulnerability_brightness_end: 0.7
|
||||
invulnerability_scale_start: 0.0
|
||||
invulnerability_scale_end: 1.0
|
||||
safety_distance: 36.0
|
||||
|
||||
colors:
|
||||
normal: [255, 0, 255] # Magenta pur "agressiu"
|
||||
wounded: [255, 220, 60]
|
||||
|
||||
score: 200
|
||||
|
||||
events:
|
||||
# HP=1 (default): decrement → on_no_health → set_hurt → wounded → mort.
|
||||
on_hit:
|
||||
- action: decrease_health
|
||||
- action: apply_impulse
|
||||
on_no_health:
|
||||
- action: set_hurt
|
||||
on_hurt_end:
|
||||
- action: destroy
|
||||
on_destroy:
|
||||
- action: add_score
|
||||
- action: create_debris
|
||||
- action: create_fireworks
|
||||
@@ -0,0 +1,49 @@
|
||||
name: player_ship
|
||||
|
||||
# Shape de la nau. Resolt per ShapeLoader (busca a "shapes/<path>").
|
||||
# Nota: el segon jugador rep un override del shape ("ship/wedge.shp") al ctor.
|
||||
# Quan s'introdueixin variants reals de nau, es crearà un YAML separat
|
||||
# per cada model.
|
||||
#
|
||||
# scale: multiplicador visual i de hitbox sobre la mida nativa del .shp (1.0 = mida del fitxer).
|
||||
# collision_factor: ajust opcional del hitbox respecte el cercle circumscrit
|
||||
# automàtic de la shape; tocar només si el feel del hitbox
|
||||
# no quadra amb la silueta visual (default 1.0).
|
||||
shape:
|
||||
path: ship/arrow.shp
|
||||
scale: 1.0
|
||||
collision_factor: 1.0
|
||||
|
||||
physics:
|
||||
mass: 10.0
|
||||
restitution: 0.6
|
||||
linear_damping: 1.5
|
||||
angular_damping: 0.0
|
||||
rotation_speed: 3.14 # rad/s (~180 deg/s, input-driven sense inercia)
|
||||
acceleration: 400.0 # px/s^2 multiplicat per la massa quan THRUST
|
||||
max_velocity: 180.0 # px/s (clamp post-integració per preservar feel arcade)
|
||||
# Factor de transferència del moment lineal de la nau a l'enemic en el
|
||||
# frame exacte que mor per col·lisió (afegit per damunt del rebot natural).
|
||||
death_impact_factor: 0.3
|
||||
|
||||
invulnerability:
|
||||
duration: 3.0 # segons d'invulnerabilitat post-respawn
|
||||
blink_visible: 0.1 # segons visible per cicle de parpelleig
|
||||
blink_invisible: 0.1 # segons invisible per cicle de parpelleig
|
||||
|
||||
hurt:
|
||||
duration: 15.0 # segons en estat "ferit" abans de tornar a normal
|
||||
blink_hz: 10.0 # freqüència parpelleig color normal <-> color hurt
|
||||
|
||||
# Empenta visual: la nau s'escala lleugerament amb la velocitat.
|
||||
# Manté la sensació del Pascal original (0..MAX_VEL → 1.0..~1.5).
|
||||
visual_thrust:
|
||||
push_divisor: 33.33
|
||||
scale_divisor: 12.0
|
||||
|
||||
colors:
|
||||
normal: [255, 255, 255] # blanc neutre
|
||||
hurt: [255, 0, 0] # roig pur (estat ferit)
|
||||
|
||||
weapon:
|
||||
bullet_speed: 700.0 # velocitat escalar de la bullet (px/s)
|
||||
@@ -0,0 +1,70 @@
|
||||
name: square
|
||||
ai_type: square # Validat contra el directori; mapeja a EnemyType::SQUARE.
|
||||
|
||||
shape:
|
||||
path: enemy/square.shp
|
||||
scale: 1.0 # multiplicador visual + hitbox sobre la mida nativa del .shp
|
||||
collision_factor: 1.0 # ajust opcional del hitbox (default 1.0)
|
||||
|
||||
physics:
|
||||
mass: 8.0 # Més pesat — "tanc"
|
||||
speed: 40.0 # px/s (velocitat mitjana)
|
||||
rotation_delta_min: 0.3 # rad/s — rotació lenta
|
||||
rotation_delta_max: 1.5
|
||||
restitution: 1.0
|
||||
linear_damping: 0.0
|
||||
angular_damping: 0.0
|
||||
|
||||
ai:
|
||||
# Square: persecució contínua del ship més proper (steering suau, "tanc lent").
|
||||
movement:
|
||||
type: chase
|
||||
chase_strength: 0.5 # Força/segon de la LERP cap a la direcció ideal (1.0 = ~1s per realinear)
|
||||
|
||||
animation:
|
||||
pulse:
|
||||
trigger_prob_per_second: 0.01
|
||||
duration_min: 1.0
|
||||
duration_max: 3.0
|
||||
amplitude_min: 0.08
|
||||
amplitude_max: 0.20
|
||||
frequency_min: 1.5
|
||||
frequency_max: 3.0
|
||||
rotation_accel:
|
||||
trigger_prob_per_second: 0.02
|
||||
duration_min: 3.0
|
||||
duration_max: 8.0
|
||||
multiplier_min: 0.3
|
||||
multiplier_max: 4.0
|
||||
|
||||
wounded:
|
||||
duration: 1.0
|
||||
blink_hz: 10.0
|
||||
|
||||
spawn:
|
||||
invulnerability_duration: 3.0
|
||||
invulnerability_brightness_start: 0.3
|
||||
invulnerability_brightness_end: 0.7
|
||||
invulnerability_scale_start: 0.0
|
||||
invulnerability_scale_end: 1.0
|
||||
safety_distance: 36.0
|
||||
|
||||
colors:
|
||||
normal: [255, 0, 0] # Roig pur "tanc"
|
||||
wounded: [255, 220, 60]
|
||||
|
||||
score: 150
|
||||
|
||||
events:
|
||||
# HP=1 (default): decrement → on_no_health → set_hurt → wounded → mort.
|
||||
on_hit:
|
||||
- action: decrease_health
|
||||
- action: apply_impulse
|
||||
on_no_health:
|
||||
- action: set_hurt
|
||||
on_hurt_end:
|
||||
- action: destroy
|
||||
on_destroy:
|
||||
- action: add_score
|
||||
- action: create_debris
|
||||
- action: create_fireworks
|
||||
@@ -0,0 +1,77 @@
|
||||
name: star
|
||||
ai_type: star # Validat contra el directori; mapeja a EnemyType::STAR.
|
||||
|
||||
shape:
|
||||
path: enemy/star.shp
|
||||
scale: 0.7 # Lleugerament més petit que els altres enemics per diferenciar visualment.
|
||||
collision_factor: 1.0
|
||||
|
||||
physics:
|
||||
mass: 5.0
|
||||
speed: 35.0 # Mateixos paràmetres que pentagon (esquivador lent).
|
||||
rotation_delta_min: 0.75
|
||||
rotation_delta_max: 3.75
|
||||
restitution: 1.0
|
||||
linear_damping: 0.0
|
||||
angular_damping: 0.0
|
||||
|
||||
ai:
|
||||
# Movement: zigzag esquivador (com Pentagon).
|
||||
movement:
|
||||
type: zigzag
|
||||
angle_change_max: 1.0
|
||||
zigzag_prob_per_second: 0.8
|
||||
# Accions periòdiques: cada ~2.5s dispara una bala apuntada al ship més proper.
|
||||
tick:
|
||||
- action: shoot
|
||||
interval: 2.5
|
||||
aim_mode: aimed # apunta al ship més proper (atan2)
|
||||
jitter_rad: 0.0 # sense soroll: tret perfecte
|
||||
bullet: bullet_long # variant més visible per al jugador
|
||||
bullet_speed: 150.0 # px/s — prou lenta per reaccionar
|
||||
|
||||
animation:
|
||||
pulse:
|
||||
trigger_prob_per_second: 0.01
|
||||
duration_min: 1.0
|
||||
duration_max: 3.0
|
||||
amplitude_min: 0.08
|
||||
amplitude_max: 0.20
|
||||
frequency_min: 1.5
|
||||
frequency_max: 3.0
|
||||
rotation_accel:
|
||||
trigger_prob_per_second: 0.02
|
||||
duration_min: 3.0
|
||||
duration_max: 8.0
|
||||
multiplier_min: 0.3
|
||||
multiplier_max: 4.0
|
||||
|
||||
wounded:
|
||||
duration: 1.0
|
||||
blink_hz: 10.0
|
||||
|
||||
spawn:
|
||||
invulnerability_duration: 3.0
|
||||
invulnerability_brightness_start: 0.3
|
||||
invulnerability_brightness_end: 0.7
|
||||
invulnerability_scale_start: 0.0
|
||||
invulnerability_scale_end: 1.0
|
||||
safety_distance: 36.0
|
||||
|
||||
colors:
|
||||
normal: [255, 255, 0] # Groc estrella
|
||||
wounded: [255, 220, 60]
|
||||
|
||||
score: 100
|
||||
|
||||
events:
|
||||
# STAR: mor al primer impacte, sense passar per wounded.
|
||||
# HP=1 (default): decrement → on_no_health → destroy directe (sense wounded).
|
||||
on_hit:
|
||||
- action: decrease_health
|
||||
on_no_health:
|
||||
- action: destroy
|
||||
on_destroy:
|
||||
- action: add_score
|
||||
- action: create_debris
|
||||
- action: create_fireworks
|
||||
@@ -0,0 +1,116 @@
|
||||
# Orni Attack - locale: Catala (valencia)
|
||||
# Interficie traduida; pool in-game identic a en.yaml (es queda en angles).
|
||||
# Tots els textos en ASCII: VectorText no suporta caracters accentuats.
|
||||
|
||||
notification:
|
||||
press_again_exit: "PREMEU ESC UN ALTRE COP PER EIXIR"
|
||||
zoom: "ZOOM: {z}X"
|
||||
fullscreen_on: "PANTALLA COMPLETA"
|
||||
fullscreen_off: "MODE FINESTRA"
|
||||
vsync_on: "VSYNC ACTIU"
|
||||
vsync_off: "VSYNC INACTIU"
|
||||
antialias_on: "AA ACTIU"
|
||||
antialias_off: "AA INACTIU"
|
||||
postfx_on: "POSTPROCESSAT ACTIU"
|
||||
postfx_off: "POSTPROCESSAT INACTIU"
|
||||
screenshot: "IMATGE {file} GUARDADA A {folder}"
|
||||
locale_switched: "IDIOMA: {lang}"
|
||||
gamepad_connected: "{name} CONNECTAT"
|
||||
gamepad_disconnected: "{name} DESCONNECTAT"
|
||||
|
||||
language:
|
||||
ca: "CATALA"
|
||||
en: "ANGLES"
|
||||
|
||||
hud:
|
||||
level: "NIVELL "
|
||||
|
||||
title:
|
||||
press_start: "PREMEU START PER JUGAR"
|
||||
|
||||
demo:
|
||||
banner: "MODE DEMO - PREMEU START"
|
||||
|
||||
game_screen:
|
||||
game_over: "FI DEL JOC"
|
||||
continue: "CONTINUAR"
|
||||
continues_left: "CONTINUACIONS: {n}"
|
||||
|
||||
stage:
|
||||
start:
|
||||
- "ORNI ALERT!"
|
||||
- "INCOMING ORNIS!"
|
||||
- "ROLLING THREAT!"
|
||||
- "ENEMY WAVE!"
|
||||
- "WAVE OF ORNIS DETECTED!"
|
||||
- "NEXT SWARM APPROACHING!"
|
||||
- "BRACE FOR THE NEXT WAVE!"
|
||||
- "ANOTHER ATTACK INCOMING!"
|
||||
- "SENSORS DETECT HOSTILE ORNIS..."
|
||||
- "UNIDENTIFIED ROLLING OBJECTS INBOUND!"
|
||||
- "ENEMY FORCES MOBILIZING!"
|
||||
- "PREPARE FOR IMPACT!"
|
||||
completed: "GOOD JOB COMMANDER!"
|
||||
|
||||
service_menu:
|
||||
title: "MENU DE SERVEI"
|
||||
video: "VIDEO"
|
||||
audio: "AUDIO"
|
||||
options: "OPCIONS"
|
||||
system: "SISTEMA"
|
||||
controls: "CONTROLS"
|
||||
back: "ENRERE"
|
||||
exit: "EIXIR DEL JOC"
|
||||
# Items del submenu VIDEO
|
||||
video_zoom: "ZOOM"
|
||||
video_fullscreen: "PANTALLA COMPLETA"
|
||||
video_vsync: "VSYNC"
|
||||
video_aa: "ANTIALIAS"
|
||||
video_postfx: "POSTPROCESSAT"
|
||||
video_resolution: "RESOLUCIO"
|
||||
# Items del submenu OPCIONS
|
||||
options_language: "IDIOMA"
|
||||
options_show_info: "MOSTRAR INFO"
|
||||
# Items del submenu AUDIO
|
||||
audio_master: "AUDIO"
|
||||
audio_master_volume: "VOLUM GENERAL"
|
||||
audio_music: "MUSICA"
|
||||
audio_music_volume: "VOLUM MUSICA"
|
||||
audio_sound: "EFECTES"
|
||||
audio_sound_volume: "VOLUM EFECTES"
|
||||
# Items del submenu SISTEMA
|
||||
system_restart: "REINICIAR"
|
||||
# Pagines de confirmacio (estructura: titol + NO/SI)
|
||||
confirm_restart: "ESTAS SEGUR DE REINICIAR?"
|
||||
confirm_exit: "ESTAS SEGUR DE EIXIR?"
|
||||
confirm_no: "NO"
|
||||
confirm_yes: "SI"
|
||||
# Valors comuns
|
||||
value_on: "ACTIU"
|
||||
value_off: "INACTIU"
|
||||
# Items del submenu CONTROLS
|
||||
controls_pad_p1: "MANDO JUGADOR 1"
|
||||
controls_pad_p2: "MANDO JUGADOR 2"
|
||||
controls_no_pad: "SENSE MANDO"
|
||||
controls_define_keyboard_p1: "REDEFINIR TECLES P1"
|
||||
controls_define_keyboard_p2: "REDEFINIR TECLES P2"
|
||||
controls_define_gamepad_p1: "REDEFINIR BOTONS P1"
|
||||
controls_define_gamepad_p2: "REDEFINIR BOTONS P2"
|
||||
|
||||
# Overlay modal de redefinicio (DefineInputs)
|
||||
define:
|
||||
title_keyboard_p1: "REDEFINIR TECLES P1"
|
||||
title_keyboard_p2: "REDEFINIR TECLES P2"
|
||||
title_gamepad_p1: "REDEFINIR BOTONS P1"
|
||||
title_gamepad_p2: "REDEFINIR BOTONS P2"
|
||||
press_key: "PREMEU UNA TECLA"
|
||||
press_button: "PREMEU UN BOTO"
|
||||
complete: "CONFIGURACIO COMPLETA"
|
||||
no_gamepad: "CAP MANDO ASSIGNAT AL JUGADOR"
|
||||
action:
|
||||
left: "ESQUERRA"
|
||||
right: "DRETA"
|
||||
fire: "DISPARAR"
|
||||
accelerate: "ACCELERAR"
|
||||
start: "START"
|
||||
menu: "MENU"
|
||||
@@ -0,0 +1,115 @@
|
||||
# Orni Attack - locale: English
|
||||
# In-game pool kept English in both locales per design.
|
||||
|
||||
notification:
|
||||
press_again_exit: "PRESS ESC AGAIN TO EXIT"
|
||||
zoom: "ZOOM: {z}X"
|
||||
fullscreen_on: "FULLSCREEN"
|
||||
fullscreen_off: "WINDOWED"
|
||||
vsync_on: "VSYNC ON"
|
||||
vsync_off: "VSYNC OFF"
|
||||
antialias_on: "AA ON"
|
||||
antialias_off: "AA OFF"
|
||||
postfx_on: "POSTPROCESS ON"
|
||||
postfx_off: "POSTPROCESS OFF"
|
||||
screenshot: "IMAGE {file} SAVED AT {folder}"
|
||||
locale_switched: "LANGUAGE: {lang}"
|
||||
gamepad_connected: "{name} CONNECTED"
|
||||
gamepad_disconnected: "{name} DISCONNECTED"
|
||||
|
||||
language:
|
||||
ca: "CATALAN"
|
||||
en: "ENGLISH"
|
||||
|
||||
hud:
|
||||
level: "LEVEL "
|
||||
|
||||
title:
|
||||
press_start: "PRESS START TO PLAY"
|
||||
|
||||
demo:
|
||||
banner: "DEMO MODE - PRESS START"
|
||||
|
||||
game_screen:
|
||||
game_over: "GAME OVER"
|
||||
continue: "CONTINUE"
|
||||
continues_left: "CONTINUES LEFT: {n}"
|
||||
|
||||
stage:
|
||||
start:
|
||||
- "ORNI ALERT!"
|
||||
- "INCOMING ORNIS!"
|
||||
- "ROLLING THREAT!"
|
||||
- "ENEMY WAVE!"
|
||||
- "WAVE OF ORNIS DETECTED!"
|
||||
- "NEXT SWARM APPROACHING!"
|
||||
- "BRACE FOR THE NEXT WAVE!"
|
||||
- "ANOTHER ATTACK INCOMING!"
|
||||
- "SENSORS DETECT HOSTILE ORNIS..."
|
||||
- "UNIDENTIFIED ROLLING OBJECTS INBOUND!"
|
||||
- "ENEMY FORCES MOBILIZING!"
|
||||
- "PREPARE FOR IMPACT!"
|
||||
completed: "GOOD JOB COMMANDER!"
|
||||
|
||||
service_menu:
|
||||
title: "SERVICE MENU"
|
||||
video: "VIDEO"
|
||||
audio: "AUDIO"
|
||||
options: "OPTIONS"
|
||||
system: "SYSTEM"
|
||||
controls: "CONTROLS"
|
||||
back: "BACK"
|
||||
exit: "EXIT GAME"
|
||||
# Items of VIDEO submenu
|
||||
video_zoom: "ZOOM"
|
||||
video_fullscreen: "FULLSCREEN"
|
||||
video_vsync: "VSYNC"
|
||||
video_aa: "ANTIALIAS"
|
||||
video_postfx: "POSTPROCESS"
|
||||
video_resolution: "RESOLUTION"
|
||||
# Items of OPTIONS submenu
|
||||
options_language: "LANGUAGE"
|
||||
options_show_info: "SHOW INFO"
|
||||
# Items of AUDIO submenu
|
||||
audio_master: "AUDIO"
|
||||
audio_master_volume: "MASTER VOLUME"
|
||||
audio_music: "MUSIC"
|
||||
audio_music_volume: "MUSIC VOLUME"
|
||||
audio_sound: "SOUNDS"
|
||||
audio_sound_volume: "SOUND VOLUME"
|
||||
# Items of SYSTEM submenu
|
||||
system_restart: "RESTART"
|
||||
# Confirmation pages (structure: title + NO/YES)
|
||||
confirm_restart: "REALLY RESTART?"
|
||||
confirm_exit: "REALLY EXIT?"
|
||||
confirm_no: "NO"
|
||||
confirm_yes: "YES"
|
||||
# Common values
|
||||
value_on: "ON"
|
||||
value_off: "OFF"
|
||||
# Items of CONTROLS submenu
|
||||
controls_pad_p1: "PLAYER 1 GAMEPAD"
|
||||
controls_pad_p2: "PLAYER 2 GAMEPAD"
|
||||
controls_no_pad: "NO GAMEPAD"
|
||||
controls_define_keyboard_p1: "REDEFINE KEYS P1"
|
||||
controls_define_keyboard_p2: "REDEFINE KEYS P2"
|
||||
controls_define_gamepad_p1: "REDEFINE BUTTONS P1"
|
||||
controls_define_gamepad_p2: "REDEFINE BUTTONS P2"
|
||||
|
||||
# Modal overlay for input redefinition (DefineInputs)
|
||||
define:
|
||||
title_keyboard_p1: "REDEFINE KEYS P1"
|
||||
title_keyboard_p2: "REDEFINE KEYS P2"
|
||||
title_gamepad_p1: "REDEFINE BUTTONS P1"
|
||||
title_gamepad_p2: "REDEFINE BUTTONS P2"
|
||||
press_key: "PRESS A KEY"
|
||||
press_button: "PRESS A BUTTON"
|
||||
complete: "CONFIGURATION COMPLETE"
|
||||
no_gamepad: "NO GAMEPAD ASSIGNED TO PLAYER"
|
||||
action:
|
||||
left: "LEFT"
|
||||
right: "RIGHT"
|
||||
fire: "FIRE"
|
||||
accelerate: "ACCELERATE"
|
||||
start: "START"
|
||||
menu: "MENU"
|
||||
@@ -1,23 +0,0 @@
|
||||
# bullet.shp - Projectil (petit pentàgon)
|
||||
# © 1999 Visente i Sergi (versió Pascal)
|
||||
# © 2025 Port a C++20 amb SDL3
|
||||
|
||||
name: bullet
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Cercle (octàgon regular radi=3)
|
||||
# 8 punts equidistants (45° entre ells) per aproximar un cercle
|
||||
# Començant a angle=-90° (amunt), rotant sentit horari
|
||||
#
|
||||
# Conversió polar→cartesià (radi=3, SDL: Y creix cap avall):
|
||||
# angle=-90°: (0.00, -3.00)
|
||||
# angle=-45°: (2.12, -2.12)
|
||||
# angle=0°: (3.00, 0.00)
|
||||
# angle=45°: (2.12, 2.12)
|
||||
# angle=90°: (0.00, 3.00)
|
||||
# angle=135°: (-2.12, 2.12)
|
||||
# angle=180°: (-3.00, 0.00)
|
||||
# angle=225°: (-2.12, -2.12)
|
||||
|
||||
polyline: 0,-3 2.12,-2.12 3,0 2.12,2.12 0,3 -2.12,2.12 -3,0 -2.12,-2.12 0,-3
|
||||
@@ -0,0 +1,7 @@
|
||||
# bullet/basic.shp - Projectil (octàgon, radi=3)
|
||||
|
||||
name: basic
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
polyline: 0,-3 2.12,-2.12 3,0 2.12,2.12 0,3 -2.12,2.12 -3,0 -2.12,-2.12 0,-3
|
||||
@@ -0,0 +1,17 @@
|
||||
# bullet/double.shp - Bala anular (dos cercles concèntrics)
|
||||
# © 2026 JailDesigner
|
||||
#
|
||||
# Dos octàgons concèntrics al centre (0,0):
|
||||
# - Exterior: radi 4 (lleugerament més gran que la bala estàndard, radi 3)
|
||||
# - Interior: radi 2 (lleugerament més petit que la bala estàndard)
|
||||
# Aspecte d'anell / aura de plasma. Bounding radius natiu = 4.
|
||||
|
||||
name: double
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Cercle exterior (octàgon, radi 4)
|
||||
polyline: 0,-4 2.83,-2.83 4,0 2.83,2.83 0,4 -2.83,2.83 -4,0 -2.83,-2.83 0,-4
|
||||
|
||||
# Cercle interior (octàgon, radi 2)
|
||||
polyline: 0,-2 1.41,-1.41 2,0 1.41,1.41 0,2 -1.41,1.41 -2,0 -1.41,-1.41 0,-2
|
||||
@@ -0,0 +1,32 @@
|
||||
# bullet/long.shp - Bala allargada vertical (dos mig-octàgons + dos costats)
|
||||
# © 2026 JailDesigner
|
||||
#
|
||||
# Càpsula orientada al llarg de l'eix Y: la bala viatja segons el seu angle
|
||||
# de moviment (angle=0 = Y negatiu), i així s'estira en la direcció de vol.
|
||||
# Es dibuixen només els segments exteriors per evitar veure la unió interna
|
||||
# dels dos cercles; el resultat visual són dos "mig-octàgons" separats per
|
||||
# un petit gap al centre, units pels dos costats verticals.
|
||||
#
|
||||
# Geometria:
|
||||
# Mig-octàgon superior (radi 3) centrat a (0, -3)
|
||||
# Mig-octàgon inferior (radi 3) centrat a (0, 3)
|
||||
# Punt extrem superior: (0, -6)
|
||||
# Punt extrem inferior: (0, 6)
|
||||
# Bounding radius natiu = 6 (extrem vertical a y=±6).
|
||||
# collision_factor al YAML compensa el bounding doble (0.5 → hitbox ≈ 3).
|
||||
|
||||
name: long
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Mig-octàgon superior (5 vèrtexs: del cantó dret cap al punt extrem i a l'esquerre)
|
||||
polyline: 3,-3 2.12,-5.12 0,-6 -2.12,-5.12 -3,-3
|
||||
|
||||
# Mig-octàgon inferior
|
||||
polyline: 3,3 2.12,5.12 0,6 -2.12,5.12 -3,3
|
||||
|
||||
# Costat dret (uneix extrem inferior del mig superior amb extrem superior del mig inferior)
|
||||
polyline: 3,-3 3,3
|
||||
|
||||
# Costat esquerre
|
||||
polyline: -3,-3 -3,3
|
||||
@@ -1,7 +1,7 @@
|
||||
# star.shp - Estrella per a starfield
|
||||
# © 2025 Orni Attack
|
||||
# effect/starfield.shp - Estrella per a starfield
|
||||
# © 2026 JailDesigner
|
||||
|
||||
name: star
|
||||
name: starfield
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# effect/title_flash.shp - Sparkle 4-puntes amb costats còncaus (Atari-style)
|
||||
# 4 puntes als cardinals (radi 30) i valls còncaus als 45° (corba Bezier
|
||||
# quadràtica amb control point ±8). 5 punts per arc subdividint la corba.
|
||||
|
||||
name: title_flash
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
polyline: 0,-30 3.76,-21.76 8.64,-14.64 14.64,-8.64 21.76,-3.76 30,0 21.76,3.76 14.64,8.64 8.64,14.64 3.76,21.76 0,30 -3.76,21.76 -8.64,14.64 -14.64,8.64 -21.76,3.76 -30,0 -21.76,-3.76 -14.64,-8.64 -8.64,-14.64 -3.76,-21.76 0,-30
|
||||
@@ -0,0 +1,32 @@
|
||||
# enemy/orb.shp - ORNI enemic gegant (orb circular, doble anell amb radis)
|
||||
# © 2026 JailDesigner
|
||||
#
|
||||
# Forma "reactor / boss circular" — més detall que els enemics petits perquè
|
||||
# es renderitza a escala 1.5x i ha de llegir-se com a amenaça gran.
|
||||
# - Anell exterior: dodecàgon (12 vèrtexs) — aparença circular suau, radi 20.
|
||||
# - Anell interior: hexàgon (6 vèrtexs, rotat 30°) — radi 10.
|
||||
# - 6 radis curts que connecten l'anell interior amb l'exterior.
|
||||
# - Petit "+" central com a nucli.
|
||||
# Bounding radius natiu = 20 (alineat amb la resta d'enemics).
|
||||
|
||||
name: orb
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Anell exterior (dodecàgon, vèrtex apuntant amunt)
|
||||
polyline: 0,-20 10,-17.32 17.32,-10 20,0 17.32,10 10,17.32 0,20 -10,17.32 -17.32,10 -20,0 -17.32,-10 -10,-17.32 0,-20
|
||||
|
||||
# Anell interior (hexàgon, vèrtex apuntant a la dreta — rotat 30° respecte l'exterior)
|
||||
polyline: 5,-8.66 10,0 5,8.66 -5,8.66 -10,0 -5,-8.66 5,-8.66
|
||||
|
||||
# 6 radis: del vèrtex de l'hexàgon interior al vèrtex corresponent del dodecàgon exterior
|
||||
line: 5,-8.66 10,-17.32
|
||||
line: 10,0 20,0
|
||||
line: 5,8.66 10,17.32
|
||||
line: -5,8.66 -10,17.32
|
||||
line: -10,0 -20,0
|
||||
line: -5,-8.66 -10,-17.32
|
||||
|
||||
# Nucli central: petit "+" (2 segments creuats, radi 3)
|
||||
line: -3,0 3,0
|
||||
line: 0,-3 0,3
|
||||
@@ -0,0 +1,11 @@
|
||||
# enemy/pentagon.shp - ORNI enemic (pentàgon doble concentric, radi exterior=20)
|
||||
|
||||
name: pentagon
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Pentàgon exterior (vèrtex apuntant amunt, radi 20)
|
||||
polyline: 0,-20 19.02,-6.18 11.76,16.18 -11.76,16.18 -19.02,-6.18 0,-20
|
||||
|
||||
# Pentàgon interior (radi 10, rotat 36° → vèrtex apuntant a les arestes exteriors)
|
||||
polyline: 5.88,-8.09 9.51,3.09 0,10 -9.51,3.09 -5.88,-8.09 5.88,-8.09
|
||||
@@ -1,7 +1,7 @@
|
||||
# enemy_pinwheel.shp - ORNI enemic (molinillo de 4 triangles)
|
||||
# © 2025 Port a C++20 amb SDL3
|
||||
# enemy/pinwheel.shp - ORNI enemic (molinillo de 4 triangles)
|
||||
# © 2026 JailDesigner
|
||||
|
||||
name: enemy_pinwheel
|
||||
name: pinwheel
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# enemy/square.shp - ORNI enemic (rombe, radi=20) + ull amb pupil·la al centre
|
||||
|
||||
name: square
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Rombe exterior
|
||||
polyline: 0,-20 20,0 0,20 -20,0 0,-20
|
||||
|
||||
# Ull (dos arcs units, forma d'almetlla). Amplada 20px, altura 8px.
|
||||
polyline: -10,0 -5,-3 0,-4 5,-3 10,0 5,3 0,4 -5,3 -10,0
|
||||
|
||||
# Pupil·la (octàgon, radi 2) al centre
|
||||
polyline: 0,-2 1.41,-1.41 2,0 1.41,1.41 0,2 -1.41,1.41 -2,0 -1.41,-1.41 0,-2
|
||||
@@ -0,0 +1,15 @@
|
||||
# enemy/star.shp - ORNI enemic (estrella de 5 puntes, només perímetre)
|
||||
# © 2026 JailDesigner
|
||||
#
|
||||
# Pentagrama clàssic: 5 vèrtexs exteriors (radi 20) alternant amb 5 vèrtexs
|
||||
# interiors (radi 7.64 = 20/φ² ≈ proporció àuria) per donar puntes esveltes.
|
||||
# Vèrtex apuntant amunt (igual que enemy_pentagon).
|
||||
#
|
||||
# Sense línies interiors: una única polyline que recorre el perímetre.
|
||||
# Bounding radius natiu ≈ 20 (alineat amb pentagon/square/pinwheel).
|
||||
|
||||
name: star
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
polyline: 0,-20 4.49,-6.18 19.02,-6.18 7.27,2.36 11.76,16.18 0,7.64 -11.76,16.18 -7.27,2.36 -19.02,-6.18 -4.49,-6.18 0,-20
|
||||
@@ -1,21 +0,0 @@
|
||||
# enemy_pentagon.shp - ORNI enemic (pentàgon regular)
|
||||
# © 1999 Visente i Sergi (versió Pascal)
|
||||
# © 2025 Port a C++20 amb SDL3
|
||||
|
||||
name: enemy_pentagon
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Pentàgon regular radi=20
|
||||
# 5 punts equidistants al voltant d'un cercle (72° entre ells)
|
||||
# Començant a angle=-90° (amunt), rotant sentit antihorari
|
||||
#
|
||||
# Angles: -90°, -18°, 54°, 126°, 198°
|
||||
# Conversió polar→cartesià (SDL: Y creix cap avall):
|
||||
# angle=-90°: (0.00, -20.00)
|
||||
# angle=-18°: (19.02, -6.18)
|
||||
# angle=54°: (11.76, 16.18)
|
||||
# angle=126°: (-11.76, 16.18)
|
||||
# angle=198°: (-19.02, -6.18)
|
||||
|
||||
polyline: 0,-20 19.02,-6.18 11.76,16.18 -11.76,16.18 -19.02,-6.18 0,-20
|
||||
@@ -1,19 +0,0 @@
|
||||
# enemy_square.shp - ORNI enemic (quadrat regular)
|
||||
# © 2025 Port a C++20 amb SDL3
|
||||
|
||||
name: enemy_square
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Quadrat regular radi=20 (circumscrit)
|
||||
# 4 punts equidistants al voltant d'un cercle (90° entre ells)
|
||||
# Començant a angle=-90° (amunt), rotant sentit horari
|
||||
#
|
||||
# Angles: -90°, 0°, 90°, 180°
|
||||
# Conversió polar→cartesià (SDL: Y creix cap avall):
|
||||
# angle=-90°: (0.00, -20.00)
|
||||
# angle=0°: (20.00, 0.00)
|
||||
# angle=90°: (0.00, 20.00)
|
||||
# angle=180°: (-20.00, 0.00)
|
||||
|
||||
polyline: 0,-20 20,0 0,20 -20,0 0,-20
|
||||
@@ -0,0 +1,9 @@
|
||||
# char_lparen.shp - Símbol ( (parèntesi esquerre)
|
||||
# Dimensions: 20×40 (blocky display)
|
||||
|
||||
name: char_lparen
|
||||
scale: 1.0
|
||||
center: 10, 20
|
||||
|
||||
# Arc cap a l'esquerra aproximat amb 4 trams rectes
|
||||
polyline: 14,4 8,12 6,20 8,28 14,36
|
||||
@@ -0,0 +1,9 @@
|
||||
# char_rparen.shp - Símbol ) (parèntesi dret)
|
||||
# Dimensions: 20×40 (blocky display)
|
||||
|
||||
name: char_rparen
|
||||
scale: 1.0
|
||||
center: 10, 20
|
||||
|
||||
# Arc cap a la dreta aproximat amb 4 trams rectes
|
||||
polyline: 6,4 12,12 14,20 12,28 6,36
|
||||
@@ -0,0 +1,9 @@
|
||||
# char_slash.shp - Símbol / (barra)
|
||||
# Dimensions: 20×40 (blocky display)
|
||||
|
||||
name: char_slash
|
||||
scale: 1.0
|
||||
center: 10, 20
|
||||
|
||||
# Línia diagonal de baix-esquerra a dalt-dreta
|
||||
line: 4,36 16,4
|
||||
@@ -0,0 +1,9 @@
|
||||
# char_underscore.shp - Símbolo _ (barra baja)
|
||||
# Dimensiones: 20×40 (blocky display)
|
||||
|
||||
name: char_underscore
|
||||
scale: 1.0
|
||||
center: 10, 20
|
||||
|
||||
# Línea horizontal abajo (bajo la baseline de las letras)
|
||||
line: 3,33 17,33
|
||||
@@ -1,24 +0,0 @@
|
||||
# ship.shp - Nau del jugador 1 (triangle amb base còncava - punta de fletxa)
|
||||
# © 1999 Visente i Sergi (versió Pascal)
|
||||
# © 2025 Port a C++20 amb SDL3
|
||||
|
||||
name: ship
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Triangle amb base còncava tipus "punta de fletxa"
|
||||
# Punts originals (polar):
|
||||
# p1: r=12, angle=270° (3π/2) → punta amunt
|
||||
# p2: r=12, angle=45° (π/4) → base dreta-darrere
|
||||
# p3: r=12, angle=135° (3π/4) → base esquerra-darrere
|
||||
#
|
||||
# MODIFICACIÓ: afegit p4 al mig de la base, desplaçat cap al centre
|
||||
# p4: (0, 4) → punt central de la base, cap endins
|
||||
#
|
||||
# Conversió polar→cartesià (angle-90° perquè origen visual és amunt):
|
||||
# p1: (0, -12) → punta
|
||||
# p2: (8.49, 8.49) → base dreta
|
||||
# p4: (0, 4) → base centre (cap endins)
|
||||
# p3: (-8.49, 8.49) → base esquerra
|
||||
|
||||
polyline: 0,-12 8.49,8.49 0,4 -8.49,8.49 0,-12
|
||||
@@ -0,0 +1,7 @@
|
||||
# ship/arrow.shp - Nau del jugador 1 (triangle amb base còncava, punta de fletxa)
|
||||
|
||||
name: arrow
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
polyline: 0,-12 8.49,8.49 0,4 -8.49,8.49 0,-12
|
||||
@@ -1,7 +1,7 @@
|
||||
# ship2.shp - Nau del jugador 2 (interceptor amb ales)
|
||||
# © 2025 Orni Attack - Jugador 2
|
||||
# ship/interceptor.shp - Interceptor amb ales laterals pronunciades
|
||||
# © 2026 JailDesigner
|
||||
|
||||
name: ship2
|
||||
name: interceptor
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# ship/wedge.shp - Nau del jugador 2 (triangle amb cercle central)
|
||||
|
||||
name: wedge
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
polyline: 0,-12 8.49,8.49 -8.49,8.49 0,-12
|
||||
|
||||
# Octàgon central (radi=2.5)
|
||||
polyline: 0,-2.5 1.77,-1.77 2.5,0 1.77,1.77 0,2.5 -1.77,1.77 -2.5,0 -1.77,-1.77 0,-2.5
|
||||
@@ -1,30 +0,0 @@
|
||||
# ship2.shp - Nau del jugador 2 (triangle amb circulito central)
|
||||
# © 1999 Visente i Sergi (versió Pascal)
|
||||
# © 2025 Port a C++20 amb SDL3
|
||||
|
||||
name: ship2
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# Triangle amb base còncava tipus "punta de fletxa"
|
||||
# (Mateix que ship.shp)
|
||||
# Punts originals (polar):
|
||||
# p1: r=12, angle=270° (3π/2) → punta amunt
|
||||
# p2: r=12, angle=45° (π/4) → base dreta-darrere
|
||||
# p3: r=12, angle=135° (3π/4) → base esquerra-darrere
|
||||
#
|
||||
# MODIFICACIÓ: afegit p4 al mig de la base, desplaçat cap al centre
|
||||
# p4: (0, 4) → punt central de la base, cap endins
|
||||
#
|
||||
# Conversió polar→cartesià (angle-90° perquè origen visual és amunt):
|
||||
# p1: (0, -12) → punta
|
||||
# p2: (8.49, 8.49) → base dreta
|
||||
# p4: (0, 4) → base centre (cap endins)
|
||||
# p3: (-8.49, 8.49) → base esquerra
|
||||
|
||||
#polyline: 0,-12 8.49,8.49 0,4 -8.49,8.49 0,-12
|
||||
polyline: 0,-12 8.49,8.49 -8.49,8.49 0,-12
|
||||
|
||||
# Circulito central (octàgon r=2.5)
|
||||
# Distintiu visual del jugador 2
|
||||
polyline: 0,-2.5 1.77,-1.77 2.5,0 1.77,1.77 0,2.5 -1.77,1.77 -2.5,0 -1.77,-1.77 0,-2.5
|
||||
@@ -1,28 +0,0 @@
|
||||
# ship2_perspective.shp - Nave P2 con perspectiva pre-calculada
|
||||
# Posición optimizada: "4 del reloj" (Abajo-Derecha)
|
||||
# Dirección: Volando hacia el fondo (centro pantalla)
|
||||
|
||||
name: ship2_perspective
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# TRANSFORMACIÓN APLICADA:
|
||||
# 1. Rotación -45° (apuntando al centro desde abajo-dcha)
|
||||
# 2. Proyección de perspectiva:
|
||||
# - Punta (p1): Reducida al 60% (simula lejanía)
|
||||
# - Base (p2, p3): Aumentada al 110% (simula cercanía)
|
||||
# 3. Flip horizontal (simétrica a ship_starfield.shp)
|
||||
#
|
||||
# Nuevos Punts (aprox):
|
||||
# p1 (Punta): (-4, -4) -> Lejos, pequeña y apuntando arriba-izq
|
||||
# p2 (Ala Izq): (-3, 11) -> Cerca, lado interior
|
||||
# p4 (Base Cnt): (3, 5) -> Centro base
|
||||
# p3 (Ala Dcha): (11, 2) -> Cerca, lado exterior (más grande)
|
||||
|
||||
#polyline: -4,-4 -3,11 3,5 11,2 -4,-4
|
||||
polyline: -4,-4 -3,11 11,2 -4,-4
|
||||
|
||||
# Circulito central (octàgon r=2.5)
|
||||
# Distintiu visual del jugador 2
|
||||
# Sin perspectiva (está en el centro de la nave)
|
||||
polyline: 0,-2.5 1.77,-1.77 2.5,0 1.77,1.77 0,2.5 -1.77,1.77 -2.5,0 -1.77,-1.77 0,-2.5
|
||||
@@ -1,21 +0,0 @@
|
||||
# ship_perspective.shp - Nave con perspectiva pre-calculada
|
||||
# Posición optimizada: "8 del reloj" (Abajo-Izquierda)
|
||||
# Dirección: Volando hacia el fondo (centro pantalla)
|
||||
|
||||
name: ship_perspective
|
||||
scale: 1.0
|
||||
center: 0, 0
|
||||
|
||||
# TRANSFORMACIÓN APLICADA:
|
||||
# 1. Rotación +45° (apuntando al centro desde abajo-izq)
|
||||
# 2. Proyección de perspectiva:
|
||||
# - Punta (p1): Reducida al 60% (simula lejanía)
|
||||
# - Base (p2, p3): Aumentada al 110% (simula cercanía)
|
||||
#
|
||||
# Nuevos Puntos (aprox):
|
||||
# p1 (Punta): (4, -4) -> Lejos, pequeña y apuntando arriba-dcha
|
||||
# p2 (Ala Dcha): (3, 11) -> Cerca, lado interior
|
||||
# p4 (Base Cnt): (-3, 5) -> Centro base
|
||||
# p3 (Ala Izq): (-11, 2) -> Cerca, lado exterior (más grande)
|
||||
|
||||
polyline: 4,-4 3,11 -3,5 -11,2 4,-4
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+159
-144
@@ -1,168 +1,183 @@
|
||||
# stages.yaml - Configuració de les 10 etapes d'Orni Attack
|
||||
# © 2025 Orni Attack
|
||||
# stages.yaml - Configuració de les fases d'Orni Attack
|
||||
# © 2026 JailDesigner
|
||||
#
|
||||
# Format basat en onades (waves). Cada wave:
|
||||
# - spawn: list d'enemics a generar, en ordre.
|
||||
# - spawn_interval: segons entre spawns interns (default 0 = simultanis).
|
||||
# - next: condició per avançar a la wave següent.
|
||||
# - "all_dead" / "end" → quan tots els enemics de l'arena han mort.
|
||||
# - { timeout: T } → quan han passat T segons des de l'inici de la wave.
|
||||
# - { all_dead: true, timeout: T } → el que arribe abans (amuntegament si vas lent).
|
||||
#
|
||||
# Tipus d'enemic: pentagon, square (alias: cuadrado), pinwheel (alias: molinillo), star, orb.
|
||||
|
||||
metadata:
|
||||
version: "1.0"
|
||||
version: "2.0"
|
||||
total_stages: 10
|
||||
description: "Progressive difficulty curve from novice to expert"
|
||||
description: "Wave-based progression"
|
||||
|
||||
stages:
|
||||
# STAGE 1: Tutorial - Only pentagons, slow speed
|
||||
# STAGE 1 — Tutorial: contacte amb pentagons i un cuadrado.
|
||||
# (Test: també hi ha un orb a la primera onada per provar el contra-atac.)
|
||||
- stage_id: 1
|
||||
total_enemies: 5
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 2.0
|
||||
spawn_interval: 3.0
|
||||
enemy_distribution:
|
||||
pentagon: 100
|
||||
quadrat: 0
|
||||
molinillo: 0
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 0.7
|
||||
rotation_multiplier: 0.8
|
||||
tracking_strength: 0.0
|
||||
multipliers: { velocity: 0.85, rotation: 0.9, tracking: 0.3 }
|
||||
waves:
|
||||
- spawn: [pentagon, pentagon, orb]
|
||||
spawn_interval: 0.6
|
||||
next: all_dead
|
||||
- spawn: [pentagon, pentagon, square]
|
||||
spawn_interval: 0.5
|
||||
next: all_dead
|
||||
- spawn: [pentagon, pentagon, square, square]
|
||||
spawn_interval: 0.4
|
||||
next: end
|
||||
|
||||
# STAGE 2: Introduction to tracking enemies
|
||||
# STAGE 2 — Apareixen molinillos.
|
||||
- stage_id: 2
|
||||
total_enemies: 7
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 1.5
|
||||
spawn_interval: 2.5
|
||||
enemy_distribution:
|
||||
pentagon: 70
|
||||
quadrat: 30
|
||||
molinillo: 0
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 0.85
|
||||
rotation_multiplier: 0.9
|
||||
tracking_strength: 0.3
|
||||
multipliers: { velocity: 0.95, rotation: 1.0, tracking: 0.4 }
|
||||
waves:
|
||||
- spawn: [pentagon, pentagon, pentagon]
|
||||
spawn_interval: 0.5
|
||||
next: all_dead
|
||||
- spawn: [pinwheel]
|
||||
next: all_dead
|
||||
- spawn: [pentagon, square, pinwheel]
|
||||
spawn_interval: 0.6
|
||||
next: all_dead
|
||||
- spawn: [pinwheel, pinwheel, pentagon]
|
||||
spawn_interval: 0.5
|
||||
next: end
|
||||
|
||||
# STAGE 3: All enemy types, normal speed
|
||||
# STAGE 3 — Primer orb (HP=10).
|
||||
- stage_id: 3
|
||||
total_enemies: 10
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 1.0
|
||||
spawn_interval: 2.0
|
||||
enemy_distribution:
|
||||
pentagon: 50
|
||||
quadrat: 30
|
||||
molinillo: 20
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.0
|
||||
rotation_multiplier: 1.0
|
||||
tracking_strength: 0.5
|
||||
multipliers: { velocity: 1.0, rotation: 1.0, tracking: 0.5 }
|
||||
waves:
|
||||
- spawn: [pentagon, pentagon, square]
|
||||
spawn_interval: 0.4
|
||||
next: all_dead
|
||||
- spawn: [orb]
|
||||
next: { all_dead: true, timeout: 12.0 }
|
||||
- spawn: [pinwheel, pinwheel]
|
||||
spawn_interval: 0.5
|
||||
next: all_dead
|
||||
- spawn: [pentagon, square, pinwheel, pinwheel]
|
||||
spawn_interval: 0.4
|
||||
next: end
|
||||
|
||||
# STAGE 4: Increased count, faster enemies
|
||||
# STAGE 4 — Pressió creixent: timeouts curts que poden encavalcar onades.
|
||||
- stage_id: 4
|
||||
total_enemies: 12
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 0.8
|
||||
spawn_interval: 1.8
|
||||
enemy_distribution:
|
||||
pentagon: 40
|
||||
quadrat: 35
|
||||
molinillo: 25
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.1
|
||||
rotation_multiplier: 1.15
|
||||
tracking_strength: 0.6
|
||||
multipliers: { velocity: 1.05, rotation: 1.1, tracking: 0.6 }
|
||||
waves:
|
||||
- spawn: [pentagon, pentagon, pentagon]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 5.0 }
|
||||
- spawn: [square, square]
|
||||
spawn_interval: 0.4
|
||||
next: { all_dead: true, timeout: 6.0 }
|
||||
- spawn: [pinwheel, pinwheel, pinwheel]
|
||||
spawn_interval: 0.4
|
||||
next: all_dead
|
||||
- spawn: [orb, pentagon, pentagon]
|
||||
spawn_interval: 0.5
|
||||
next: end
|
||||
|
||||
# STAGE 5: Maximum count reached
|
||||
# STAGE 5 — Apareix la star (zigzag clon del pentagon).
|
||||
- stage_id: 5
|
||||
total_enemies: 15
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 0.5
|
||||
spawn_interval: 1.5
|
||||
enemy_distribution:
|
||||
pentagon: 35
|
||||
quadrat: 35
|
||||
molinillo: 30
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.2
|
||||
rotation_multiplier: 1.25
|
||||
tracking_strength: 0.7
|
||||
multipliers: { velocity: 1.1, rotation: 1.2, tracking: 0.7 }
|
||||
waves:
|
||||
- spawn: [star, star]
|
||||
spawn_interval: 0.4
|
||||
next: all_dead
|
||||
- spawn: [pentagon, square, star]
|
||||
spawn_interval: 0.4
|
||||
next: { all_dead: true, timeout: 6.0 }
|
||||
- spawn: [pinwheel, pinwheel, star, star]
|
||||
spawn_interval: 0.4
|
||||
next: all_dead
|
||||
- spawn: [orb, square, square]
|
||||
spawn_interval: 0.5
|
||||
next: end
|
||||
|
||||
# STAGE 6: Molinillo becomes dominant
|
||||
# STAGE 6 — Densitat alta, mix amb timeouts agressius.
|
||||
- stage_id: 6
|
||||
total_enemies: 15
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 0.3
|
||||
spawn_interval: 1.3
|
||||
enemy_distribution:
|
||||
pentagon: 30
|
||||
quadrat: 30
|
||||
molinillo: 40
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.3
|
||||
rotation_multiplier: 1.4
|
||||
tracking_strength: 0.8
|
||||
multipliers: { velocity: 1.15, rotation: 1.25, tracking: 0.8 }
|
||||
waves:
|
||||
- spawn: [pentagon, pinwheel, pentagon, pinwheel]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 5.0 }
|
||||
- spawn: [square, square, star]
|
||||
spawn_interval: 0.4
|
||||
next: { all_dead: true, timeout: 5.0 }
|
||||
- spawn: [pinwheel, pinwheel, pinwheel]
|
||||
spawn_interval: 0.3
|
||||
next: all_dead
|
||||
- spawn: [orb, pinwheel, pinwheel]
|
||||
spawn_interval: 0.4
|
||||
next: end
|
||||
|
||||
# STAGE 7: High intensity, fast spawns
|
||||
# STAGE 7 — Tiradors i agressivitat.
|
||||
- stage_id: 7
|
||||
total_enemies: 15
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 0.2
|
||||
spawn_interval: 1.0
|
||||
enemy_distribution:
|
||||
pentagon: 25
|
||||
quadrat: 30
|
||||
molinillo: 45
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.4
|
||||
rotation_multiplier: 1.5
|
||||
tracking_strength: 0.9
|
||||
multipliers: { velocity: 1.25, rotation: 1.35, tracking: 0.9 }
|
||||
waves:
|
||||
- spawn: [square, square, square]
|
||||
spawn_interval: 0.5
|
||||
next: { all_dead: true, timeout: 6.0 }
|
||||
- spawn: [pinwheel, pinwheel, pentagon, pentagon]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 5.0 }
|
||||
- spawn: [star, star, star]
|
||||
spawn_interval: 0.4
|
||||
next: all_dead
|
||||
- spawn: [orb, pinwheel, pinwheel, square]
|
||||
spawn_interval: 0.5
|
||||
next: end
|
||||
|
||||
# STAGE 8: Expert level, 50% molinillos
|
||||
# STAGE 8 — Pressió constant.
|
||||
- stage_id: 8
|
||||
total_enemies: 15
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 0.1
|
||||
spawn_interval: 0.8
|
||||
enemy_distribution:
|
||||
pentagon: 20
|
||||
quadrat: 30
|
||||
molinillo: 50
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.5
|
||||
rotation_multiplier: 1.6
|
||||
tracking_strength: 1.0
|
||||
multipliers: { velocity: 1.35, rotation: 1.45, tracking: 1.0 }
|
||||
waves:
|
||||
- spawn: [pinwheel, pinwheel, pinwheel]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 4.0 }
|
||||
- spawn: [square, square, star, star]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 5.0 }
|
||||
- spawn: [orb]
|
||||
next: { all_dead: true, timeout: 8.0 }
|
||||
- spawn: [pinwheel, pinwheel, square, star, pentagon]
|
||||
spawn_interval: 0.3
|
||||
next: end
|
||||
|
||||
# STAGE 9: Near-maximum difficulty
|
||||
# STAGE 9 — Quasi-final.
|
||||
- stage_id: 9
|
||||
total_enemies: 15
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 0.0
|
||||
spawn_interval: 0.6
|
||||
enemy_distribution:
|
||||
pentagon: 15
|
||||
quadrat: 25
|
||||
molinillo: 60
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.6
|
||||
rotation_multiplier: 1.7
|
||||
tracking_strength: 1.1
|
||||
multipliers: { velocity: 1.5, rotation: 1.6, tracking: 1.1 }
|
||||
waves:
|
||||
- spawn: [pinwheel, pinwheel, star, star]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 4.0 }
|
||||
- spawn: [orb, square, square]
|
||||
spawn_interval: 0.4
|
||||
next: { all_dead: true, timeout: 8.0 }
|
||||
- spawn: [pinwheel, pinwheel, pinwheel, pinwheel]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 5.0 }
|
||||
- spawn: [orb, pinwheel, pinwheel, square, star]
|
||||
spawn_interval: 0.4
|
||||
next: end
|
||||
|
||||
# STAGE 10: Final challenge, 70% molinillos
|
||||
# STAGE 10 — Repte final.
|
||||
- stage_id: 10
|
||||
total_enemies: 15
|
||||
spawn_config:
|
||||
mode: "progressive"
|
||||
initial_delay: 0.0
|
||||
spawn_interval: 0.5
|
||||
enemy_distribution:
|
||||
pentagon: 10
|
||||
quadrat: 20
|
||||
molinillo: 70
|
||||
difficulty_multipliers:
|
||||
speed_multiplier: 1.8
|
||||
rotation_multiplier: 2.0
|
||||
tracking_strength: 1.2
|
||||
multipliers: { velocity: 1.7, rotation: 1.8, tracking: 1.2 }
|
||||
waves:
|
||||
- spawn: [pinwheel, pinwheel, pinwheel, pinwheel]
|
||||
spawn_interval: 0.25
|
||||
next: { all_dead: true, timeout: 4.0 }
|
||||
- spawn: [orb, square, star]
|
||||
spawn_interval: 0.4
|
||||
next: { all_dead: true, timeout: 6.0 }
|
||||
- spawn: [pinwheel, pinwheel, star, star, square]
|
||||
spawn_interval: 0.3
|
||||
next: { all_dead: true, timeout: 5.0 }
|
||||
- spawn: [orb, orb, pinwheel, pinwheel, star]
|
||||
spawn_interval: 0.4
|
||||
next: end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-20
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.org.libsdl.SDL3</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.2.26</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3.2.26</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
Binary file not shown.
-4454
File diff suppressed because it is too large
Load Diff
-106
@@ -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)
|
||||
-57
@@ -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()
|
||||
-90
@@ -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.26
|
||||
*
|
||||
* 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_ */
|
||||
-662
@@ -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(__MINGW32__) || (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_ */
|
||||
-546
@@ -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_ */
|
||||
-664
@@ -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_ */
|
||||
-2203
File diff suppressed because it is too large
Load Diff
-486
@@ -1,486 +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: BeginCode */
|
||||
|
||||
/**
|
||||
* # CategoryBeginCode
|
||||
*
|
||||
* `SDL_begin_code.h` sets things up for C dynamic library function
|
||||
* definitions, static inlined functions, and structures aligned at 4-byte
|
||||
* alignment. If you don't like ugly C preprocessor code, don't look at this
|
||||
* file. :)
|
||||
*
|
||||
* SDL's headers use this; applications generally should not include this
|
||||
* header directly.
|
||||
*/
|
||||
|
||||
/* This shouldn't be nested -- included it around code only. */
|
||||
#ifdef SDL_begin_code_h
|
||||
#error Nested inclusion of SDL_begin_code.h
|
||||
#endif
|
||||
#define SDL_begin_code_h
|
||||
|
||||
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
|
||||
/**
|
||||
* A macro to tag a symbol as deprecated.
|
||||
*
|
||||
* A function is marked deprecated by adding this macro to its declaration:
|
||||
*
|
||||
* ```c
|
||||
* extern SDL_DEPRECATED int ThisFunctionWasABadIdea(void);
|
||||
* ```
|
||||
*
|
||||
* Compilers with deprecation support can give a warning when a deprecated
|
||||
* function is used. This symbol may be used in SDL's headers, but apps are
|
||||
* welcome to use it for their own interfaces as well.
|
||||
*
|
||||
* SDL, on occasion, might deprecate a function for various reasons. However,
|
||||
* SDL never removes symbols before major versions, so deprecated interfaces
|
||||
* in SDL3 will remain available until SDL4, where it would be expected an app
|
||||
* would have to take steps to migrate anyhow.
|
||||
*
|
||||
* On compilers without a deprecation mechanism, this is defined to nothing,
|
||||
* and using a deprecated function will not generate a warning.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
/**
|
||||
* A macro to tag a symbol as a public API.
|
||||
*
|
||||
* SDL uses this macro for all its public functions. On some targets, it is
|
||||
* used to signal to the compiler that this function needs to be exported from
|
||||
* a shared library, but it might have other side effects.
|
||||
*
|
||||
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||
* welcome to use it for their own interfaces as well.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_DECLSPEC __attribute__ ((visibility("default")))
|
||||
|
||||
/**
|
||||
* A macro to set a function's calling conventions.
|
||||
*
|
||||
* SDL uses this macro for all its public functions, and any callbacks it
|
||||
* defines. This macro guarantees that calling conventions match between SDL
|
||||
* and the app, even if the two were built with different compilers or
|
||||
* optimization settings.
|
||||
*
|
||||
* When writing a callback function, it is very important for it to be
|
||||
* correctly tagged with SDLCALL, as mismatched calling conventions can cause
|
||||
* strange behaviors and can be difficult to diagnose. Plus, on many
|
||||
* platforms, SDLCALL is defined to nothing, so compilers won't be able to
|
||||
* warn that the tag is missing.
|
||||
*
|
||||
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||
* welcome to use it for their own interfaces as well.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDLCALL __cdecl
|
||||
|
||||
/**
|
||||
* A macro to request a function be inlined.
|
||||
*
|
||||
* This is a hint to the compiler to inline a function. The compiler is free
|
||||
* to ignore this request. On compilers without inline support, this is
|
||||
* defined to nothing.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_INLINE __inline
|
||||
|
||||
/**
|
||||
* A macro to demand a function be inlined.
|
||||
*
|
||||
* This is a command to the compiler to inline a function. SDL uses this macro
|
||||
* in its public headers for a handful of simple functions. On compilers
|
||||
* without forceinline support, this is defined to `static SDL_INLINE`, which
|
||||
* is often good enough.
|
||||
*
|
||||
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||
* welcome to use it for their own interfaces as well.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_FORCE_INLINE __forceinline
|
||||
|
||||
/**
|
||||
* A macro to tag a function as never-returning.
|
||||
*
|
||||
* This is a hint to the compiler that a function does not return. An example
|
||||
* of a function like this is the C runtime's exit() function.
|
||||
*
|
||||
* This hint can lead to code optimizations, and help analyzers understand
|
||||
* code flow better. On compilers without noreturn support, this is defined to
|
||||
* nothing.
|
||||
*
|
||||
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||
* welcome to use it for their own interfaces as well.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_NORETURN __attribute__((noreturn))
|
||||
|
||||
/**
|
||||
* A macro to tag a function as never-returning (for analysis purposes).
|
||||
*
|
||||
* This is almost identical to SDL_NORETURN, except functions marked with this
|
||||
* _can_ actually return. The difference is that this isn't used for code
|
||||
* generation, but rather static analyzers use this information to assume
|
||||
* truths about program state and available code paths. Specifically, this tag
|
||||
* is useful for writing an assertion mechanism. Indeed, SDL_assert uses this
|
||||
* tag behind the scenes. Generally, apps that don't understand the specific
|
||||
* use-case for this tag should avoid using it directly.
|
||||
*
|
||||
* On compilers without analyzer_noreturn support, this is defined to nothing.
|
||||
*
|
||||
* This symbol is used in SDL's headers, but apps and other libraries are
|
||||
* welcome to use it for their own interfaces as well.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||
|
||||
|
||||
/**
|
||||
* A macro to signal that a case statement without a `break` is intentional.
|
||||
*
|
||||
* C compilers have gotten more aggressive about warning when a switch's
|
||||
* `case` block does not end with a `break` or other flow control statement,
|
||||
* flowing into the next case's code, as this is a common accident that leads
|
||||
* to strange bugs. But sometimes falling through to the next case is the
|
||||
* correct and desired behavior. This symbol lets an app communicate this
|
||||
* intention to the compiler, so it doesn't generate a warning.
|
||||
*
|
||||
* It is used like this:
|
||||
*
|
||||
* ```c
|
||||
* switch (x) {
|
||||
* case 1:
|
||||
* DoSomethingOnlyForOne();
|
||||
* SDL_FALLTHROUGH; // tell the compiler this was intentional.
|
||||
* case 2:
|
||||
* DoSomethingForOneAndTwo();
|
||||
* break;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_FALLTHROUGH [[fallthrough]]
|
||||
|
||||
/**
|
||||
* A macro to tag a function's return value as critical.
|
||||
*
|
||||
* This is a hint to the compiler that a function's return value should not be
|
||||
* ignored.
|
||||
*
|
||||
* If an NODISCARD function's return value is thrown away (the function is
|
||||
* called as if it returns `void`), the compiler will issue a warning.
|
||||
*
|
||||
* While it's generally good practice to check return values for errors, often
|
||||
* times legitimate programs do not for good reasons. Be careful about what
|
||||
* functions are tagged as NODISCARD. It operates best when used on a function
|
||||
* that's failure is surprising and catastrophic; a good example would be a
|
||||
* program that checks the return values of all its file write function calls
|
||||
* but not the call to close the file, which it assumes incorrectly never
|
||||
* fails.
|
||||
*
|
||||
* Function callers that want to throw away a NODISCARD return value can call
|
||||
* the function with a `(void)` cast, which informs the compiler the act is
|
||||
* intentional.
|
||||
*
|
||||
* On compilers without nodiscard support, this is defined to nothing.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_NODISCARD [[nodiscard]]
|
||||
|
||||
/**
|
||||
* A macro to tag a function as an allocator.
|
||||
*
|
||||
* This is a hint to the compiler that a function is an allocator, like
|
||||
* malloc(), with certain rules. A description of how GCC treats this hint is
|
||||
* here:
|
||||
*
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
|
||||
*
|
||||
* On compilers without allocator tag support, this is defined to nothing.
|
||||
*
|
||||
* Most apps don't need to, and should not, use this directly.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
|
||||
|
||||
/**
|
||||
* A macro to tag a function as returning a certain allocation.
|
||||
*
|
||||
* This is a hint to the compiler that a function allocates and returns a
|
||||
* specific amount of memory based on one of its arguments. For example, the C
|
||||
* runtime's malloc() function could use this macro with an argument of 1
|
||||
* (first argument to malloc is the size of the allocation).
|
||||
*
|
||||
* On compilers without alloc_size support, this is defined to nothing.
|
||||
*
|
||||
* Most apps don't need to, and should not, use this directly.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
|
||||
|
||||
/**
|
||||
* A macro to tag a pointer variable, to help with pointer aliasing.
|
||||
*
|
||||
* A good explanation of the restrict keyword is here:
|
||||
*
|
||||
* https://en.wikipedia.org/wiki/Restrict
|
||||
*
|
||||
* On compilers without restrict support, this is defined to nothing.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_RESTRICT __restrict__
|
||||
|
||||
/**
|
||||
* Check if the compiler supports a given builtin functionality.
|
||||
*
|
||||
* This allows preprocessor checks for things that otherwise might fail to
|
||||
* compile.
|
||||
*
|
||||
* Supported by virtually all clang versions and more-recent GCCs. Use this
|
||||
* instead of checking the clang version if possible.
|
||||
*
|
||||
* On compilers without has_builtin support, this is defined to 0 (always
|
||||
* false).
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_HAS_BUILTIN(x) __has_builtin(x)
|
||||
|
||||
/* end of wiki documentation section. */
|
||||
#endif
|
||||
|
||||
#ifndef SDL_HAS_BUILTIN
|
||||
#ifdef __has_builtin
|
||||
#define SDL_HAS_BUILTIN(x) __has_builtin(x)
|
||||
#else
|
||||
#define SDL_HAS_BUILTIN(x) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SDL_DEPRECATED
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
|
||||
# define SDL_DEPRECATED __attribute__((deprecated))
|
||||
# elif defined(_MSC_VER)
|
||||
# define SDL_DEPRECATED __declspec(deprecated)
|
||||
# else
|
||||
# define SDL_DEPRECATED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SDL_UNUSED
|
||||
# ifdef __GNUC__
|
||||
# define SDL_UNUSED __attribute__((unused))
|
||||
# else
|
||||
# define SDL_UNUSED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some compilers use a special export keyword */
|
||||
#ifndef SDL_DECLSPEC
|
||||
# if defined(SDL_PLATFORM_WINDOWS)
|
||||
# ifdef DLL_EXPORT
|
||||
# define SDL_DECLSPEC __declspec(dllexport)
|
||||
# else
|
||||
# define SDL_DECLSPEC
|
||||
# endif
|
||||
# else
|
||||
# if defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define SDL_DECLSPEC __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define SDL_DECLSPEC
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* By default SDL uses the C calling convention */
|
||||
#ifndef SDLCALL
|
||||
#if defined(SDL_PLATFORM_WINDOWS) && !defined(__GNUC__)
|
||||
#define SDLCALL __cdecl
|
||||
#else
|
||||
#define SDLCALL
|
||||
#endif
|
||||
#endif /* SDLCALL */
|
||||
|
||||
/* Force structure packing at 4 byte alignment.
|
||||
This is necessary if the header is included in code which has structure
|
||||
packing set to an alternate value, say for loading structures from disk.
|
||||
The packing is reset to the previous value in SDL_close_code.h
|
||||
*/
|
||||
#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4103)
|
||||
#endif
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wpragma-pack"
|
||||
#endif
|
||||
#ifdef __BORLANDC__
|
||||
#pragma nopackwarning
|
||||
#endif
|
||||
#ifdef _WIN64
|
||||
/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
|
||||
#pragma pack(push,8)
|
||||
#else
|
||||
#pragma pack(push,4)
|
||||
#endif
|
||||
#endif /* Compiler needs structure packing set */
|
||||
|
||||
#ifndef SDL_INLINE
|
||||
#ifdef __GNUC__
|
||||
#define SDL_INLINE __inline__
|
||||
#elif defined(_MSC_VER) || defined(__BORLANDC__) || \
|
||||
defined(__DMC__) || defined(__SC__) || \
|
||||
defined(__WATCOMC__) || defined(__LCC__) || \
|
||||
defined(__DECC) || defined(__CC_ARM)
|
||||
#define SDL_INLINE __inline
|
||||
#ifndef __inline__
|
||||
#define __inline__ __inline
|
||||
#endif
|
||||
#else
|
||||
#define SDL_INLINE inline
|
||||
#ifndef __inline__
|
||||
#define __inline__ inline
|
||||
#endif
|
||||
#endif
|
||||
#endif /* SDL_INLINE not defined */
|
||||
|
||||
#ifndef SDL_FORCE_INLINE
|
||||
#ifdef _MSC_VER
|
||||
#define SDL_FORCE_INLINE __forceinline
|
||||
#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
|
||||
#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
|
||||
#else
|
||||
#define SDL_FORCE_INLINE static SDL_INLINE
|
||||
#endif
|
||||
#endif /* SDL_FORCE_INLINE not defined */
|
||||
|
||||
#ifndef SDL_NORETURN
|
||||
#ifdef __GNUC__
|
||||
#define SDL_NORETURN __attribute__((noreturn))
|
||||
#elif defined(_MSC_VER)
|
||||
#define SDL_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
#define SDL_NORETURN
|
||||
#endif
|
||||
#endif /* SDL_NORETURN not defined */
|
||||
|
||||
#ifdef __clang__
|
||||
#if __has_feature(attribute_analyzer_noreturn)
|
||||
#define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SDL_ANALYZER_NORETURN
|
||||
#define SDL_ANALYZER_NORETURN
|
||||
#endif
|
||||
|
||||
/* Apparently this is needed by several Windows compilers */
|
||||
#ifndef __MACH__
|
||||
#ifndef NULL
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
#else
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
#endif /* NULL */
|
||||
#endif /* ! macOS - breaks precompiled headers */
|
||||
|
||||
#ifndef SDL_FALLTHROUGH
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L)
|
||||
#define SDL_FALLTHROUGH [[fallthrough]]
|
||||
#else
|
||||
#if defined(__has_attribute) && !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
|
||||
#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__)
|
||||
#else
|
||||
#define SDL_HAS_FALLTHROUGH 0
|
||||
#endif /* __has_attribute */
|
||||
#if SDL_HAS_FALLTHROUGH && \
|
||||
((defined(__GNUC__) && __GNUC__ >= 7) || \
|
||||
(defined(__clang_major__) && __clang_major__ >= 10))
|
||||
#define SDL_FALLTHROUGH __attribute__((__fallthrough__))
|
||||
#else
|
||||
#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */
|
||||
#endif /* SDL_HAS_FALLTHROUGH */
|
||||
#undef SDL_HAS_FALLTHROUGH
|
||||
#endif /* C++17 or C2x */
|
||||
#endif /* SDL_FALLTHROUGH not defined */
|
||||
|
||||
#ifndef SDL_NODISCARD
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
|
||||
#define SDL_NODISCARD [[nodiscard]]
|
||||
#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
|
||||
#define SDL_NODISCARD __attribute__((warn_unused_result))
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
|
||||
#define SDL_NODISCARD _Check_return_
|
||||
#else
|
||||
#define SDL_NODISCARD
|
||||
#endif /* C++17 or C23 */
|
||||
#endif /* SDL_NODISCARD not defined */
|
||||
|
||||
#ifndef SDL_MALLOC
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 3)
|
||||
#define SDL_MALLOC __attribute__((malloc))
|
||||
/** FIXME
|
||||
#elif defined(_MSC_VER)
|
||||
#define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
|
||||
**/
|
||||
#else
|
||||
#define SDL_MALLOC
|
||||
#endif
|
||||
#endif /* SDL_MALLOC not defined */
|
||||
|
||||
#ifndef SDL_ALLOC_SIZE
|
||||
#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||
#define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
|
||||
#elif defined(_MSC_VER)
|
||||
#define SDL_ALLOC_SIZE(p)
|
||||
#else
|
||||
#define SDL_ALLOC_SIZE(p)
|
||||
#endif
|
||||
#endif /* SDL_ALLOC_SIZE not defined */
|
||||
|
||||
#ifndef SDL_ALLOC_SIZE2
|
||||
#if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||
#define SDL_ALLOC_SIZE2(p1, p2) __attribute__((alloc_size(p1, p2)))
|
||||
#elif defined(_MSC_VER)
|
||||
#define SDL_ALLOC_SIZE2(p1, p2)
|
||||
#else
|
||||
#define SDL_ALLOC_SIZE2(p1, p2)
|
||||
#endif
|
||||
#endif /* SDL_ALLOC_SIZE2 not defined */
|
||||
-147
@@ -1,147 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryBits
|
||||
*
|
||||
* Functions for fiddling with bits and bitmasks.
|
||||
*/
|
||||
|
||||
#ifndef SDL_bits_h_
|
||||
#define SDL_bits_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && defined(__386__)
|
||||
extern __inline int _SDL_bsr_watcom(Uint32);
|
||||
#pragma aux _SDL_bsr_watcom = \
|
||||
"bsr eax, eax" \
|
||||
parm [eax] nomemory \
|
||||
value [eax] \
|
||||
modify exact [eax] nomemory;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the index of the most significant (set) bit in a 32-bit number.
|
||||
*
|
||||
* Result is undefined when called with 0. This operation can also be stated
|
||||
* as "count leading zeroes" and "log base 2".
|
||||
*
|
||||
* Note that this is a forced-inline function in a header, and not a public
|
||||
* API function available in the SDL library (which is to say, the code is
|
||||
* embedded in the calling program and the linker and dynamic loader will not
|
||||
* be able to find this function inside SDL itself).
|
||||
*
|
||||
* \param x the 32-bit value to examine.
|
||||
* \returns the index of the most significant bit, or -1 if the value is 0.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x)
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
/* Count Leading Zeroes builtin in GCC.
|
||||
* http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html
|
||||
*/
|
||||
if (x == 0) {
|
||||
return -1;
|
||||
}
|
||||
return 31 - __builtin_clz(x);
|
||||
#elif defined(__WATCOMC__) && defined(__386__)
|
||||
if (x == 0) {
|
||||
return -1;
|
||||
}
|
||||
return _SDL_bsr_watcom(x);
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
unsigned long index;
|
||||
if (_BitScanReverse(&index, x)) {
|
||||
return (int)index;
|
||||
}
|
||||
return -1;
|
||||
#else
|
||||
/* Based off of Bit Twiddling Hacks by Sean Eron Anderson
|
||||
* <seander@cs.stanford.edu>, released in the public domain.
|
||||
* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
|
||||
*/
|
||||
const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
|
||||
const int S[] = {1, 2, 4, 8, 16};
|
||||
|
||||
int msbIndex = 0;
|
||||
int i;
|
||||
|
||||
if (x == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 4; i >= 0; i--)
|
||||
{
|
||||
if (x & b[i])
|
||||
{
|
||||
x >>= S[i];
|
||||
msbIndex |= S[i];
|
||||
}
|
||||
}
|
||||
|
||||
return msbIndex;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a unsigned 32-bit value has exactly one bit set.
|
||||
*
|
||||
* If there are no bits set (`x` is zero), or more than one bit set, this
|
||||
* returns false. If any one bit is exclusively set, this returns true.
|
||||
*
|
||||
* Note that this is a forced-inline function in a header, and not a public
|
||||
* API function available in the SDL library (which is to say, the code is
|
||||
* embedded in the calling program and the linker and dynamic loader will not
|
||||
* be able to find this function inside SDL itself).
|
||||
*
|
||||
* \param x the 32-bit value to examine.
|
||||
* \returns true if exactly one bit is set in `x`, false otherwise.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE bool SDL_HasExactlyOneBitSet32(Uint32 x)
|
||||
{
|
||||
if (x && !(x & (x - 1))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_bits_h_ */
|
||||
-202
@@ -1,202 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryBlendmode
|
||||
*
|
||||
* Blend modes decide how two colors will mix together. There are both
|
||||
* standard modes for basic needs and a means to create custom modes,
|
||||
* dictating what sort of math to do on what color components.
|
||||
*/
|
||||
|
||||
#ifndef SDL_blendmode_h_
|
||||
#define SDL_blendmode_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A set of blend modes used in drawing operations.
|
||||
*
|
||||
* These predefined blend modes are supported everywhere.
|
||||
*
|
||||
* Additional values may be obtained from SDL_ComposeCustomBlendMode.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_ComposeCustomBlendMode
|
||||
*/
|
||||
typedef Uint32 SDL_BlendMode;
|
||||
|
||||
#define SDL_BLENDMODE_NONE 0x00000000u /**< no blending: dstRGBA = srcRGBA */
|
||||
#define SDL_BLENDMODE_BLEND 0x00000001u /**< alpha blending: dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)), dstA = srcA + (dstA * (1-srcA)) */
|
||||
#define SDL_BLENDMODE_BLEND_PREMULTIPLIED 0x00000010u /**< pre-multiplied alpha blending: dstRGBA = srcRGBA + (dstRGBA * (1-srcA)) */
|
||||
#define SDL_BLENDMODE_ADD 0x00000002u /**< additive blending: dstRGB = (srcRGB * srcA) + dstRGB, dstA = dstA */
|
||||
#define SDL_BLENDMODE_ADD_PREMULTIPLIED 0x00000020u /**< pre-multiplied additive blending: dstRGB = srcRGB + dstRGB, dstA = dstA */
|
||||
#define SDL_BLENDMODE_MOD 0x00000004u /**< color modulate: dstRGB = srcRGB * dstRGB, dstA = dstA */
|
||||
#define SDL_BLENDMODE_MUL 0x00000008u /**< color multiply: dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)), dstA = dstA */
|
||||
#define SDL_BLENDMODE_INVALID 0x7FFFFFFFu
|
||||
|
||||
/**
|
||||
* The blend operation used when combining source and destination pixel
|
||||
* components.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef enum SDL_BlendOperation
|
||||
{
|
||||
SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */
|
||||
SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< src - dst : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||
SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< dst - src : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||
SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||
SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D, OpenGL, OpenGLES, and Vulkan */
|
||||
} SDL_BlendOperation;
|
||||
|
||||
/**
|
||||
* The normalized factor used to multiply pixel components.
|
||||
*
|
||||
* The blend factors are multiplied with the pixels from a drawing operation
|
||||
* (src) and the pixels from the render target (dst) before the blend
|
||||
* operation. The comma-separated factors listed above are always applied in
|
||||
* the component order red, green, blue, and alpha.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef enum SDL_BlendFactor
|
||||
{
|
||||
SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */
|
||||
SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */
|
||||
SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */
|
||||
SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */
|
||||
SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */
|
||||
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */
|
||||
SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */
|
||||
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */
|
||||
SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */
|
||||
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */
|
||||
} SDL_BlendFactor;
|
||||
|
||||
/**
|
||||
* Compose a custom blend mode for renderers.
|
||||
*
|
||||
* The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept
|
||||
* the SDL_BlendMode returned by this function if the renderer supports it.
|
||||
*
|
||||
* A blend mode controls how the pixels from a drawing operation (source) get
|
||||
* combined with the pixels from the render target (destination). First, the
|
||||
* components of the source and destination pixels get multiplied with their
|
||||
* blend factors. Then, the blend operation takes the two products and
|
||||
* calculates the result that will get stored in the render target.
|
||||
*
|
||||
* Expressed in pseudocode, it would look like this:
|
||||
*
|
||||
* ```c
|
||||
* dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor);
|
||||
* dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor);
|
||||
* ```
|
||||
*
|
||||
* Where the functions `colorOperation(src, dst)` and `alphaOperation(src,
|
||||
* dst)` can return one of the following:
|
||||
*
|
||||
* - `src + dst`
|
||||
* - `src - dst`
|
||||
* - `dst - src`
|
||||
* - `min(src, dst)`
|
||||
* - `max(src, dst)`
|
||||
*
|
||||
* The red, green, and blue components are always multiplied with the first,
|
||||
* second, and third components of the SDL_BlendFactor, respectively. The
|
||||
* fourth component is not used.
|
||||
*
|
||||
* The alpha component is always multiplied with the fourth component of the
|
||||
* SDL_BlendFactor. The other components are not used in the alpha
|
||||
* calculation.
|
||||
*
|
||||
* Support for these blend modes varies for each renderer. To check if a
|
||||
* specific SDL_BlendMode is supported, create a renderer and pass it to
|
||||
* either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will
|
||||
* return with an error if the blend mode is not supported.
|
||||
*
|
||||
* This list describes the support of custom blend modes for each renderer.
|
||||
* All renderers support the four blend modes listed in the SDL_BlendMode
|
||||
* enumeration.
|
||||
*
|
||||
* - **direct3d**: Supports all operations with all factors. However, some
|
||||
* factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and
|
||||
* `SDL_BLENDOPERATION_MAXIMUM`.
|
||||
* - **direct3d11**: Same as Direct3D 9.
|
||||
* - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all
|
||||
* factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly here.
|
||||
* - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`,
|
||||
* `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT`
|
||||
* operations with all factors.
|
||||
* - **psp**: No custom blend mode support.
|
||||
* - **software**: No custom blend mode support.
|
||||
*
|
||||
* Some renderers do not provide an alpha component for the default render
|
||||
* target. The `SDL_BLENDFACTOR_DST_ALPHA` and
|
||||
* `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this
|
||||
* case.
|
||||
*
|
||||
* \param srcColorFactor the SDL_BlendFactor applied to the red, green, and
|
||||
* blue components of the source pixels.
|
||||
* \param dstColorFactor the SDL_BlendFactor applied to the red, green, and
|
||||
* blue components of the destination pixels.
|
||||
* \param colorOperation the SDL_BlendOperation used to combine the red,
|
||||
* green, and blue components of the source and
|
||||
* destination pixels.
|
||||
* \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of
|
||||
* the source pixels.
|
||||
* \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of
|
||||
* the destination pixels.
|
||||
* \param alphaOperation the SDL_BlendOperation used to combine the alpha
|
||||
* component of the source and destination pixels.
|
||||
* \returns an SDL_BlendMode that represents the chosen factors and
|
||||
* operations.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SetRenderDrawBlendMode
|
||||
* \sa SDL_GetRenderDrawBlendMode
|
||||
* \sa SDL_SetTextureBlendMode
|
||||
* \sa SDL_GetTextureBlendMode
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor,
|
||||
SDL_BlendFactor dstColorFactor,
|
||||
SDL_BlendOperation colorOperation,
|
||||
SDL_BlendFactor srcAlphaFactor,
|
||||
SDL_BlendFactor dstAlphaFactor,
|
||||
SDL_BlendOperation alphaOperation);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_blendmode_h_ */
|
||||
-519
@@ -1,519 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryCamera
|
||||
*
|
||||
* Video capture for the SDL library.
|
||||
*
|
||||
* This API lets apps read input from video sources, like webcams. Camera
|
||||
* devices can be enumerated, queried, and opened. Once opened, it will
|
||||
* provide SDL_Surface objects as new frames of video come in. These surfaces
|
||||
* can be uploaded to an SDL_Texture or processed as pixels in memory.
|
||||
*
|
||||
* Several platforms will alert the user if an app tries to access a camera,
|
||||
* and some will present a UI asking the user if your application should be
|
||||
* allowed to obtain images at all, which they can deny. A successfully opened
|
||||
* camera will not provide images until permission is granted. Applications,
|
||||
* after opening a camera device, can see if they were granted access by
|
||||
* either polling with the SDL_GetCameraPermissionState() function, or waiting
|
||||
* for an SDL_EVENT_CAMERA_DEVICE_APPROVED or SDL_EVENT_CAMERA_DEVICE_DENIED
|
||||
* event. Platforms that don't have any user approval process will report
|
||||
* approval immediately.
|
||||
*
|
||||
* Note that SDL cameras only provide video as individual frames; they will
|
||||
* not provide full-motion video encoded in a movie file format, although an
|
||||
* app is free to encode the acquired frames into any format it likes. It also
|
||||
* does not provide audio from the camera hardware through this API; not only
|
||||
* do many webcams not have microphones at all, many people--from streamers to
|
||||
* people on Zoom calls--will want to use a separate microphone regardless of
|
||||
* the camera. In any case, recorded audio will be available through SDL's
|
||||
* audio API no matter what hardware provides the microphone.
|
||||
*
|
||||
* ## Camera gotchas
|
||||
*
|
||||
* Consumer-level camera hardware tends to take a little while to warm up,
|
||||
* once the device has been opened. Generally most camera apps have some sort
|
||||
* of UI to take a picture (a button to snap a pic while a preview is showing,
|
||||
* some sort of multi-second countdown for the user to pose, like a photo
|
||||
* booth), which puts control in the users' hands, or they are intended to
|
||||
* stay on for long times (Pokemon Go, etc).
|
||||
*
|
||||
* It's not uncommon that a newly-opened camera will provide a couple of
|
||||
* completely black frames, maybe followed by some under-exposed images. If
|
||||
* taking a single frame automatically, or recording video from a camera's
|
||||
* input without the user initiating it from a preview, it could be wise to
|
||||
* drop the first several frames (if not the first several _seconds_ worth of
|
||||
* frames!) before using images from a camera.
|
||||
*/
|
||||
|
||||
#ifndef SDL_camera_h_
|
||||
#define SDL_camera_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#include <SDL3/SDL_properties.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This is a unique ID for a camera device for the time it is connected to the
|
||||
* system, and is never reused for the lifetime of the application.
|
||||
*
|
||||
* If the device is disconnected and reconnected, it will get a new ID.
|
||||
*
|
||||
* The value 0 is an invalid ID.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameras
|
||||
*/
|
||||
typedef Uint32 SDL_CameraID;
|
||||
|
||||
/**
|
||||
* The opaque structure used to identify an opened SDL camera.
|
||||
*
|
||||
* \since This struct is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef struct SDL_Camera SDL_Camera;
|
||||
|
||||
/**
|
||||
* The details of an output format for a camera device.
|
||||
*
|
||||
* Cameras often support multiple formats; each one will be encapsulated in
|
||||
* this struct.
|
||||
*
|
||||
* \since This struct is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameraSupportedFormats
|
||||
* \sa SDL_GetCameraFormat
|
||||
*/
|
||||
typedef struct SDL_CameraSpec
|
||||
{
|
||||
SDL_PixelFormat format; /**< Frame format */
|
||||
SDL_Colorspace colorspace; /**< Frame colorspace */
|
||||
int width; /**< Frame width */
|
||||
int height; /**< Frame height */
|
||||
int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
int framerate_denominator; /**< Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
} SDL_CameraSpec;
|
||||
|
||||
/**
|
||||
* The position of camera in relation to system device.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameraPosition
|
||||
*/
|
||||
typedef enum SDL_CameraPosition
|
||||
{
|
||||
SDL_CAMERA_POSITION_UNKNOWN,
|
||||
SDL_CAMERA_POSITION_FRONT_FACING,
|
||||
SDL_CAMERA_POSITION_BACK_FACING
|
||||
} SDL_CameraPosition;
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to get the number of built-in camera drivers.
|
||||
*
|
||||
* This function returns a hardcoded number. This never returns a negative
|
||||
* value; if there are no drivers compiled into this build of SDL, this
|
||||
* function returns zero. The presence of a driver in this list does not mean
|
||||
* it will function, it just means SDL is capable of interacting with that
|
||||
* interface. For example, a build of SDL might have v4l2 support, but if
|
||||
* there's no kernel support available, SDL's v4l2 driver would fail if used.
|
||||
*
|
||||
* By default, SDL tries all drivers, in its preferred order, until one is
|
||||
* found to be usable.
|
||||
*
|
||||
* \returns the number of built-in camera drivers.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameraDriver
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_GetNumCameraDrivers(void);
|
||||
|
||||
/**
|
||||
* Use this function to get the name of a built in camera driver.
|
||||
*
|
||||
* The list of camera drivers is given in the order that they are normally
|
||||
* initialized by default; the drivers that seem more reasonable to choose
|
||||
* first (as far as the SDL developers believe) are earlier in the list.
|
||||
*
|
||||
* The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
|
||||
* "coremedia" or "android". These never have Unicode characters, and are not
|
||||
* meant to be proper names.
|
||||
*
|
||||
* \param index the index of the camera driver; the value ranges from 0 to
|
||||
* SDL_GetNumCameraDrivers() - 1.
|
||||
* \returns the name of the camera driver at the requested index, or NULL if
|
||||
* an invalid index was specified.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetNumCameraDrivers
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraDriver(int index);
|
||||
|
||||
/**
|
||||
* Get the name of the current camera driver.
|
||||
*
|
||||
* The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
|
||||
* "coremedia" or "android". These never have Unicode characters, and are not
|
||||
* meant to be proper names.
|
||||
*
|
||||
* \returns the name of the current camera driver or NULL if no driver has
|
||||
* been initialized.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCurrentCameraDriver(void);
|
||||
|
||||
/**
|
||||
* Get a list of currently connected camera devices.
|
||||
*
|
||||
* \param count a pointer filled in with the number of cameras returned, may
|
||||
* be NULL.
|
||||
* \returns a 0 terminated array of camera instance IDs or NULL on failure;
|
||||
* call SDL_GetError() for more information. This should be freed
|
||||
* with SDL_free() when it is no longer needed.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_CameraID * SDLCALL SDL_GetCameras(int *count);
|
||||
|
||||
/**
|
||||
* Get the list of native formats/sizes a camera supports.
|
||||
*
|
||||
* This returns a list of all formats and frame sizes that a specific camera
|
||||
* can offer. This is useful if your app can accept a variety of image formats
|
||||
* and sizes and so want to find the optimal spec that doesn't require
|
||||
* conversion.
|
||||
*
|
||||
* This function isn't strictly required; if you call SDL_OpenCamera with a
|
||||
* NULL spec, SDL will choose a native format for you, and if you instead
|
||||
* specify a desired format, it will transparently convert to the requested
|
||||
* format on your behalf.
|
||||
*
|
||||
* If `count` is not NULL, it will be filled with the number of elements in
|
||||
* the returned array.
|
||||
*
|
||||
* Note that it's legal for a camera to supply an empty list. This is what
|
||||
* will happen on Emscripten builds, since that platform won't tell _anything_
|
||||
* about available cameras until you've opened one, and won't even tell if
|
||||
* there _is_ a camera until the user has given you permission to check
|
||||
* through a scary warning popup.
|
||||
*
|
||||
* \param instance_id the camera device instance ID.
|
||||
* \param count a pointer filled in with the number of elements in the list,
|
||||
* may be NULL.
|
||||
* \returns a NULL terminated array of pointers to SDL_CameraSpec or NULL on
|
||||
* failure; call SDL_GetError() for more information. This is a
|
||||
* single allocation that should be freed with SDL_free() when it is
|
||||
* no longer needed.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameras
|
||||
* \sa SDL_OpenCamera
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_CameraSpec ** SDLCALL SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int *count);
|
||||
|
||||
/**
|
||||
* Get the human-readable device name for a camera.
|
||||
*
|
||||
* \param instance_id the camera device instance ID.
|
||||
* \returns a human-readable device name or NULL on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameras
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraName(SDL_CameraID instance_id);
|
||||
|
||||
/**
|
||||
* Get the position of the camera in relation to the system.
|
||||
*
|
||||
* Most platforms will report UNKNOWN, but mobile devices, like phones, can
|
||||
* often make a distinction between cameras on the front of the device (that
|
||||
* points towards the user, for taking "selfies") and cameras on the back (for
|
||||
* filming in the direction the user is facing).
|
||||
*
|
||||
* \param instance_id the camera device instance ID.
|
||||
* \returns the position of the camera on the system hardware.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameras
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_CameraPosition SDLCALL SDL_GetCameraPosition(SDL_CameraID instance_id);
|
||||
|
||||
/**
|
||||
* Open a video recording device (a "camera").
|
||||
*
|
||||
* You can open the device with any reasonable spec, and if the hardware can't
|
||||
* directly support it, it will convert data seamlessly to the requested
|
||||
* format. This might incur overhead, including scaling of image data.
|
||||
*
|
||||
* If you would rather accept whatever format the device offers, you can pass
|
||||
* a NULL spec here and it will choose one for you (and you can use
|
||||
* SDL_Surface's conversion/scaling functions directly if necessary).
|
||||
*
|
||||
* You can call SDL_GetCameraFormat() to get the actual data format if passing
|
||||
* a NULL spec here. You can see the exact specs a device can support without
|
||||
* conversion with SDL_GetCameraSupportedFormats().
|
||||
*
|
||||
* SDL will not attempt to emulate framerate; it will try to set the hardware
|
||||
* to the rate closest to the requested speed, but it won't attempt to limit
|
||||
* or duplicate frames artificially; call SDL_GetCameraFormat() to see the
|
||||
* actual framerate of the opened the device, and check your timestamps if
|
||||
* this is crucial to your app!
|
||||
*
|
||||
* Note that the camera is not usable until the user approves its use! On some
|
||||
* platforms, the operating system will prompt the user to permit access to
|
||||
* the camera, and they can choose Yes or No at that point. Until they do, the
|
||||
* camera will not be usable. The app should either wait for an
|
||||
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
|
||||
* or poll SDL_GetCameraPermissionState() occasionally until it returns
|
||||
* non-zero. On platforms that don't require explicit user approval (and
|
||||
* perhaps in places where the user previously permitted access), the approval
|
||||
* event might come immediately, but it might come seconds, minutes, or hours
|
||||
* later!
|
||||
*
|
||||
* \param instance_id the camera device instance ID.
|
||||
* \param spec the desired format for data the device will provide. Can be
|
||||
* NULL.
|
||||
* \returns an SDL_Camera object or NULL on failure; call SDL_GetError() for
|
||||
* more information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetCameras
|
||||
* \sa SDL_GetCameraFormat
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_Camera * SDLCALL SDL_OpenCamera(SDL_CameraID instance_id, const SDL_CameraSpec *spec);
|
||||
|
||||
/**
|
||||
* Query if camera access has been approved by the user.
|
||||
*
|
||||
* Cameras will not function between when the device is opened by the app and
|
||||
* when the user permits access to the hardware. On some platforms, this
|
||||
* presents as a popup dialog where the user has to explicitly approve access;
|
||||
* on others the approval might be implicit and not alert the user at all.
|
||||
*
|
||||
* This function can be used to check the status of that approval. It will
|
||||
* return 0 if still waiting for user response, 1 if the camera is approved
|
||||
* for use, and -1 if the user denied access.
|
||||
*
|
||||
* Instead of polling with this function, you can wait for a
|
||||
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event
|
||||
* in the standard SDL event loop, which is guaranteed to be sent once when
|
||||
* permission to use the camera is decided.
|
||||
*
|
||||
* If a camera is declined, there's nothing to be done but call
|
||||
* SDL_CloseCamera() to dispose of it.
|
||||
*
|
||||
* \param camera the opened camera device to query.
|
||||
* \returns -1 if user denied access to the camera, 1 if user approved access,
|
||||
* 0 if no decision has been made yet.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
* \sa SDL_CloseCamera
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_GetCameraPermissionState(SDL_Camera *camera);
|
||||
|
||||
/**
|
||||
* Get the instance ID of an opened camera.
|
||||
*
|
||||
* \param camera an SDL_Camera to query.
|
||||
* \returns the instance ID of the specified camera on success or 0 on
|
||||
* failure; call SDL_GetError() for more information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_CameraID SDLCALL SDL_GetCameraID(SDL_Camera *camera);
|
||||
|
||||
/**
|
||||
* Get the properties associated with an opened camera.
|
||||
*
|
||||
* \param camera the SDL_Camera obtained from SDL_OpenCamera().
|
||||
* \returns a valid property ID on success or 0 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetCameraProperties(SDL_Camera *camera);
|
||||
|
||||
/**
|
||||
* Get the spec that a camera is using when generating images.
|
||||
*
|
||||
* Note that this might not be the native format of the hardware, as SDL might
|
||||
* be converting to this format behind the scenes.
|
||||
*
|
||||
* If the system is waiting for the user to approve access to the camera, as
|
||||
* some platforms require, this will return false, but this isn't necessarily
|
||||
* a fatal error; you should either wait for an
|
||||
* SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event,
|
||||
* or poll SDL_GetCameraPermissionState() occasionally until it returns
|
||||
* non-zero.
|
||||
*
|
||||
* \param camera opened camera device.
|
||||
* \param spec the SDL_CameraSpec to be initialized by this function.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_GetCameraFormat(SDL_Camera *camera, SDL_CameraSpec *spec);
|
||||
|
||||
/**
|
||||
* Acquire a frame.
|
||||
*
|
||||
* The frame is a memory pointer to the image data, whose size and format are
|
||||
* given by the spec requested when opening the device.
|
||||
*
|
||||
* This is a non blocking API. If there is a frame available, a non-NULL
|
||||
* surface is returned, and timestampNS will be filled with a non-zero value.
|
||||
*
|
||||
* Note that an error case can also return NULL, but a NULL by itself is
|
||||
* normal and just signifies that a new frame is not yet available. Note that
|
||||
* even if a camera device fails outright (a USB camera is unplugged while in
|
||||
* use, etc), SDL will send an event separately to notify the app, but
|
||||
* continue to provide blank frames at ongoing intervals until
|
||||
* SDL_CloseCamera() is called, so real failure here is almost always an out
|
||||
* of memory condition.
|
||||
*
|
||||
* After use, the frame should be released with SDL_ReleaseCameraFrame(). If
|
||||
* you don't do this, the system may stop providing more video!
|
||||
*
|
||||
* Do not call SDL_DestroySurface() on the returned surface! It must be given
|
||||
* back to the camera subsystem with SDL_ReleaseCameraFrame!
|
||||
*
|
||||
* If the system is waiting for the user to approve access to the camera, as
|
||||
* some platforms require, this will return NULL (no frames available); you
|
||||
* should either wait for an SDL_EVENT_CAMERA_DEVICE_APPROVED (or
|
||||
* SDL_EVENT_CAMERA_DEVICE_DENIED) event, or poll
|
||||
* SDL_GetCameraPermissionState() occasionally until it returns non-zero.
|
||||
*
|
||||
* \param camera opened camera device.
|
||||
* \param timestampNS a pointer filled in with the frame's timestamp, or 0 on
|
||||
* error. Can be NULL.
|
||||
* \returns a new frame of video on success, NULL if none is currently
|
||||
* available.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_ReleaseCameraFrame
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_AcquireCameraFrame(SDL_Camera *camera, Uint64 *timestampNS);
|
||||
|
||||
/**
|
||||
* Release a frame of video acquired from a camera.
|
||||
*
|
||||
* Let the back-end re-use the internal buffer for camera.
|
||||
*
|
||||
* This function _must_ be called only on surface objects returned by
|
||||
* SDL_AcquireCameraFrame(). This function should be called as quickly as
|
||||
* possible after acquisition, as SDL keeps a small FIFO queue of surfaces for
|
||||
* video frames; if surfaces aren't released in a timely manner, SDL may drop
|
||||
* upcoming video frames from the camera.
|
||||
*
|
||||
* If the app needs to keep the surface for a significant time, they should
|
||||
* make a copy of it and release the original.
|
||||
*
|
||||
* The app should not use the surface again after calling this function;
|
||||
* assume the surface is freed and the pointer is invalid.
|
||||
*
|
||||
* \param camera opened camera device.
|
||||
* \param frame the video frame surface to release.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_AcquireCameraFrame
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_ReleaseCameraFrame(SDL_Camera *camera, SDL_Surface *frame);
|
||||
|
||||
/**
|
||||
* Use this function to shut down camera processing and close the camera
|
||||
* device.
|
||||
*
|
||||
* \param camera opened camera device.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, but no
|
||||
* thread may reference `device` once this function is called.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_CloseCamera(SDL_Camera *camera);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_camera_h_ */
|
||||
-330
@@ -1,330 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryClipboard
|
||||
*
|
||||
* SDL provides access to the system clipboard, both for reading information
|
||||
* from other processes and publishing information of its own.
|
||||
*
|
||||
* This is not just text! SDL apps can access and publish data by mimetype.
|
||||
*
|
||||
* ## Basic use (text)
|
||||
*
|
||||
* Obtaining and publishing simple text to the system clipboard is as easy as
|
||||
* calling SDL_GetClipboardText() and SDL_SetClipboardText(), respectively.
|
||||
* These deal with C strings in UTF-8 encoding. Data transmission and encoding
|
||||
* conversion is completely managed by SDL.
|
||||
*
|
||||
* ## Clipboard callbacks (data other than text)
|
||||
*
|
||||
* Things get more complicated when the clipboard contains something other
|
||||
* than text. Not only can the system clipboard contain data of any type, in
|
||||
* some cases it can contain the same data in different formats! For example,
|
||||
* an image painting app might let the user copy a graphic to the clipboard,
|
||||
* and offers it in .BMP, .JPG, or .PNG format for other apps to consume.
|
||||
*
|
||||
* Obtaining clipboard data ("pasting") like this is a matter of calling
|
||||
* SDL_GetClipboardData() and telling it the mimetype of the data you want.
|
||||
* But how does one know if that format is available? SDL_HasClipboardData()
|
||||
* can report if a specific mimetype is offered, and
|
||||
* SDL_GetClipboardMimeTypes() can provide the entire list of mimetypes
|
||||
* available, so the app can decide what to do with the data and what formats
|
||||
* it can support.
|
||||
*
|
||||
* Setting the clipboard ("copying") to arbitrary data is done with
|
||||
* SDL_SetClipboardData. The app does not provide the data in this call, but
|
||||
* rather the mimetypes it is willing to provide and a callback function.
|
||||
* During the callback, the app will generate the data. This allows massive
|
||||
* data sets to be provided to the clipboard, without any data being copied
|
||||
* before it is explicitly requested. More specifically, it allows an app to
|
||||
* offer data in multiple formats without providing a copy of all of them
|
||||
* upfront. If the app has an image that it could provide in PNG or JPG
|
||||
* format, it doesn't have to encode it to either of those unless and until
|
||||
* something tries to paste it.
|
||||
*
|
||||
* ## Primary Selection
|
||||
*
|
||||
* The X11 and Wayland video targets have a concept of the "primary selection"
|
||||
* in addition to the usual clipboard. This is generally highlighted (but not
|
||||
* explicitly copied) text from various apps. SDL offers APIs for this through
|
||||
* SDL_GetPrimarySelectionText() and SDL_SetPrimarySelectionText(). SDL offers
|
||||
* these APIs on platforms without this concept, too, but only so far that it
|
||||
* will keep a copy of a string that the app sets for later retrieval; the
|
||||
* operating system will not ever attempt to change the string externally if
|
||||
* it doesn't support a primary selection.
|
||||
*/
|
||||
|
||||
#ifndef SDL_clipboard_h_
|
||||
#define SDL_clipboard_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
/**
|
||||
* Put UTF-8 text into the clipboard.
|
||||
*
|
||||
* \param text the text to store in the clipboard.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetClipboardText
|
||||
* \sa SDL_HasClipboardText
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
|
||||
|
||||
/**
|
||||
* Get UTF-8 text from the clipboard.
|
||||
*
|
||||
* This function returns an empty string if there is not enough memory left
|
||||
* for a copy of the clipboard's content.
|
||||
*
|
||||
* \returns the clipboard text on success or an empty string on failure; call
|
||||
* SDL_GetError() for more information. This should be freed with
|
||||
* SDL_free() when it is no longer needed.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasClipboardText
|
||||
* \sa SDL_SetClipboardText
|
||||
*/
|
||||
extern SDL_DECLSPEC char * SDLCALL SDL_GetClipboardText(void);
|
||||
|
||||
/**
|
||||
* Query whether the clipboard exists and contains a non-empty text string.
|
||||
*
|
||||
* \returns true if the clipboard has text, or false if it does not.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetClipboardText
|
||||
* \sa SDL_SetClipboardText
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardText(void);
|
||||
|
||||
/**
|
||||
* Put UTF-8 text into the primary selection.
|
||||
*
|
||||
* \param text the text to store in the primary selection.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetPrimarySelectionText
|
||||
* \sa SDL_HasPrimarySelectionText
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
|
||||
|
||||
/**
|
||||
* Get UTF-8 text from the primary selection.
|
||||
*
|
||||
* This function returns an empty string if there is not enough memory left
|
||||
* for a copy of the primary selection's content.
|
||||
*
|
||||
* \returns the primary selection text on success or an empty string on
|
||||
* failure; call SDL_GetError() for more information. This should be
|
||||
* freed with SDL_free() when it is no longer needed.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasPrimarySelectionText
|
||||
* \sa SDL_SetPrimarySelectionText
|
||||
*/
|
||||
extern SDL_DECLSPEC char * SDLCALL SDL_GetPrimarySelectionText(void);
|
||||
|
||||
/**
|
||||
* Query whether the primary selection exists and contains a non-empty text
|
||||
* string.
|
||||
*
|
||||
* \returns true if the primary selection has text, or false if it does not.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetPrimarySelectionText
|
||||
* \sa SDL_SetPrimarySelectionText
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
|
||||
|
||||
/**
|
||||
* Callback function that will be called when data for the specified mime-type
|
||||
* is requested by the OS.
|
||||
*
|
||||
* The callback function is called with NULL as the mime_type when the
|
||||
* clipboard is cleared or new data is set. The clipboard is automatically
|
||||
* cleared in SDL_Quit().
|
||||
*
|
||||
* \param userdata a pointer to the provided user data.
|
||||
* \param mime_type the requested mime-type.
|
||||
* \param size a pointer filled in with the length of the returned data.
|
||||
* \returns a pointer to the data for the provided mime-type. Returning NULL
|
||||
* or setting the length to 0 will cause zero length data to be sent
|
||||
* to the "receiver", which should be able to handle this. The
|
||||
* returned data will not be freed, so it needs to be retained and
|
||||
* dealt with internally.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SetClipboardData
|
||||
*/
|
||||
typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size);
|
||||
|
||||
/**
|
||||
* Callback function that will be called when the clipboard is cleared, or when new
|
||||
* data is set.
|
||||
*
|
||||
* \param userdata a pointer to the provided user data.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SetClipboardData
|
||||
*/
|
||||
typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
|
||||
|
||||
/**
|
||||
* Offer clipboard data to the OS.
|
||||
*
|
||||
* Tell the operating system that the application is offering clipboard data
|
||||
* for each of the provided mime-types. Once another application requests the
|
||||
* data the callback function will be called, allowing it to generate and
|
||||
* respond with the data for the requested mime-type.
|
||||
*
|
||||
* The size of text data does not include any terminator, and the text does
|
||||
* not need to be null-terminated (e.g., you can directly copy a portion of a
|
||||
* document).
|
||||
*
|
||||
* \param callback a function pointer to the function that provides the
|
||||
* clipboard data.
|
||||
* \param cleanup a function pointer to the function that cleans up the
|
||||
* clipboard data.
|
||||
* \param userdata an opaque pointer that will be forwarded to the callbacks.
|
||||
* \param mime_types a list of mime-types that are being offered. SDL copies the given list.
|
||||
* \param num_mime_types the number of mime-types in the mime_types list.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_ClearClipboardData
|
||||
* \sa SDL_GetClipboardData
|
||||
* \sa SDL_HasClipboardData
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardCleanupCallback cleanup, void *userdata, const char **mime_types, size_t num_mime_types);
|
||||
|
||||
/**
|
||||
* Clear the clipboard data.
|
||||
*
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SetClipboardData
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
|
||||
|
||||
/**
|
||||
* Get the data from the clipboard for a given mime type.
|
||||
*
|
||||
* The size of text data does not include the terminator, but the text is
|
||||
* guaranteed to be null-terminated.
|
||||
*
|
||||
* \param mime_type the mime type to read from the clipboard.
|
||||
* \param size a pointer filled in with the length of the returned data.
|
||||
* \returns the retrieved data buffer or NULL on failure; call SDL_GetError()
|
||||
* for more information. This should be freed with SDL_free() when it
|
||||
* is no longer needed.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasClipboardData
|
||||
* \sa SDL_SetClipboardData
|
||||
*/
|
||||
extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, size_t *size);
|
||||
|
||||
/**
|
||||
* Query whether there is data in the clipboard for the provided mime type.
|
||||
*
|
||||
* \param mime_type the mime type to check for data.
|
||||
* \returns true if data exists in the clipboard for the provided mime type,
|
||||
* false if it does not.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SetClipboardData
|
||||
* \sa SDL_GetClipboardData
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
|
||||
|
||||
/**
|
||||
* Retrieve the list of mime types available in the clipboard.
|
||||
*
|
||||
* \param num_mime_types a pointer filled with the number of mime types, may
|
||||
* be NULL.
|
||||
* \returns a null-terminated array of strings with mime types, or NULL on
|
||||
* failure; call SDL_GetError() for more information. This should be
|
||||
* freed with SDL_free() when it is no longer needed.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SetClipboardData
|
||||
*/
|
||||
extern SDL_DECLSPEC char ** SDLCALL SDL_GetClipboardMimeTypes(size_t *num_mime_types);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_clipboard_h_ */
|
||||
-41
@@ -1,41 +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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file reverses the effects of SDL_begin_code.h and should be included
|
||||
* after you finish any function and structure declarations in your headers.
|
||||
*
|
||||
* SDL's headers use this; applications generally should not include this
|
||||
* header directly.
|
||||
*/
|
||||
|
||||
#ifndef SDL_begin_code_h
|
||||
#error SDL_close_code.h included without matching SDL_begin_code.h
|
||||
#endif
|
||||
#undef SDL_begin_code_h
|
||||
|
||||
/* Reset structure packing at previous byte alignment */
|
||||
#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
|
||||
#ifdef __BORLANDC__
|
||||
#pragma nopackwarning
|
||||
#endif
|
||||
#pragma pack(pop)
|
||||
#endif /* Compiler needs structure packing set */
|
||||
-22
@@ -1,22 +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.
|
||||
*/
|
||||
|
||||
/* Header file containing SDL's license. */
|
||||
-353
@@ -1,353 +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: CPUInfo */
|
||||
|
||||
/**
|
||||
* # CategoryCPUInfo
|
||||
*
|
||||
* CPU feature detection for SDL.
|
||||
*
|
||||
* These functions are largely concerned with reporting if the system has
|
||||
* access to various SIMD instruction sets, but also has other important info
|
||||
* to share, such as system RAM size and number of logical CPU cores.
|
||||
*
|
||||
* CPU instruction set checks, like SDL_HasSSE() and SDL_HasNEON(), are
|
||||
* available on all platforms, even if they don't make sense (an ARM processor
|
||||
* will never have SSE and an x86 processor will never have NEON, for example,
|
||||
* but these functions still exist and will simply return false in these
|
||||
* cases).
|
||||
*/
|
||||
|
||||
#ifndef SDL_cpuinfo_h_
|
||||
#define SDL_cpuinfo_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A guess for the cacheline size used for padding.
|
||||
*
|
||||
* Most x86 processors have a 64 byte cache line. The 64-bit PowerPC
|
||||
* processors have a 128 byte cache line. We use the larger value to be
|
||||
* generally safe.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_CACHELINE_SIZE 128
|
||||
|
||||
/**
|
||||
* Get the number of logical CPU cores available.
|
||||
*
|
||||
* \returns the total number of logical CPU cores. On CPUs that include
|
||||
* technologies such as hyperthreading, the number of logical cores
|
||||
* may be more than the number of physical cores.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_GetNumLogicalCPUCores(void);
|
||||
|
||||
/**
|
||||
* Determine the L1 cache line size of the CPU.
|
||||
*
|
||||
* This is useful for determining multi-threaded structure padding or SIMD
|
||||
* prefetch sizes.
|
||||
*
|
||||
* \returns the L1 cache line size of the CPU, in bytes.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has AltiVec features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using PowerPC instruction
|
||||
* sets.
|
||||
*
|
||||
* \returns true if the CPU has AltiVec features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasAltiVec(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has MMX features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has MMX features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasMMX(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has SSE features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has SSE features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasSSE2
|
||||
* \sa SDL_HasSSE3
|
||||
* \sa SDL_HasSSE41
|
||||
* \sa SDL_HasSSE42
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has SSE2 features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has SSE2 features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasSSE
|
||||
* \sa SDL_HasSSE3
|
||||
* \sa SDL_HasSSE41
|
||||
* \sa SDL_HasSSE42
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE2(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has SSE3 features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has SSE3 features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasSSE
|
||||
* \sa SDL_HasSSE2
|
||||
* \sa SDL_HasSSE41
|
||||
* \sa SDL_HasSSE42
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE3(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has SSE4.1 features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has SSE4.1 features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasSSE
|
||||
* \sa SDL_HasSSE2
|
||||
* \sa SDL_HasSSE3
|
||||
* \sa SDL_HasSSE42
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE41(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has SSE4.2 features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has SSE4.2 features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasSSE
|
||||
* \sa SDL_HasSSE2
|
||||
* \sa SDL_HasSSE3
|
||||
* \sa SDL_HasSSE41
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasSSE42(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has AVX features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has AVX features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasAVX2
|
||||
* \sa SDL_HasAVX512F
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has AVX2 features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has AVX2 features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasAVX
|
||||
* \sa SDL_HasAVX512F
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX2(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has AVX-512F (foundation) features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using Intel instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has AVX-512F features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasAVX
|
||||
* \sa SDL_HasAVX2
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasAVX512F(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has ARM SIMD (ARMv6) features.
|
||||
*
|
||||
* This is different from ARM NEON, which is a different instruction set.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using ARM instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has ARM SIMD features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_HasNEON
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasARMSIMD(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has NEON (ARM SIMD) features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using ARM instruction sets.
|
||||
*
|
||||
* \returns true if the CPU has ARM NEON features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasNEON(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has LSX (LOONGARCH SIMD) features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using LOONGARCH instruction
|
||||
* sets.
|
||||
*
|
||||
* \returns true if the CPU has LOONGARCH LSX features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasLSX(void);
|
||||
|
||||
/**
|
||||
* Determine whether the CPU has LASX (LOONGARCH SIMD) features.
|
||||
*
|
||||
* This always returns false on CPUs that aren't using LOONGARCH instruction
|
||||
* sets.
|
||||
*
|
||||
* \returns true if the CPU has LOONGARCH LASX features or false if not.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_HasLASX(void);
|
||||
|
||||
/**
|
||||
* Get the amount of RAM configured in the system.
|
||||
*
|
||||
* \returns the amount of RAM configured in the system in MiB.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
|
||||
|
||||
/**
|
||||
* Report the alignment this system needs for SIMD allocations.
|
||||
*
|
||||
* This will return the minimum number of bytes to which a pointer must be
|
||||
* aligned to be compatible with SIMD instructions on the current machine. For
|
||||
* example, if the machine supports SSE only, it will return 16, but if it
|
||||
* supports AVX-512F, it'll return 64 (etc). This only reports values for
|
||||
* instruction sets SDL knows about, so if your SDL build doesn't have
|
||||
* SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and
|
||||
* not 64 for the AVX-512 instructions that exist but SDL doesn't know about.
|
||||
* Plan accordingly.
|
||||
*
|
||||
* \returns the alignment in bytes needed for available, known SIMD
|
||||
* instructions.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_aligned_alloc
|
||||
* \sa SDL_aligned_free
|
||||
*/
|
||||
extern SDL_DECLSPEC size_t SDLCALL SDL_GetSIMDAlignment(void);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_cpuinfo_h_ */
|
||||
-341
@@ -1,341 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryDialog
|
||||
*
|
||||
* File dialog support.
|
||||
*
|
||||
* SDL offers file dialogs, to let users select files with native GUI
|
||||
* interfaces. There are "open" dialogs, "save" dialogs, and folder selection
|
||||
* dialogs. The app can control some details, such as filtering to specific
|
||||
* files, or whether multiple files can be selected by the user.
|
||||
*
|
||||
* Note that launching a file dialog is a non-blocking operation; control
|
||||
* returns to the app immediately, and a callback is called later (possibly in
|
||||
* another thread) when the user makes a choice.
|
||||
*/
|
||||
|
||||
#ifndef SDL_dialog_h_
|
||||
#define SDL_dialog_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_properties.h>
|
||||
#include <SDL3/SDL_video.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An entry for filters for file dialogs.
|
||||
*
|
||||
* `name` is a user-readable label for the filter (for example, "Office
|
||||
* document").
|
||||
*
|
||||
* `pattern` is a semicolon-separated list of file extensions (for example,
|
||||
* "doc;docx"). File extensions may only contain alphanumeric characters,
|
||||
* hyphens, underscores and periods. Alternatively, the whole string can be a
|
||||
* single asterisk ("*"), which serves as an "All files" filter.
|
||||
*
|
||||
* \since This struct is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_DialogFileCallback
|
||||
* \sa SDL_ShowOpenFileDialog
|
||||
* \sa SDL_ShowSaveFileDialog
|
||||
* \sa SDL_ShowOpenFolderDialog
|
||||
* \sa SDL_ShowFileDialogWithProperties
|
||||
*/
|
||||
typedef struct SDL_DialogFileFilter
|
||||
{
|
||||
const char *name;
|
||||
const char *pattern;
|
||||
} SDL_DialogFileFilter;
|
||||
|
||||
/**
|
||||
* Callback used by file dialog functions.
|
||||
*
|
||||
* The specific usage is described in each function.
|
||||
*
|
||||
* If `filelist` is:
|
||||
*
|
||||
* - NULL, an error occurred. Details can be obtained with SDL_GetError().
|
||||
* - A pointer to NULL, the user either didn't choose any file or canceled the
|
||||
* dialog.
|
||||
* - A pointer to non-`NULL`, the user chose one or more files. The argument
|
||||
* is a null-terminated array of pointers to UTF-8 encoded strings, each
|
||||
* containing a path.
|
||||
*
|
||||
* The filelist argument should not be freed; it will automatically be freed
|
||||
* when the callback returns.
|
||||
*
|
||||
* The filter argument is the index of the filter that was selected, or -1 if
|
||||
* no filter was selected or if the platform or method doesn't support
|
||||
* fetching the selected filter.
|
||||
*
|
||||
* In Android, the `filelist` are `content://` URIs. They should be opened
|
||||
* using SDL_IOFromFile() with appropriate modes. This applies both to open
|
||||
* and save file dialog.
|
||||
*
|
||||
* \param userdata an app-provided pointer, for the callback's use.
|
||||
* \param filelist the file(s) chosen by the user.
|
||||
* \param filter index of the selected filter.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_DialogFileFilter
|
||||
* \sa SDL_ShowOpenFileDialog
|
||||
* \sa SDL_ShowSaveFileDialog
|
||||
* \sa SDL_ShowOpenFolderDialog
|
||||
* \sa SDL_ShowFileDialogWithProperties
|
||||
*/
|
||||
typedef void (SDLCALL *SDL_DialogFileCallback)(void *userdata, const char * const *filelist, int filter);
|
||||
|
||||
/**
|
||||
* Displays a dialog that lets the user select a file on their filesystem.
|
||||
*
|
||||
* This is an asynchronous function; it will return immediately, and the
|
||||
* result will be passed to the callback.
|
||||
*
|
||||
* The callback will be invoked with a null-terminated list of files the user
|
||||
* chose. The list will be empty if the user canceled the dialog, and it will
|
||||
* be NULL if an error occurred.
|
||||
*
|
||||
* Note that the callback may be called from a different thread than the one
|
||||
* the function was invoked on.
|
||||
*
|
||||
* Depending on the platform, the user may be allowed to input paths that
|
||||
* don't yet exist.
|
||||
*
|
||||
* On Linux, dialogs may require XDG Portals, which requires DBus, which
|
||||
* requires an event-handling loop. Apps that do not use SDL to handle events
|
||||
* should add a call to SDL_PumpEvents in their main loop.
|
||||
*
|
||||
* \param callback a function pointer to be invoked when the user selects a
|
||||
* file and accepts, or cancels the dialog, or an error
|
||||
* occurs.
|
||||
* \param userdata an optional pointer to pass extra data to the callback when
|
||||
* it will be invoked.
|
||||
* \param window the window that the dialog should be modal for, may be NULL.
|
||||
* Not all platforms support this option.
|
||||
* \param filters a list of filters, may be NULL. Not all platforms support
|
||||
* this option, and platforms that do support it may allow the
|
||||
* user to ignore the filters. If non-NULL, it must remain
|
||||
* valid at least until the callback is invoked.
|
||||
* \param nfilters the number of filters. Ignored if filters is NULL.
|
||||
* \param default_location the default folder or file to start the dialog at,
|
||||
* may be NULL. Not all platforms support this option.
|
||||
* \param allow_many if non-zero, the user will be allowed to select multiple
|
||||
* entries. Not all platforms support this option.
|
||||
*
|
||||
* \threadsafety This function should be called only from the main thread. The
|
||||
* callback may be invoked from the same thread or from a
|
||||
* different one, depending on the OS's constraints.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_DialogFileCallback
|
||||
* \sa SDL_DialogFileFilter
|
||||
* \sa SDL_ShowSaveFileDialog
|
||||
* \sa SDL_ShowOpenFolderDialog
|
||||
* \sa SDL_ShowFileDialogWithProperties
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, bool allow_many);
|
||||
|
||||
/**
|
||||
* Displays a dialog that lets the user choose a new or existing file on their
|
||||
* filesystem.
|
||||
*
|
||||
* This is an asynchronous function; it will return immediately, and the
|
||||
* result will be passed to the callback.
|
||||
*
|
||||
* The callback will be invoked with a null-terminated list of files the user
|
||||
* chose. The list will be empty if the user canceled the dialog, and it will
|
||||
* be NULL if an error occurred.
|
||||
*
|
||||
* Note that the callback may be called from a different thread than the one
|
||||
* the function was invoked on.
|
||||
*
|
||||
* The chosen file may or may not already exist.
|
||||
*
|
||||
* On Linux, dialogs may require XDG Portals, which requires DBus, which
|
||||
* requires an event-handling loop. Apps that do not use SDL to handle events
|
||||
* should add a call to SDL_PumpEvents in their main loop.
|
||||
*
|
||||
* \param callback a function pointer to be invoked when the user selects a
|
||||
* file and accepts, or cancels the dialog, or an error
|
||||
* occurs.
|
||||
* \param userdata an optional pointer to pass extra data to the callback when
|
||||
* it will be invoked.
|
||||
* \param window the window that the dialog should be modal for, may be NULL.
|
||||
* Not all platforms support this option.
|
||||
* \param filters a list of filters, may be NULL. Not all platforms support
|
||||
* this option, and platforms that do support it may allow the
|
||||
* user to ignore the filters. If non-NULL, it must remain
|
||||
* valid at least until the callback is invoked.
|
||||
* \param nfilters the number of filters. Ignored if filters is NULL.
|
||||
* \param default_location the default folder or file to start the dialog at,
|
||||
* may be NULL. Not all platforms support this option.
|
||||
*
|
||||
* \threadsafety This function should be called only from the main thread. The
|
||||
* callback may be invoked from the same thread or from a
|
||||
* different one, depending on the OS's constraints.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_DialogFileCallback
|
||||
* \sa SDL_DialogFileFilter
|
||||
* \sa SDL_ShowOpenFileDialog
|
||||
* \sa SDL_ShowOpenFolderDialog
|
||||
* \sa SDL_ShowFileDialogWithProperties
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location);
|
||||
|
||||
/**
|
||||
* Displays a dialog that lets the user select a folder on their filesystem.
|
||||
*
|
||||
* This is an asynchronous function; it will return immediately, and the
|
||||
* result will be passed to the callback.
|
||||
*
|
||||
* The callback will be invoked with a null-terminated list of files the user
|
||||
* chose. The list will be empty if the user canceled the dialog, and it will
|
||||
* be NULL if an error occurred.
|
||||
*
|
||||
* Note that the callback may be called from a different thread than the one
|
||||
* the function was invoked on.
|
||||
*
|
||||
* Depending on the platform, the user may be allowed to input paths that
|
||||
* don't yet exist.
|
||||
*
|
||||
* On Linux, dialogs may require XDG Portals, which requires DBus, which
|
||||
* requires an event-handling loop. Apps that do not use SDL to handle events
|
||||
* should add a call to SDL_PumpEvents in their main loop.
|
||||
*
|
||||
* \param callback a function pointer to be invoked when the user selects a
|
||||
* file and accepts, or cancels the dialog, or an error
|
||||
* occurs.
|
||||
* \param userdata an optional pointer to pass extra data to the callback when
|
||||
* it will be invoked.
|
||||
* \param window the window that the dialog should be modal for, may be NULL.
|
||||
* Not all platforms support this option.
|
||||
* \param default_location the default folder or file to start the dialog at,
|
||||
* may be NULL. Not all platforms support this option.
|
||||
* \param allow_many if non-zero, the user will be allowed to select multiple
|
||||
* entries. Not all platforms support this option.
|
||||
*
|
||||
* \threadsafety This function should be called only from the main thread. The
|
||||
* callback may be invoked from the same thread or from a
|
||||
* different one, depending on the OS's constraints.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_DialogFileCallback
|
||||
* \sa SDL_ShowOpenFileDialog
|
||||
* \sa SDL_ShowSaveFileDialog
|
||||
* \sa SDL_ShowFileDialogWithProperties
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const char *default_location, bool allow_many);
|
||||
|
||||
/**
|
||||
* Various types of file dialogs.
|
||||
*
|
||||
* This is used by SDL_ShowFileDialogWithProperties() to decide what kind of
|
||||
* dialog to present to the user.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_ShowFileDialogWithProperties
|
||||
*/
|
||||
typedef enum SDL_FileDialogType
|
||||
{
|
||||
SDL_FILEDIALOG_OPENFILE,
|
||||
SDL_FILEDIALOG_SAVEFILE,
|
||||
SDL_FILEDIALOG_OPENFOLDER
|
||||
} SDL_FileDialogType;
|
||||
|
||||
/**
|
||||
* Create and launch a file dialog with the specified properties.
|
||||
*
|
||||
* These are the supported properties:
|
||||
*
|
||||
* - `SDL_PROP_FILE_DIALOG_FILTERS_POINTER`: a pointer to a list of
|
||||
* SDL_DialogFileFilter structs, which will be used as filters for
|
||||
* file-based selections. Ignored if the dialog is an "Open Folder" dialog.
|
||||
* If non-NULL, the array of filters must remain valid at least until the
|
||||
* callback is invoked.
|
||||
* - `SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER`: the number of filters in the
|
||||
* array of filters, if it exists.
|
||||
* - `SDL_PROP_FILE_DIALOG_WINDOW_POINTER`: the window that the dialog should
|
||||
* be modal for.
|
||||
* - `SDL_PROP_FILE_DIALOG_LOCATION_STRING`: the default folder or file to
|
||||
* start the dialog at.
|
||||
* - `SDL_PROP_FILE_DIALOG_MANY_BOOLEAN`: true to allow the user to select
|
||||
* more than one entry.
|
||||
* - `SDL_PROP_FILE_DIALOG_TITLE_STRING`: the title for the dialog.
|
||||
* - `SDL_PROP_FILE_DIALOG_ACCEPT_STRING`: the label that the accept button
|
||||
* should have.
|
||||
* - `SDL_PROP_FILE_DIALOG_CANCEL_STRING`: the label that the cancel button
|
||||
* should have.
|
||||
*
|
||||
* Note that each platform may or may not support any of the properties.
|
||||
*
|
||||
* \param type the type of file dialog.
|
||||
* \param callback a function pointer to be invoked when the user selects a
|
||||
* file and accepts, or cancels the dialog, or an error
|
||||
* occurs.
|
||||
* \param userdata an optional pointer to pass extra data to the callback when
|
||||
* it will be invoked.
|
||||
* \param props the properties to use.
|
||||
*
|
||||
* \threadsafety This function should be called only from the main thread. The
|
||||
* callback may be invoked from the same thread or from a
|
||||
* different one, depending on the OS's constraints.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_FileDialogType
|
||||
* \sa SDL_DialogFileCallback
|
||||
* \sa SDL_DialogFileFilter
|
||||
* \sa SDL_ShowOpenFileDialog
|
||||
* \sa SDL_ShowSaveFileDialog
|
||||
* \sa SDL_ShowOpenFolderDialog
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFileCallback callback, void *userdata, SDL_PropertiesID props);
|
||||
|
||||
#define SDL_PROP_FILE_DIALOG_FILTERS_POINTER "SDL.filedialog.filters"
|
||||
#define SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER "SDL.filedialog.nfilters"
|
||||
#define SDL_PROP_FILE_DIALOG_WINDOW_POINTER "SDL.filedialog.window"
|
||||
#define SDL_PROP_FILE_DIALOG_LOCATION_STRING "SDL.filedialog.location"
|
||||
#define SDL_PROP_FILE_DIALOG_MANY_BOOLEAN "SDL.filedialog.many"
|
||||
#define SDL_PROP_FILE_DIALOG_TITLE_STRING "SDL.filedialog.title"
|
||||
#define SDL_PROP_FILE_DIALOG_ACCEPT_STRING "SDL.filedialog.accept"
|
||||
#define SDL_PROP_FILE_DIALOG_CANCEL_STRING "SDL.filedialog.cancel"
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_dialog_h_ */
|
||||
-2355
File diff suppressed because it is too large
Load Diff
-645
@@ -1,645 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryEndian
|
||||
*
|
||||
* Functions converting endian-specific values to different byte orders.
|
||||
*
|
||||
* These functions either unconditionally swap byte order (SDL_Swap16,
|
||||
* SDL_Swap32, SDL_Swap64, SDL_SwapFloat), or they swap to/from the system's
|
||||
* native byte order (SDL_Swap16LE, SDL_Swap16BE, SDL_Swap32LE, SDL_Swap32BE,
|
||||
* SDL_Swap32LE, SDL_Swap32BE, SDL_SwapFloatLE, SDL_SwapFloatBE). In the
|
||||
* latter case, the functionality is provided by macros that become no-ops if
|
||||
* a swap isn't necessary: on an x86 (littleendian) processor, SDL_Swap32LE
|
||||
* does nothing, but SDL_Swap32BE reverses the bytes of the data. On a PowerPC
|
||||
* processor (bigendian), the macros behavior is reversed.
|
||||
*
|
||||
* The swap routines are inline functions, and attempt to use compiler
|
||||
* intrinsics, inline assembly, and other magic to make byteswapping
|
||||
* efficient.
|
||||
*/
|
||||
|
||||
#ifndef SDL_endian_h_
|
||||
#define SDL_endian_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
|
||||
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
|
||||
#if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
|
||||
#ifndef __PRFCHWINTRIN_H
|
||||
#define __PRFCHWINTRIN_H
|
||||
static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
||||
_m_prefetch(void *__P)
|
||||
{
|
||||
__builtin_prefetch(__P, 0, 3 /* _MM_HINT_T0 */);
|
||||
}
|
||||
#endif /* __PRFCHWINTRIN_H */
|
||||
#endif /* __clang__ */
|
||||
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name The two types of endianness
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
|
||||
/**
|
||||
* A value to represent littleendian byteorder.
|
||||
*
|
||||
* This is used with the preprocessor macro SDL_BYTEORDER, to determine a
|
||||
* platform's byte ordering:
|
||||
*
|
||||
* ```c
|
||||
* #if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
* SDL_Log("This system is littleendian.");
|
||||
* #endif
|
||||
* ```
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_BYTEORDER
|
||||
* \sa SDL_BIG_ENDIAN
|
||||
*/
|
||||
#define SDL_LIL_ENDIAN 1234
|
||||
|
||||
/**
|
||||
* A value to represent bigendian byteorder.
|
||||
*
|
||||
* This is used with the preprocessor macro SDL_BYTEORDER, to determine a
|
||||
* platform's byte ordering:
|
||||
*
|
||||
* ```c
|
||||
* #if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
* SDL_Log("This system is bigendian.");
|
||||
* #endif
|
||||
* ```
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_BYTEORDER
|
||||
* \sa SDL_LIL_ENDIAN
|
||||
*/
|
||||
#define SDL_BIG_ENDIAN 4321
|
||||
|
||||
/* @} */
|
||||
|
||||
#ifndef SDL_BYTEORDER
|
||||
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
|
||||
/**
|
||||
* A macro that reports the target system's byte order.
|
||||
*
|
||||
* This is set to either SDL_LIL_ENDIAN or SDL_BIG_ENDIAN (and maybe other
|
||||
* values in the future, if something else becomes popular). This can be
|
||||
* tested with the preprocessor, so decisions can be made at compile time.
|
||||
*
|
||||
* ```c
|
||||
* #if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
* SDL_Log("This system is bigendian.");
|
||||
* #endif
|
||||
* ```
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_LIL_ENDIAN
|
||||
* \sa SDL_BIG_ENDIAN
|
||||
*/
|
||||
#define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
|
||||
#elif defined(SDL_PLATFORM_LINUX) || defined(__GLIBC__)
|
||||
#include <endian.h>
|
||||
#define SDL_BYTEORDER __BYTE_ORDER
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
#include <sys/byteorder.h>
|
||||
#if defined(_LITTLE_ENDIAN)
|
||||
#define SDL_BYTEORDER SDL_LIL_ENDIAN
|
||||
#elif defined(_BIG_ENDIAN)
|
||||
#define SDL_BYTEORDER SDL_BIG_ENDIAN
|
||||
#else
|
||||
#error Unsupported endianness
|
||||
#endif
|
||||
#elif defined(SDL_PLATFORM_OPENBSD) || defined(__DragonFly__)
|
||||
#include <endian.h>
|
||||
#define SDL_BYTEORDER BYTE_ORDER
|
||||
#elif defined(SDL_PLATFORM_FREEBSD) || defined(SDL_PLATFORM_NETBSD)
|
||||
#include <sys/endian.h>
|
||||
#define SDL_BYTEORDER BYTE_ORDER
|
||||
/* predefs from newer gcc and clang versions: */
|
||||
#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__)
|
||||
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
#define SDL_BYTEORDER SDL_LIL_ENDIAN
|
||||
#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
#define SDL_BYTEORDER SDL_BIG_ENDIAN
|
||||
#else
|
||||
#error Unsupported endianness
|
||||
#endif /**/
|
||||
#else
|
||||
#if defined(__hppa__) || \
|
||||
defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
|
||||
(defined(__MIPS__) && defined(__MIPSEB__)) || \
|
||||
defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \
|
||||
defined(__sparc__) || defined(__sparc)
|
||||
#define SDL_BYTEORDER SDL_BIG_ENDIAN
|
||||
#else
|
||||
#define SDL_BYTEORDER SDL_LIL_ENDIAN
|
||||
#endif
|
||||
#endif /* SDL_PLATFORM_LINUX */
|
||||
#endif /* !SDL_BYTEORDER */
|
||||
|
||||
#ifndef SDL_FLOATWORDORDER
|
||||
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
|
||||
/**
|
||||
* A macro that reports the target system's floating point word order.
|
||||
*
|
||||
* This is set to either SDL_LIL_ENDIAN or SDL_BIG_ENDIAN (and maybe other
|
||||
* values in the future, if something else becomes popular). This can be
|
||||
* tested with the preprocessor, so decisions can be made at compile time.
|
||||
*
|
||||
* ```c
|
||||
* #if SDL_FLOATWORDORDER == SDL_BIG_ENDIAN
|
||||
* SDL_Log("This system's floats are bigendian.");
|
||||
* #endif
|
||||
* ```
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_LIL_ENDIAN
|
||||
* \sa SDL_BIG_ENDIAN
|
||||
*/
|
||||
#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
|
||||
/* predefs from newer gcc versions: */
|
||||
#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__)
|
||||
#if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
|
||||
#elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
|
||||
#else
|
||||
#error Unsupported endianness
|
||||
#endif /**/
|
||||
#elif defined(__MAVERICK__)
|
||||
/* For Maverick, float words are always little-endian. */
|
||||
#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
|
||||
#elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__)
|
||||
/* For FPA, float words are always big-endian. */
|
||||
#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
|
||||
#else
|
||||
/* By default, assume that floats words follow the memory system mode. */
|
||||
#define SDL_FLOATWORDORDER SDL_BYTEORDER
|
||||
#endif /* __FLOAT_WORD_ORDER__ */
|
||||
#endif /* !SDL_FLOATWORDORDER */
|
||||
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* various modern compilers may have builtin swap */
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define HAS_BUILTIN_BSWAP16 (SDL_HAS_BUILTIN(__builtin_bswap16)) || \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
|
||||
# define HAS_BUILTIN_BSWAP32 (SDL_HAS_BUILTIN(__builtin_bswap32)) || \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
# define HAS_BUILTIN_BSWAP64 (SDL_HAS_BUILTIN(__builtin_bswap64)) || \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
|
||||
/* this one is broken */
|
||||
# define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95)
|
||||
#else
|
||||
# define HAS_BUILTIN_BSWAP16 0
|
||||
# define HAS_BUILTIN_BSWAP32 0
|
||||
# define HAS_BUILTIN_BSWAP64 0
|
||||
# define HAS_BROKEN_BSWAP 0
|
||||
#endif
|
||||
|
||||
/* Byte swap 16-bit integer. */
|
||||
#ifndef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
#if HAS_BUILTIN_BSWAP16
|
||||
#define SDL_Swap16(x) __builtin_bswap16(x)
|
||||
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
|
||||
#pragma intrinsic(_byteswap_ushort)
|
||||
#define SDL_Swap16(x) _byteswap_ushort(x)
|
||||
#elif defined(__i386__) && !HAS_BROKEN_BSWAP
|
||||
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
||||
{
|
||||
__asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
|
||||
return x;
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
||||
{
|
||||
__asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
|
||||
return x;
|
||||
}
|
||||
#elif (defined(__powerpc__) || defined(__ppc__))
|
||||
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
||||
{
|
||||
int result;
|
||||
|
||||
__asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
|
||||
return (Uint16)result;
|
||||
}
|
||||
#elif (defined(__m68k__) && !defined(__mcoldfire__))
|
||||
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
||||
{
|
||||
__asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
|
||||
return x;
|
||||
}
|
||||
#elif defined(__WATCOMC__) && defined(__386__)
|
||||
extern __inline Uint16 SDL_Swap16(Uint16);
|
||||
#pragma aux SDL_Swap16 = \
|
||||
"xchg al, ah" \
|
||||
parm [ax] \
|
||||
modify [ax];
|
||||
#else
|
||||
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
||||
{
|
||||
return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Byte swap 32-bit integer. */
|
||||
#ifndef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
#if HAS_BUILTIN_BSWAP32
|
||||
#define SDL_Swap32(x) __builtin_bswap32(x)
|
||||
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#define SDL_Swap32(x) _byteswap_ulong(x)
|
||||
#elif defined(__i386__) && !HAS_BROKEN_BSWAP
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
||||
{
|
||||
__asm__("bswap %0": "=r"(x):"0"(x));
|
||||
return x;
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
||||
{
|
||||
__asm__("bswapl %0": "=r"(x):"0"(x));
|
||||
return x;
|
||||
}
|
||||
#elif (defined(__powerpc__) || defined(__ppc__))
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
||||
{
|
||||
Uint32 result;
|
||||
|
||||
__asm__("rlwimi %0,%2,24,16,23": "=&r"(result): "0" (x>>24), "r"(x));
|
||||
__asm__("rlwimi %0,%2,8,8,15" : "=&r"(result): "0" (result), "r"(x));
|
||||
__asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x));
|
||||
return result;
|
||||
}
|
||||
#elif (defined(__m68k__) && !defined(__mcoldfire__))
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
||||
{
|
||||
__asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
|
||||
return x;
|
||||
}
|
||||
#elif defined(__WATCOMC__) && defined(__386__)
|
||||
extern __inline Uint32 SDL_Swap32(Uint32);
|
||||
#pragma aux SDL_Swap32 = \
|
||||
"bswap eax" \
|
||||
parm [eax] \
|
||||
modify [eax];
|
||||
#else
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
||||
{
|
||||
return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |
|
||||
((x >> 8) & 0x0000FF00) | (x >> 24)));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Byte swap 64-bit integer. */
|
||||
#ifndef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
#if HAS_BUILTIN_BSWAP64
|
||||
#define SDL_Swap64(x) __builtin_bswap64(x)
|
||||
#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define SDL_Swap64(x) _byteswap_uint64(x)
|
||||
#elif defined(__i386__) && !HAS_BROKEN_BSWAP
|
||||
SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
Uint32 a, b;
|
||||
} s;
|
||||
Uint64 u;
|
||||
} v;
|
||||
v.u = x;
|
||||
__asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
|
||||
: "=r"(v.s.a), "=r"(v.s.b)
|
||||
: "0" (v.s.a), "1"(v.s.b));
|
||||
return v.u;
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
|
||||
{
|
||||
__asm__("bswapq %0": "=r"(x):"0"(x));
|
||||
return x;
|
||||
}
|
||||
#elif defined(__WATCOMC__) && defined(__386__)
|
||||
extern __inline Uint64 SDL_Swap64(Uint64);
|
||||
#pragma aux SDL_Swap64 = \
|
||||
"bswap eax" \
|
||||
"bswap edx" \
|
||||
"xchg eax,edx" \
|
||||
parm [eax edx] \
|
||||
modify [eax edx];
|
||||
#else
|
||||
SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
|
||||
{
|
||||
Uint32 hi, lo;
|
||||
|
||||
/* Separate into high and low 32-bit values and swap them */
|
||||
lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
|
||||
x >>= 32;
|
||||
hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
|
||||
x = SDL_Swap32(lo);
|
||||
x <<= 32;
|
||||
x |= SDL_Swap32(hi);
|
||||
return (x);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Byte-swap a floating point number.
|
||||
*
|
||||
* This will always byte-swap the value, whether it's currently in the native
|
||||
* byteorder of the system or not. You should use SDL_SwapFloatLE or
|
||||
* SDL_SwapFloatBE instead, in most cases.
|
||||
*
|
||||
* Note that this is a forced-inline function in a header, and not a public
|
||||
* API function available in the SDL library (which is to say, the code is
|
||||
* embedded in the calling program and the linker and dynamic loader will not
|
||||
* be able to find this function inside SDL itself).
|
||||
*
|
||||
* \param x the value to byte-swap.
|
||||
* \returns x, with its bytes in the opposite endian order.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE float SDL_SwapFloat(float x)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
Uint32 ui32;
|
||||
} swapper;
|
||||
swapper.f = x;
|
||||
swapper.ui32 = SDL_Swap32(swapper.ui32);
|
||||
return swapper.f;
|
||||
}
|
||||
|
||||
/* remove extra macros */
|
||||
#undef HAS_BROKEN_BSWAP
|
||||
#undef HAS_BUILTIN_BSWAP16
|
||||
#undef HAS_BUILTIN_BSWAP32
|
||||
#undef HAS_BUILTIN_BSWAP64
|
||||
|
||||
|
||||
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
|
||||
/**
|
||||
* Byte-swap an unsigned 16-bit number.
|
||||
*
|
||||
* This will always byte-swap the value, whether it's currently in the native
|
||||
* byteorder of the system or not. You should use SDL_Swap16LE or SDL_Swap16BE
|
||||
* instead, in most cases.
|
||||
*
|
||||
* Note that this is a forced-inline function in a header, and not a public
|
||||
* API function available in the SDL library (which is to say, the code is
|
||||
* embedded in the calling program and the linker and dynamic loader will not
|
||||
* be able to find this function inside SDL itself).
|
||||
*
|
||||
* \param x the value to byte-swap.
|
||||
* \returns `x`, with its bytes in the opposite endian order.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { return x_but_byteswapped; }
|
||||
|
||||
/**
|
||||
* Byte-swap an unsigned 32-bit number.
|
||||
*
|
||||
* This will always byte-swap the value, whether it's currently in the native
|
||||
* byteorder of the system or not. You should use SDL_Swap32LE or SDL_Swap32BE
|
||||
* instead, in most cases.
|
||||
*
|
||||
* Note that this is a forced-inline function in a header, and not a public
|
||||
* API function available in the SDL library (which is to say, the code is
|
||||
* embedded in the calling program and the linker and dynamic loader will not
|
||||
* be able to find this function inside SDL itself).
|
||||
*
|
||||
* \param x the value to byte-swap.
|
||||
* \returns `x`, with its bytes in the opposite endian order.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return x_but_byteswapped; }
|
||||
|
||||
/**
|
||||
* Byte-swap an unsigned 64-bit number.
|
||||
*
|
||||
* This will always byte-swap the value, whether it's currently in the native
|
||||
* byteorder of the system or not. You should use SDL_Swap64LE or SDL_Swap64BE
|
||||
* instead, in most cases.
|
||||
*
|
||||
* Note that this is a forced-inline function in a header, and not a public
|
||||
* API function available in the SDL library (which is to say, the code is
|
||||
* embedded in the calling program and the linker and dynamic loader will not
|
||||
* be able to find this function inside SDL itself).
|
||||
*
|
||||
* \param x the value to byte-swap.
|
||||
* \returns `x`, with its bytes in the opposite endian order.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
|
||||
|
||||
/**
|
||||
* Swap a 16-bit value from littleendian to native byte order.
|
||||
*
|
||||
* If this is running on a littleendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in littleendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_Swap16LE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
/**
|
||||
* Swap a 32-bit value from littleendian to native byte order.
|
||||
*
|
||||
* If this is running on a littleendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in littleendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_Swap32LE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
/**
|
||||
* Swap a 64-bit value from littleendian to native byte order.
|
||||
*
|
||||
* If this is running on a littleendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in littleendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_Swap64LE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
/**
|
||||
* Swap a floating point value from littleendian to native byte order.
|
||||
*
|
||||
* If this is running on a littleendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in littleendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_SwapFloatLE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
/**
|
||||
* Swap a 16-bit value from bigendian to native byte order.
|
||||
*
|
||||
* If this is running on a bigendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in bigendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_Swap16BE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
/**
|
||||
* Swap a 32-bit value from bigendian to native byte order.
|
||||
*
|
||||
* If this is running on a bigendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in bigendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_Swap32BE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
/**
|
||||
* Swap a 64-bit value from bigendian to native byte order.
|
||||
*
|
||||
* If this is running on a bigendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in bigendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_Swap64BE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
/**
|
||||
* Swap a floating point value from bigendian to native byte order.
|
||||
*
|
||||
* If this is running on a bigendian system, `x` is returned unchanged.
|
||||
*
|
||||
* This macro never references `x` more than once, avoiding side effects.
|
||||
*
|
||||
* \param x the value to swap, in bigendian byte order.
|
||||
* \returns `x` in native byte order.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_SwapFloatBE(x) SwapOnlyIfNecessary(x)
|
||||
|
||||
#elif SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
#define SDL_Swap16LE(x) (x)
|
||||
#define SDL_Swap32LE(x) (x)
|
||||
#define SDL_Swap64LE(x) (x)
|
||||
#define SDL_SwapFloatLE(x) (x)
|
||||
#define SDL_Swap16BE(x) SDL_Swap16(x)
|
||||
#define SDL_Swap32BE(x) SDL_Swap32(x)
|
||||
#define SDL_Swap64BE(x) SDL_Swap64(x)
|
||||
#define SDL_SwapFloatBE(x) SDL_SwapFloat(x)
|
||||
#else
|
||||
#define SDL_Swap16LE(x) SDL_Swap16(x)
|
||||
#define SDL_Swap32LE(x) SDL_Swap32(x)
|
||||
#define SDL_Swap64LE(x) SDL_Swap64(x)
|
||||
#define SDL_SwapFloatLE(x) SDL_SwapFloat(x)
|
||||
#define SDL_Swap16BE(x) (x)
|
||||
#define SDL_Swap32BE(x) (x)
|
||||
#define SDL_Swap64BE(x) (x)
|
||||
#define SDL_SwapFloatBE(x) (x)
|
||||
#endif
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_endian_h_ */
|
||||
-226
@@ -1,226 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryError
|
||||
*
|
||||
* Simple error message routines for SDL.
|
||||
*
|
||||
* Most apps will interface with these APIs in exactly one function: when
|
||||
* almost any SDL function call reports failure, you can get a human-readable
|
||||
* string of the problem from SDL_GetError().
|
||||
*
|
||||
* These strings are maintained per-thread, and apps are welcome to set their
|
||||
* own errors, which is popular when building libraries on top of SDL for
|
||||
* other apps to consume. These strings are set by calling SDL_SetError().
|
||||
*
|
||||
* A common usage pattern is to have a function that returns true for success
|
||||
* and false for failure, and do this when something fails:
|
||||
*
|
||||
* ```c
|
||||
* if (something_went_wrong) {
|
||||
* return SDL_SetError("The thing broke in this specific way: %d", errcode);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* It's also common to just return `false` in this case if the failing thing
|
||||
* is known to call SDL_SetError(), so errors simply propagate through.
|
||||
*/
|
||||
|
||||
#ifndef SDL_error_h_
|
||||
#define SDL_error_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
|
||||
|
||||
/* Public functions */
|
||||
|
||||
|
||||
/**
|
||||
* Set the SDL error message for the current thread.
|
||||
*
|
||||
* Calling this function will replace any previous error message that was set.
|
||||
*
|
||||
* This function always returns false, since SDL frequently uses false to
|
||||
* signify a failing result, leading to this idiom:
|
||||
*
|
||||
* ```c
|
||||
* if (error_code) {
|
||||
* return SDL_SetError("This operation has failed: %d", error_code);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* \param fmt a printf()-style message format string.
|
||||
* \param ... additional parameters matching % tokens in the `fmt` string, if
|
||||
* any.
|
||||
* \returns false.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_ClearError
|
||||
* \sa SDL_GetError
|
||||
* \sa SDL_SetErrorV
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
|
||||
|
||||
/**
|
||||
* Set the SDL error message for the current thread.
|
||||
*
|
||||
* Calling this function will replace any previous error message that was set.
|
||||
*
|
||||
* \param fmt a printf()-style message format string.
|
||||
* \param ap a variable argument list.
|
||||
* \returns false.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_ClearError
|
||||
* \sa SDL_GetError
|
||||
* \sa SDL_SetError
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(1);
|
||||
|
||||
/**
|
||||
* Set an error indicating that memory allocation failed.
|
||||
*
|
||||
* This function does not do any memory allocation.
|
||||
*
|
||||
* \returns false.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_OutOfMemory(void);
|
||||
|
||||
/**
|
||||
* Retrieve a message about the last error that occurred on the current
|
||||
* thread.
|
||||
*
|
||||
* It is possible for multiple errors to occur before calling SDL_GetError().
|
||||
* Only the last error is returned.
|
||||
*
|
||||
* The message is only applicable when an SDL function has signaled an error.
|
||||
* You must check the return values of SDL function calls to determine when to
|
||||
* appropriately call SDL_GetError(). You should *not* use the results of
|
||||
* SDL_GetError() to decide if an error has occurred! Sometimes SDL will set
|
||||
* an error string even when reporting success.
|
||||
*
|
||||
* SDL will *not* clear the error string for successful API calls. You *must*
|
||||
* check return values for failure cases before you can assume the error
|
||||
* string applies.
|
||||
*
|
||||
* Error strings are set per-thread, so an error set in a different thread
|
||||
* will not interfere with the current thread's operation.
|
||||
*
|
||||
* The returned value is a thread-local string which will remain valid until
|
||||
* the current thread's error string is changed. The caller should make a copy
|
||||
* if the value is needed after the next SDL API call.
|
||||
*
|
||||
* \returns a message with information about the specific error that occurred,
|
||||
* or an empty string if there hasn't been an error message set since
|
||||
* the last call to SDL_ClearError().
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_ClearError
|
||||
* \sa SDL_SetError
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetError(void);
|
||||
|
||||
/**
|
||||
* Clear any previous error message for this thread.
|
||||
*
|
||||
* \returns true.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetError
|
||||
* \sa SDL_SetError
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_ClearError(void);
|
||||
|
||||
/**
|
||||
* \name Internal error functions
|
||||
*
|
||||
* \internal
|
||||
* Private error reporting function - used internally.
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
/**
|
||||
* A macro to standardize error reporting on unsupported operations.
|
||||
*
|
||||
* This simply calls SDL_SetError() with a standardized error string, for
|
||||
* convenience, consistency, and clarity.
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_Unsupported() SDL_SetError("That operation is not supported")
|
||||
|
||||
/**
|
||||
* A macro to standardize error reporting on unsupported operations.
|
||||
*
|
||||
* This simply calls SDL_SetError() with a standardized error string, for
|
||||
* convenience, consistency, and clarity.
|
||||
*
|
||||
* A common usage pattern inside SDL is this:
|
||||
*
|
||||
* ```c
|
||||
* bool MyFunction(const char *str) {
|
||||
* if (!str) {
|
||||
* return SDL_InvalidParamError("str"); // returns false.
|
||||
* }
|
||||
* DoSomething(str);
|
||||
* return true;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* \threadsafety It is safe to call this macro from any thread.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param))
|
||||
|
||||
/* @} *//* Internal error functions */
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_error_h_ */
|
||||
-1576
File diff suppressed because it is too large
Load Diff
-503
@@ -1,503 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryFilesystem
|
||||
*
|
||||
* SDL offers an API for examining and manipulating the system's filesystem.
|
||||
* This covers most things one would need to do with directories, except for
|
||||
* actual file I/O (which is covered by [CategoryIOStream](CategoryIOStream)
|
||||
* and [CategoryAsyncIO](CategoryAsyncIO) instead).
|
||||
*
|
||||
* There are functions to answer necessary path questions:
|
||||
*
|
||||
* - Where is my app's data? SDL_GetBasePath().
|
||||
* - Where can I safely write files? SDL_GetPrefPath().
|
||||
* - Where are paths like Downloads, Desktop, Music? SDL_GetUserFolder().
|
||||
* - What is this thing at this location? SDL_GetPathInfo().
|
||||
* - What items live in this folder? SDL_EnumerateDirectory().
|
||||
* - What items live in this folder by wildcard? SDL_GlobDirectory().
|
||||
* - What is my current working directory? SDL_GetCurrentDirectory().
|
||||
*
|
||||
* SDL also offers functions to manipulate the directory tree: renaming,
|
||||
* removing, copying files.
|
||||
*/
|
||||
|
||||
#ifndef SDL_filesystem_h_
|
||||
#define SDL_filesystem_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the directory where the application was run from.
|
||||
*
|
||||
* SDL caches the result of this call internally, but the first call to this
|
||||
* function is not necessarily fast, so plan accordingly.
|
||||
*
|
||||
* **macOS and iOS Specific Functionality**: If the application is in a ".app"
|
||||
* bundle, this function returns the Resource directory (e.g.
|
||||
* MyApp.app/Contents/Resources/). This behaviour can be overridden by adding
|
||||
* a property to the Info.plist file. Adding a string key with the name
|
||||
* SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the
|
||||
* behaviour.
|
||||
*
|
||||
* Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an
|
||||
* application in /Applications/SDLApp/MyApp.app):
|
||||
*
|
||||
* - `resource`: bundle resource directory (the default). For example:
|
||||
* `/Applications/SDLApp/MyApp.app/Contents/Resources`
|
||||
* - `bundle`: the Bundle directory. For example:
|
||||
* `/Applications/SDLApp/MyApp.app/`
|
||||
* - `parent`: the containing directory of the bundle. For example:
|
||||
* `/Applications/SDLApp/`
|
||||
*
|
||||
* **Nintendo 3DS Specific Functionality**: This function returns "romfs"
|
||||
* directory of the application as it is uncommon to store resources outside
|
||||
* the executable. As such it is not a writable directory.
|
||||
*
|
||||
* The returned path is guaranteed to end with a path separator ('\\' on
|
||||
* Windows, '/' on most other platforms).
|
||||
*
|
||||
* \returns an absolute path in UTF-8 encoding to the application data
|
||||
* directory. NULL will be returned on error or when the platform
|
||||
* doesn't implement this functionality, call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetPrefPath
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetBasePath(void);
|
||||
|
||||
/**
|
||||
* Get the user-and-app-specific path where files can be written.
|
||||
*
|
||||
* Get the "pref dir". This is meant to be where users can write personal
|
||||
* files (preferences and save games, etc) that are specific to your
|
||||
* application. This directory is unique per user, per application.
|
||||
*
|
||||
* This function will decide the appropriate location in the native
|
||||
* filesystem, create the directory if necessary, and return a string of the
|
||||
* absolute path to the directory in UTF-8 encoding.
|
||||
*
|
||||
* On Windows, the string might look like:
|
||||
*
|
||||
* `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\`
|
||||
*
|
||||
* On Linux, the string might look like:
|
||||
*
|
||||
* `/home/bob/.local/share/My Program Name/`
|
||||
*
|
||||
* On macOS, the string might look like:
|
||||
*
|
||||
* `/Users/bob/Library/Application Support/My Program Name/`
|
||||
*
|
||||
* You should assume the path returned by this function is the only safe place
|
||||
* to write files (and that SDL_GetBasePath(), while it might be writable, or
|
||||
* even the parent of the returned path, isn't where you should be writing
|
||||
* things).
|
||||
*
|
||||
* Both the org and app strings may become part of a directory name, so please
|
||||
* follow these rules:
|
||||
*
|
||||
* - Try to use the same org string (_including case-sensitivity_) for all
|
||||
* your applications that use this function.
|
||||
* - Always use a unique app string for each one, and make sure it never
|
||||
* changes for an app once you've decided on it.
|
||||
* - Unicode characters are legal, as long as they are UTF-8 encoded, but...
|
||||
* - ...only use letters, numbers, and spaces. Avoid punctuation like "Game
|
||||
* Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient.
|
||||
*
|
||||
* The returned path is guaranteed to end with a path separator ('\\' on
|
||||
* Windows, '/' on most other platforms).
|
||||
*
|
||||
* \param org the name of your organization.
|
||||
* \param app the name of your application.
|
||||
* \returns a UTF-8 string of the user directory in platform-dependent
|
||||
* notation. NULL if there's a problem (creating directory failed,
|
||||
* etc.). This should be freed with SDL_free() when it is no longer
|
||||
* needed.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetBasePath
|
||||
*/
|
||||
extern SDL_DECLSPEC char * SDLCALL SDL_GetPrefPath(const char *org, const char *app);
|
||||
|
||||
/**
|
||||
* The type of the OS-provided default folder for a specific purpose.
|
||||
*
|
||||
* Note that the Trash folder isn't included here, because trashing files
|
||||
* usually involves extra OS-specific functionality to remember the file's
|
||||
* original location.
|
||||
*
|
||||
* The folders supported per platform are:
|
||||
*
|
||||
* | | Windows | macOS/iOS | tvOS | Unix (XDG) | Haiku | Emscripten |
|
||||
* | ----------- | ------- | --------- | ---- | ---------- | ----- | ---------- |
|
||||
* | HOME | X | X | | X | X | X |
|
||||
* | DESKTOP | X | X | | X | X | |
|
||||
* | DOCUMENTS | X | X | | X | | |
|
||||
* | DOWNLOADS | Vista+ | X | | X | | |
|
||||
* | MUSIC | X | X | | X | | |
|
||||
* | PICTURES | X | X | | X | | |
|
||||
* | PUBLICSHARE | | X | | X | | |
|
||||
* | SAVEDGAMES | Vista+ | | | | | |
|
||||
* | SCREENSHOTS | Vista+ | | | | | |
|
||||
* | TEMPLATES | X | X | | X | | |
|
||||
* | VIDEOS | X | X* | | X | | |
|
||||
*
|
||||
* Note that on macOS/iOS, the Videos folder is called "Movies".
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetUserFolder
|
||||
*/
|
||||
typedef enum SDL_Folder
|
||||
{
|
||||
SDL_FOLDER_HOME, /**< The folder which contains all of the current user's data, preferences, and documents. It usually contains most of the other folders. If a requested folder does not exist, the home folder can be considered a safe fallback to store a user's documents. */
|
||||
SDL_FOLDER_DESKTOP, /**< The folder of files that are displayed on the desktop. Note that the existence of a desktop folder does not guarantee that the system does show icons on its desktop; certain GNU/Linux distros with a graphical environment may not have desktop icons. */
|
||||
SDL_FOLDER_DOCUMENTS, /**< User document files, possibly application-specific. This is a good place to save a user's projects. */
|
||||
SDL_FOLDER_DOWNLOADS, /**< Standard folder for user files downloaded from the internet. */
|
||||
SDL_FOLDER_MUSIC, /**< Music files that can be played using a standard music player (mp3, ogg...). */
|
||||
SDL_FOLDER_PICTURES, /**< Image files that can be displayed using a standard viewer (png, jpg...). */
|
||||
SDL_FOLDER_PUBLICSHARE, /**< Files that are meant to be shared with other users on the same computer. */
|
||||
SDL_FOLDER_SAVEDGAMES, /**< Save files for games. */
|
||||
SDL_FOLDER_SCREENSHOTS, /**< Application screenshots. */
|
||||
SDL_FOLDER_TEMPLATES, /**< Template files to be used when the user requests the desktop environment to create a new file in a certain folder, such as "New Text File.txt". Any file in the Templates folder can be used as a starting point for a new file. */
|
||||
SDL_FOLDER_VIDEOS, /**< Video files that can be played using a standard video player (mp4, webm...). */
|
||||
SDL_FOLDER_COUNT /**< Total number of types in this enum, not a folder type by itself. */
|
||||
} SDL_Folder;
|
||||
|
||||
/**
|
||||
* Finds the most suitable user folder for a specific purpose.
|
||||
*
|
||||
* Many OSes provide certain standard folders for certain purposes, such as
|
||||
* storing pictures, music or videos for a certain user. This function gives
|
||||
* the path for many of those special locations.
|
||||
*
|
||||
* This function is specifically for _user_ folders, which are meant for the
|
||||
* user to access and manage. For application-specific folders, meant to hold
|
||||
* data for the application to manage, see SDL_GetBasePath() and
|
||||
* SDL_GetPrefPath().
|
||||
*
|
||||
* The returned path is guaranteed to end with a path separator ('\\' on
|
||||
* Windows, '/' on most other platforms).
|
||||
*
|
||||
* If NULL is returned, the error may be obtained with SDL_GetError().
|
||||
*
|
||||
* \param folder the type of folder to find.
|
||||
* \returns either a null-terminated C string containing the full path to the
|
||||
* folder, or NULL if an error happened.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetUserFolder(SDL_Folder folder);
|
||||
|
||||
|
||||
/* Abstract filesystem interface */
|
||||
|
||||
/**
|
||||
* Types of filesystem entries.
|
||||
*
|
||||
* Note that there may be other sorts of items on a filesystem: devices,
|
||||
* symlinks, named pipes, etc. They are currently reported as
|
||||
* SDL_PATHTYPE_OTHER.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_PathInfo
|
||||
*/
|
||||
typedef enum SDL_PathType
|
||||
{
|
||||
SDL_PATHTYPE_NONE, /**< path does not exist */
|
||||
SDL_PATHTYPE_FILE, /**< a normal file */
|
||||
SDL_PATHTYPE_DIRECTORY, /**< a directory */
|
||||
SDL_PATHTYPE_OTHER /**< something completely different like a device node (not a symlink, those are always followed) */
|
||||
} SDL_PathType;
|
||||
|
||||
/**
|
||||
* Information about a path on the filesystem.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GetPathInfo
|
||||
* \sa SDL_GetStoragePathInfo
|
||||
*/
|
||||
typedef struct SDL_PathInfo
|
||||
{
|
||||
SDL_PathType type; /**< the path type */
|
||||
Uint64 size; /**< the file size in bytes */
|
||||
SDL_Time create_time; /**< the time when the path was created */
|
||||
SDL_Time modify_time; /**< the last time the path was modified */
|
||||
SDL_Time access_time; /**< the last time the path was read */
|
||||
} SDL_PathInfo;
|
||||
|
||||
/**
|
||||
* Flags for path matching.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GlobDirectory
|
||||
* \sa SDL_GlobStorageDirectory
|
||||
*/
|
||||
typedef Uint32 SDL_GlobFlags;
|
||||
|
||||
#define SDL_GLOB_CASEINSENSITIVE (1u << 0)
|
||||
|
||||
/**
|
||||
* Create a directory, and any missing parent directories.
|
||||
*
|
||||
* This reports success if `path` already exists as a directory.
|
||||
*
|
||||
* If parent directories are missing, it will also create them. Note that if
|
||||
* this fails, it will not remove any parent directories it already made.
|
||||
*
|
||||
* \param path the path of the directory to create.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_CreateDirectory(const char *path);
|
||||
|
||||
/**
|
||||
* Possible results from an enumeration callback.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_EnumerateDirectoryCallback
|
||||
*/
|
||||
typedef enum SDL_EnumerationResult
|
||||
{
|
||||
SDL_ENUM_CONTINUE, /**< Value that requests that enumeration continue. */
|
||||
SDL_ENUM_SUCCESS, /**< Value that requests that enumeration stop, successfully. */
|
||||
SDL_ENUM_FAILURE /**< Value that requests that enumeration stop, as a failure. */
|
||||
} SDL_EnumerationResult;
|
||||
|
||||
/**
|
||||
* Callback for directory enumeration.
|
||||
*
|
||||
* Enumeration of directory entries will continue until either all entries
|
||||
* have been provided to the callback, or the callback has requested a stop
|
||||
* through its return value.
|
||||
*
|
||||
* Returning SDL_ENUM_CONTINUE will let enumeration proceed, calling the
|
||||
* callback with further entries. SDL_ENUM_SUCCESS and SDL_ENUM_FAILURE will
|
||||
* terminate the enumeration early, and dictate the return value of the
|
||||
* enumeration function itself.
|
||||
*
|
||||
* `dirname` is guaranteed to end with a path separator ('\\' on Windows, '/'
|
||||
* on most other platforms).
|
||||
*
|
||||
* \param userdata an app-controlled pointer that is passed to the callback.
|
||||
* \param dirname the directory that is being enumerated.
|
||||
* \param fname the next entry in the enumeration.
|
||||
* \returns how the enumeration should proceed.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_EnumerateDirectory
|
||||
*/
|
||||
typedef SDL_EnumerationResult (SDLCALL *SDL_EnumerateDirectoryCallback)(void *userdata, const char *dirname, const char *fname);
|
||||
|
||||
/**
|
||||
* Enumerate a directory through a callback function.
|
||||
*
|
||||
* This function provides every directory entry through an app-provided
|
||||
* callback, called once for each directory entry, until all results have been
|
||||
* provided or the callback returns either SDL_ENUM_SUCCESS or
|
||||
* SDL_ENUM_FAILURE.
|
||||
*
|
||||
* This will return false if there was a system problem in general, or if a
|
||||
* callback returns SDL_ENUM_FAILURE. A successful return means a callback
|
||||
* returned SDL_ENUM_SUCCESS to halt enumeration, or all directory entries
|
||||
* were enumerated.
|
||||
*
|
||||
* \param path the path of the directory to enumerate.
|
||||
* \param callback a function that is called for each entry in the directory.
|
||||
* \param userdata a pointer that is passed to `callback`.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_EnumerateDirectory(const char *path, SDL_EnumerateDirectoryCallback callback, void *userdata);
|
||||
|
||||
/**
|
||||
* Remove a file or an empty directory.
|
||||
*
|
||||
* Directories that are not empty will fail; this function will not recursely
|
||||
* delete directory trees.
|
||||
*
|
||||
* \param path the path to remove from the filesystem.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_RemovePath(const char *path);
|
||||
|
||||
/**
|
||||
* Rename a file or directory.
|
||||
*
|
||||
* If the file at `newpath` already exists, it will replaced.
|
||||
*
|
||||
* Note that this will not copy files across filesystems/drives/volumes, as
|
||||
* that is a much more complicated (and possibly time-consuming) operation.
|
||||
*
|
||||
* Which is to say, if this function fails, SDL_CopyFile() to a temporary file
|
||||
* in the same directory as `newpath`, then SDL_RenamePath() from the
|
||||
* temporary file to `newpath` and SDL_RemovePath() on `oldpath` might work
|
||||
* for files. Renaming a non-empty directory across filesystems is
|
||||
* dramatically more complex, however.
|
||||
*
|
||||
* \param oldpath the old path.
|
||||
* \param newpath the new path.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_RenamePath(const char *oldpath, const char *newpath);
|
||||
|
||||
/**
|
||||
* Copy a file.
|
||||
*
|
||||
* If the file at `newpath` already exists, it will be overwritten with the
|
||||
* contents of the file at `oldpath`.
|
||||
*
|
||||
* This function will block until the copy is complete, which might be a
|
||||
* significant time for large files on slow disks. On some platforms, the copy
|
||||
* can be handed off to the OS itself, but on others SDL might just open both
|
||||
* paths, and read from one and write to the other.
|
||||
*
|
||||
* Note that this is not an atomic operation! If something tries to read from
|
||||
* `newpath` while the copy is in progress, it will see an incomplete copy of
|
||||
* the data, and if the calling thread terminates (or the power goes out)
|
||||
* during the copy, `newpath`'s previous contents will be gone, replaced with
|
||||
* an incomplete copy of the data. To avoid this risk, it is recommended that
|
||||
* the app copy to a temporary file in the same directory as `newpath`, and if
|
||||
* the copy is successful, use SDL_RenamePath() to replace `newpath` with the
|
||||
* temporary file. This will ensure that reads of `newpath` will either see a
|
||||
* complete copy of the data, or it will see the pre-copy state of `newpath`.
|
||||
*
|
||||
* This function attempts to synchronize the newly-copied data to disk before
|
||||
* returning, if the platform allows it, so that the renaming trick will not
|
||||
* have a problem in a system crash or power failure, where the file could be
|
||||
* renamed but the contents never made it from the system file cache to the
|
||||
* physical disk.
|
||||
*
|
||||
* If the copy fails for any reason, the state of `newpath` is undefined. It
|
||||
* might be half a copy, it might be the untouched data of what was already
|
||||
* there, or it might be a zero-byte file, etc.
|
||||
*
|
||||
* \param oldpath the old path.
|
||||
* \param newpath the new path.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_CopyFile(const char *oldpath, const char *newpath);
|
||||
|
||||
/**
|
||||
* Get information about a filesystem path.
|
||||
*
|
||||
* \param path the path to query.
|
||||
* \param info a pointer filled in with information about the path, or NULL to
|
||||
* check for the existence of a file.
|
||||
* \returns true on success or false if the file doesn't exist, or another
|
||||
* failure; call SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_GetPathInfo(const char *path, SDL_PathInfo *info);
|
||||
|
||||
/**
|
||||
* Enumerate a directory tree, filtered by pattern, and return a list.
|
||||
*
|
||||
* Files are filtered out if they don't match the string in `pattern`, which
|
||||
* may contain wildcard characters '\*' (match everything) and '?' (match one
|
||||
* character). If pattern is NULL, no filtering is done and all results are
|
||||
* returned. Subdirectories are permitted, and are specified with a path
|
||||
* separator of '/'. Wildcard characters '\*' and '?' never match a path
|
||||
* separator.
|
||||
*
|
||||
* `flags` may be set to SDL_GLOB_CASEINSENSITIVE to make the pattern matching
|
||||
* case-insensitive.
|
||||
*
|
||||
* The returned array is always NULL-terminated, for your iterating
|
||||
* convenience, but if `count` is non-NULL, on return it will contain the
|
||||
* number of items in the array, not counting the NULL terminator.
|
||||
*
|
||||
* \param path the path of the directory to enumerate.
|
||||
* \param pattern the pattern that files in the directory must match. Can be
|
||||
* NULL.
|
||||
* \param flags `SDL_GLOB_*` bitflags that affect this search.
|
||||
* \param count on return, will be set to the number of items in the returned
|
||||
* array. Can be NULL.
|
||||
* \returns an array of strings on success or NULL on failure; call
|
||||
* SDL_GetError() for more information. This is a single allocation
|
||||
* that should be freed with SDL_free() when it is no longer needed.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC char ** SDLCALL SDL_GlobDirectory(const char *path, const char *pattern, SDL_GlobFlags flags, int *count);
|
||||
|
||||
/**
|
||||
* Get what the system believes is the "current working directory."
|
||||
*
|
||||
* For systems without a concept of a current working directory, this will
|
||||
* still attempt to provide something reasonable.
|
||||
*
|
||||
* SDL does not provide a means to _change_ the current working directory; for
|
||||
* platforms without this concept, this would cause surprises with file access
|
||||
* outside of SDL.
|
||||
*
|
||||
* The returned path is guaranteed to end with a path separator ('\\' on
|
||||
* Windows, '/' on most other platforms).
|
||||
*
|
||||
* \returns a UTF-8 string of the current working directory in
|
||||
* platform-dependent notation. NULL if there's a problem. This
|
||||
* should be freed with SDL_free() when it is no longer needed.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC char * SDLCALL SDL_GetCurrentDirectory(void);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_filesystem_h_ */
|
||||
-1509
File diff suppressed because it is too large
Load Diff
-4213
File diff suppressed because it is too large
Load Diff
-106
@@ -1,106 +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: GUID */
|
||||
|
||||
/**
|
||||
* # CategoryGUID
|
||||
*
|
||||
* A GUID is a 128-bit value that represents something that is uniquely
|
||||
* identifiable by this value: "globally unique."
|
||||
*
|
||||
* SDL provides functions to convert a GUID to/from a string.
|
||||
*/
|
||||
|
||||
#ifndef SDL_guid_h_
|
||||
#define SDL_guid_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
|
||||
|
||||
/**
|
||||
* An SDL_GUID is a 128-bit identifier for an input device that identifies
|
||||
* that device across runs of SDL programs on the same platform.
|
||||
*
|
||||
* If the device is detached and then re-attached to a different port, or if
|
||||
* the base system is rebooted, the device should still report the same GUID.
|
||||
*
|
||||
* GUIDs are as precise as possible but are not guaranteed to distinguish
|
||||
* physically distinct but equivalent devices. For example, two game
|
||||
* controllers from the same vendor with the same product ID and revision may
|
||||
* have the same GUID.
|
||||
*
|
||||
* GUIDs may be platform-dependent (i.e., the same device may report different
|
||||
* GUIDs on different operating systems).
|
||||
*
|
||||
* \since This struct is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef struct SDL_GUID {
|
||||
Uint8 data[16];
|
||||
} SDL_GUID;
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
/**
|
||||
* Get an ASCII string representation for a given SDL_GUID.
|
||||
*
|
||||
* \param guid the SDL_GUID you wish to convert to string.
|
||||
* \param pszGUID buffer in which to write the ASCII string.
|
||||
* \param cbGUID the size of pszGUID, should be at least 33 bytes.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_StringToGUID
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID);
|
||||
|
||||
/**
|
||||
* Convert a GUID string into a SDL_GUID structure.
|
||||
*
|
||||
* Performs no error checking. If this function is given a string containing
|
||||
* an invalid GUID, the function will silently succeed, but the GUID generated
|
||||
* will not be useful.
|
||||
*
|
||||
* \param pchGUID string containing an ASCII representation of a GUID.
|
||||
* \returns a SDL_GUID structure.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_GUIDToString
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_GUID SDLCALL SDL_StringToGUID(const char *pchGUID);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_guid_h_ */
|
||||
-1441
File diff suppressed because it is too large
Load Diff
-552
@@ -1,552 +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: HIDAPI */
|
||||
|
||||
/**
|
||||
* # CategoryHIDAPI
|
||||
*
|
||||
* Header file for SDL HIDAPI functions.
|
||||
*
|
||||
* This is an adaptation of the original HIDAPI interface by Alan Ott, and
|
||||
* includes source code licensed under the following license:
|
||||
*
|
||||
* ```
|
||||
* HIDAPI - Multi-Platform library for
|
||||
* communication with HID devices.
|
||||
*
|
||||
* Copyright 2009, Alan Ott, Signal 11 Software.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This software may be used by anyone for any reason so
|
||||
* long as the copyright notice in the source files
|
||||
* remains intact.
|
||||
* ```
|
||||
*
|
||||
* (Note that this license is the same as item three of SDL's zlib license, so
|
||||
* it adds no new requirements on the user.)
|
||||
*
|
||||
* If you would like a version of SDL without this code, you can build SDL
|
||||
* with SDL_HIDAPI_DISABLED defined to 1. You might want to do this for
|
||||
* example on iOS or tvOS to avoid a dependency on the CoreBluetooth
|
||||
* framework.
|
||||
*/
|
||||
|
||||
#ifndef SDL_hidapi_h_
|
||||
#define SDL_hidapi_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An opaque handle representing an open HID device.
|
||||
*
|
||||
* \since This struct is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef struct SDL_hid_device SDL_hid_device;
|
||||
|
||||
/**
|
||||
* HID underlying bus types.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef enum SDL_hid_bus_type {
|
||||
/** Unknown bus type */
|
||||
SDL_HID_API_BUS_UNKNOWN = 0x00,
|
||||
|
||||
/** USB bus
|
||||
Specifications:
|
||||
https://usb.org/hid */
|
||||
SDL_HID_API_BUS_USB = 0x01,
|
||||
|
||||
/** Bluetooth or Bluetooth LE bus
|
||||
Specifications:
|
||||
https://www.bluetooth.com/specifications/specs/human-interface-device-profile-1-1-1/
|
||||
https://www.bluetooth.com/specifications/specs/hid-service-1-0/
|
||||
https://www.bluetooth.com/specifications/specs/hid-over-gatt-profile-1-0/ */
|
||||
SDL_HID_API_BUS_BLUETOOTH = 0x02,
|
||||
|
||||
/** I2C bus
|
||||
Specifications:
|
||||
https://docs.microsoft.com/previous-versions/windows/hardware/design/dn642101(v=vs.85) */
|
||||
SDL_HID_API_BUS_I2C = 0x03,
|
||||
|
||||
/** SPI bus
|
||||
Specifications:
|
||||
https://www.microsoft.com/download/details.aspx?id=103325 */
|
||||
SDL_HID_API_BUS_SPI = 0x04
|
||||
|
||||
} SDL_hid_bus_type;
|
||||
|
||||
/** hidapi info structure */
|
||||
|
||||
/**
|
||||
* Information about a connected HID device
|
||||
*
|
||||
* \since This struct is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef struct SDL_hid_device_info
|
||||
{
|
||||
/** Platform-specific device path */
|
||||
char *path;
|
||||
/** Device Vendor ID */
|
||||
unsigned short vendor_id;
|
||||
/** Device Product ID */
|
||||
unsigned short product_id;
|
||||
/** Serial Number */
|
||||
wchar_t *serial_number;
|
||||
/** Device Release Number in binary-coded decimal,
|
||||
also known as Device Version Number */
|
||||
unsigned short release_number;
|
||||
/** Manufacturer String */
|
||||
wchar_t *manufacturer_string;
|
||||
/** Product string */
|
||||
wchar_t *product_string;
|
||||
/** Usage Page for this Device/Interface
|
||||
(Windows/Mac/hidraw only) */
|
||||
unsigned short usage_page;
|
||||
/** Usage for this Device/Interface
|
||||
(Windows/Mac/hidraw only) */
|
||||
unsigned short usage;
|
||||
/** The USB interface which this logical device
|
||||
represents.
|
||||
|
||||
Valid only if the device is a USB HID device.
|
||||
Set to -1 in all other cases.
|
||||
*/
|
||||
int interface_number;
|
||||
|
||||
/** Additional information about the USB interface.
|
||||
Valid on libusb and Android implementations. */
|
||||
int interface_class;
|
||||
int interface_subclass;
|
||||
int interface_protocol;
|
||||
|
||||
/** Underlying bus type */
|
||||
SDL_hid_bus_type bus_type;
|
||||
|
||||
/** Pointer to the next device */
|
||||
struct SDL_hid_device_info *next;
|
||||
|
||||
} SDL_hid_device_info;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the HIDAPI library.
|
||||
*
|
||||
* This function initializes the HIDAPI library. Calling it is not strictly
|
||||
* necessary, as it will be called automatically by SDL_hid_enumerate() and
|
||||
* any of the SDL_hid_open_*() functions if it is needed. This function should
|
||||
* be called at the beginning of execution however, if there is a chance of
|
||||
* HIDAPI handles being opened by different threads simultaneously.
|
||||
*
|
||||
* Each call to this function should have a matching call to SDL_hid_exit()
|
||||
*
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_hid_exit
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_init(void);
|
||||
|
||||
/**
|
||||
* Finalize the HIDAPI library.
|
||||
*
|
||||
* This function frees all of the static data associated with HIDAPI. It
|
||||
* should be called at the end of execution to avoid memory leaks.
|
||||
*
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_hid_init
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_exit(void);
|
||||
|
||||
/**
|
||||
* Check to see if devices may have been added or removed.
|
||||
*
|
||||
* Enumerating the HID devices is an expensive operation, so you can call this
|
||||
* to see if there have been any system device changes since the last call to
|
||||
* this function. A change in the counter returned doesn't necessarily mean
|
||||
* that anything has changed, but you can call SDL_hid_enumerate() to get an
|
||||
* updated device list.
|
||||
*
|
||||
* Calling this function for the first time may cause a thread or other system
|
||||
* resource to be allocated to track device change notifications.
|
||||
*
|
||||
* \returns a change counter that is incremented with each potential device
|
||||
* change, or 0 if device change detection isn't available.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_hid_enumerate
|
||||
*/
|
||||
extern SDL_DECLSPEC Uint32 SDLCALL SDL_hid_device_change_count(void);
|
||||
|
||||
/**
|
||||
* Enumerate the HID Devices.
|
||||
*
|
||||
* This function returns a linked list of all the HID devices attached to the
|
||||
* system which match vendor_id and product_id. If `vendor_id` is set to 0
|
||||
* then any vendor matches. If `product_id` is set to 0 then any product
|
||||
* matches. If `vendor_id` and `product_id` are both set to 0, then all HID
|
||||
* devices will be returned.
|
||||
*
|
||||
* By default SDL will only enumerate controllers, to reduce risk of hanging
|
||||
* or crashing on bad drivers, but SDL_HINT_HIDAPI_ENUMERATE_ONLY_CONTROLLERS
|
||||
* can be set to "0" to enumerate all HID devices.
|
||||
*
|
||||
* \param vendor_id the Vendor ID (VID) of the types of device to open, or 0
|
||||
* to match any vendor.
|
||||
* \param product_id the Product ID (PID) of the types of device to open, or 0
|
||||
* to match any product.
|
||||
* \returns a pointer to a linked list of type SDL_hid_device_info, containing
|
||||
* information about the HID devices attached to the system, or NULL
|
||||
* in the case of failure. Free this linked list by calling
|
||||
* SDL_hid_free_enumeration().
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_hid_device_change_count
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id);
|
||||
|
||||
/**
|
||||
* Free an enumeration linked list.
|
||||
*
|
||||
* This function frees a linked list created by SDL_hid_enumerate().
|
||||
*
|
||||
* \param devs pointer to a list of struct_device returned from
|
||||
* SDL_hid_enumerate().
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_hid_free_enumeration(SDL_hid_device_info *devs);
|
||||
|
||||
/**
|
||||
* Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally
|
||||
* a serial number.
|
||||
*
|
||||
* If `serial_number` is NULL, the first device with the specified VID and PID
|
||||
* is opened.
|
||||
*
|
||||
* \param vendor_id the Vendor ID (VID) of the device to open.
|
||||
* \param product_id the Product ID (PID) of the device to open.
|
||||
* \param serial_number the Serial Number of the device to open (Optionally
|
||||
* NULL).
|
||||
* \returns a pointer to a SDL_hid_device object on success or NULL on
|
||||
* failure; call SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number);
|
||||
|
||||
/**
|
||||
* Open a HID device by its path name.
|
||||
*
|
||||
* The path name be determined by calling SDL_hid_enumerate(), or a
|
||||
* platform-specific path name can be used (eg: /dev/hidraw0 on Linux).
|
||||
*
|
||||
* \param path the path name of the device to open.
|
||||
* \returns a pointer to a SDL_hid_device object on success or NULL on
|
||||
* failure; call SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path);
|
||||
|
||||
/**
|
||||
* Write an Output report to a HID device.
|
||||
*
|
||||
* The first byte of `data` must contain the Report ID. For devices which only
|
||||
* support a single report, this must be set to 0x0. The remaining bytes
|
||||
* contain the report data. Since the Report ID is mandatory, calls to
|
||||
* SDL_hid_write() will always contain one more byte than the report contains.
|
||||
* For example, if a hid report is 16 bytes long, 17 bytes must be passed to
|
||||
* SDL_hid_write(), the Report ID (or 0x0, for devices with a single report),
|
||||
* followed by the report data (16 bytes). In this example, the length passed
|
||||
* in would be 17.
|
||||
*
|
||||
* SDL_hid_write() will send the data on the first OUT endpoint, if one
|
||||
* exists. If it does not, it will send the data through the Control Endpoint
|
||||
* (Endpoint 0).
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param data the data to send, including the report number as the first
|
||||
* byte.
|
||||
* \param length the length in bytes of the data to send.
|
||||
* \returns the actual number of bytes written and -1 on on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_write(SDL_hid_device *dev, const unsigned char *data, size_t length);
|
||||
|
||||
/**
|
||||
* Read an Input report from a HID device with timeout.
|
||||
*
|
||||
* Input reports are returned to the host through the INTERRUPT IN endpoint.
|
||||
* The first byte will contain the Report number if the device uses numbered
|
||||
* reports.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param data a buffer to put the read data into.
|
||||
* \param length the number of bytes to read. For devices with multiple
|
||||
* reports, make sure to read an extra byte for the report
|
||||
* number.
|
||||
* \param milliseconds timeout in milliseconds or -1 for blocking wait.
|
||||
* \returns the actual number of bytes read and -1 on on failure; call
|
||||
* SDL_GetError() for more information. If no packet was available to
|
||||
* be read within the timeout period, this function returns 0.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_read_timeout(SDL_hid_device *dev, unsigned char *data, size_t length, int milliseconds);
|
||||
|
||||
/**
|
||||
* Read an Input report from a HID device.
|
||||
*
|
||||
* Input reports are returned to the host through the INTERRUPT IN endpoint.
|
||||
* The first byte will contain the Report number if the device uses numbered
|
||||
* reports.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param data a buffer to put the read data into.
|
||||
* \param length the number of bytes to read. For devices with multiple
|
||||
* reports, make sure to read an extra byte for the report
|
||||
* number.
|
||||
* \returns the actual number of bytes read and -1 on failure; call
|
||||
* SDL_GetError() for more information. If no packet was available to
|
||||
* be read and the handle is in non-blocking mode, this function
|
||||
* returns 0.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_read(SDL_hid_device *dev, unsigned char *data, size_t length);
|
||||
|
||||
/**
|
||||
* Set the device handle to be non-blocking.
|
||||
*
|
||||
* In non-blocking mode calls to SDL_hid_read() will return immediately with a
|
||||
* value of 0 if there is no data to be read. In blocking mode, SDL_hid_read()
|
||||
* will wait (block) until there is data to read before returning.
|
||||
*
|
||||
* Nonblocking can be turned on and off at any time.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param nonblock enable or not the nonblocking reads - 1 to enable
|
||||
* nonblocking - 0 to disable nonblocking.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_set_nonblocking(SDL_hid_device *dev, int nonblock);
|
||||
|
||||
/**
|
||||
* Send a Feature report to the device.
|
||||
*
|
||||
* Feature reports are sent over the Control endpoint as a Set_Report
|
||||
* transfer. The first byte of `data` must contain the Report ID. For devices
|
||||
* which only support a single report, this must be set to 0x0. The remaining
|
||||
* bytes contain the report data. Since the Report ID is mandatory, calls to
|
||||
* SDL_hid_send_feature_report() will always contain one more byte than the
|
||||
* report contains. For example, if a hid report is 16 bytes long, 17 bytes
|
||||
* must be passed to SDL_hid_send_feature_report(): the Report ID (or 0x0, for
|
||||
* devices which do not use numbered reports), followed by the report data (16
|
||||
* bytes). In this example, the length passed in would be 17.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param data the data to send, including the report number as the first
|
||||
* byte.
|
||||
* \param length the length in bytes of the data to send, including the report
|
||||
* number.
|
||||
* \returns the actual number of bytes written and -1 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_send_feature_report(SDL_hid_device *dev, const unsigned char *data, size_t length);
|
||||
|
||||
/**
|
||||
* Get a feature report from a HID device.
|
||||
*
|
||||
* Set the first byte of `data` to the Report ID of the report to be read.
|
||||
* Make sure to allow space for this extra byte in `data`. Upon return, the
|
||||
* first byte will still contain the Report ID, and the report data will start
|
||||
* in data[1].
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param data a buffer to put the read data into, including the Report ID.
|
||||
* Set the first byte of `data` to the Report ID of the report to
|
||||
* be read, or set it to zero if your device does not use numbered
|
||||
* reports.
|
||||
* \param length the number of bytes to read, including an extra byte for the
|
||||
* report ID. The buffer can be longer than the actual report.
|
||||
* \returns the number of bytes read plus one for the report ID (which is
|
||||
* still in the first byte), or -1 on on failure; call SDL_GetError()
|
||||
* for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_get_feature_report(SDL_hid_device *dev, unsigned char *data, size_t length);
|
||||
|
||||
/**
|
||||
* Get an input report from a HID device.
|
||||
*
|
||||
* Set the first byte of `data` to the Report ID of the report to be read.
|
||||
* Make sure to allow space for this extra byte in `data`. Upon return, the
|
||||
* first byte will still contain the Report ID, and the report data will start
|
||||
* in data[1].
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param data a buffer to put the read data into, including the Report ID.
|
||||
* Set the first byte of `data` to the Report ID of the report to
|
||||
* be read, or set it to zero if your device does not use numbered
|
||||
* reports.
|
||||
* \param length the number of bytes to read, including an extra byte for the
|
||||
* report ID. The buffer can be longer than the actual report.
|
||||
* \returns the number of bytes read plus one for the report ID (which is
|
||||
* still in the first byte), or -1 on on failure; call SDL_GetError()
|
||||
* for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_get_input_report(SDL_hid_device *dev, unsigned char *data, size_t length);
|
||||
|
||||
/**
|
||||
* Close a HID device.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_close(SDL_hid_device *dev);
|
||||
|
||||
/**
|
||||
* Get The Manufacturer String from a HID device.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param string a wide string buffer to put the data into.
|
||||
* \param maxlen the length of the buffer in multiples of wchar_t.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_get_manufacturer_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen);
|
||||
|
||||
/**
|
||||
* Get The Product String from a HID device.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param string a wide string buffer to put the data into.
|
||||
* \param maxlen the length of the buffer in multiples of wchar_t.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_get_product_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen);
|
||||
|
||||
/**
|
||||
* Get The Serial Number String from a HID device.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param string a wide string buffer to put the data into.
|
||||
* \param maxlen the length of the buffer in multiples of wchar_t.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_get_serial_number_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen);
|
||||
|
||||
/**
|
||||
* Get a string from a HID device, based on its string index.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param string_index the index of the string to get.
|
||||
* \param string a wide string buffer to put the data into.
|
||||
* \param maxlen the length of the buffer in multiples of wchar_t.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_get_indexed_string(SDL_hid_device *dev, int string_index, wchar_t *string, size_t maxlen);
|
||||
|
||||
/**
|
||||
* Get the device info from a HID device.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \returns a pointer to the SDL_hid_device_info for this hid_device or NULL
|
||||
* on failure; call SDL_GetError() for more information. This struct
|
||||
* is valid until the device is closed with SDL_hid_close().
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_get_device_info(SDL_hid_device *dev);
|
||||
|
||||
/**
|
||||
* Get a report descriptor from a HID device.
|
||||
*
|
||||
* User has to provide a preallocated buffer where descriptor will be copied
|
||||
* to. The recommended size for a preallocated buffer is 4096 bytes.
|
||||
*
|
||||
* \param dev a device handle returned from SDL_hid_open().
|
||||
* \param buf the buffer to copy descriptor into.
|
||||
* \param buf_size the size of the buffer in bytes.
|
||||
* \returns the number of bytes actually copied or -1 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_hid_get_report_descriptor(SDL_hid_device *dev, unsigned char *buf, size_t buf_size);
|
||||
|
||||
/**
|
||||
* Start or stop a BLE scan on iOS and tvOS to pair Steam Controllers.
|
||||
*
|
||||
* \param active true to start the scan, false to stop the scan.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_hid_ble_scan(bool active);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_hidapi_h_ */
|
||||
-4486
File diff suppressed because it is too large
Load Diff
-497
@@ -1,497 +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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* # CategoryInit
|
||||
*
|
||||
* All SDL programs need to initialize the library before starting to work
|
||||
* with it.
|
||||
*
|
||||
* Almost everything can simply call SDL_Init() near startup, with a handful
|
||||
* of flags to specify subsystems to touch. These are here to make sure SDL
|
||||
* does not even attempt to touch low-level pieces of the operating system
|
||||
* that you don't intend to use. For example, you might be using SDL for video
|
||||
* and input but chose an external library for audio, and in this case you
|
||||
* would just need to leave off the `SDL_INIT_AUDIO` flag to make sure that
|
||||
* external library has complete control.
|
||||
*
|
||||
* Most apps, when terminating, should call SDL_Quit(). This will clean up
|
||||
* (nearly) everything that SDL might have allocated, and crucially, it'll
|
||||
* make sure that the display's resolution is back to what the user expects if
|
||||
* you had previously changed it for your game.
|
||||
*
|
||||
* SDL3 apps are strongly encouraged to call SDL_SetAppMetadata() at startup
|
||||
* to fill in details about the program. This is completely optional, but it
|
||||
* helps in small ways (we can provide an About dialog box for the macOS menu,
|
||||
* we can name the app in the system's audio mixer, etc). Those that want to
|
||||
* provide a _lot_ of information should look at the more-detailed
|
||||
* SDL_SetAppMetadataProperty().
|
||||
*/
|
||||
|
||||
#ifndef SDL_init_h_
|
||||
#define SDL_init_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_events.h>
|
||||
|
||||
#include <SDL3/SDL_begin_code.h>
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* As of version 0.5, SDL is loaded dynamically into the application */
|
||||
|
||||
/**
|
||||
* Initialization flags for SDL_Init and/or SDL_InitSubSystem
|
||||
*
|
||||
* These are the flags which may be passed to SDL_Init(). You should specify
|
||||
* the subsystems which you will be using in your application.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_Init
|
||||
* \sa SDL_Quit
|
||||
* \sa SDL_InitSubSystem
|
||||
* \sa SDL_QuitSubSystem
|
||||
* \sa SDL_WasInit
|
||||
*/
|
||||
typedef Uint32 SDL_InitFlags;
|
||||
|
||||
#define SDL_INIT_AUDIO 0x00000010u /**< `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS` */
|
||||
#define SDL_INIT_VIDEO 0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread */
|
||||
#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS` */
|
||||
#define SDL_INIT_HAPTIC 0x00001000u
|
||||
#define SDL_INIT_GAMEPAD 0x00002000u /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */
|
||||
#define SDL_INIT_EVENTS 0x00004000u
|
||||
#define SDL_INIT_SENSOR 0x00008000u /**< `SDL_INIT_SENSOR` implies `SDL_INIT_EVENTS` */
|
||||
#define SDL_INIT_CAMERA 0x00010000u /**< `SDL_INIT_CAMERA` implies `SDL_INIT_EVENTS` */
|
||||
|
||||
/**
|
||||
* Return values for optional main callbacks.
|
||||
*
|
||||
* Returning SDL_APP_SUCCESS or SDL_APP_FAILURE from SDL_AppInit,
|
||||
* SDL_AppEvent, or SDL_AppIterate will terminate the program and report
|
||||
* success/failure to the operating system. What that means is
|
||||
* platform-dependent. On Unix, for example, on success, the process error
|
||||
* code will be zero, and on failure it will be 1. This interface doesn't
|
||||
* allow you to return specific exit codes, just whether there was an error
|
||||
* generally or not.
|
||||
*
|
||||
* Returning SDL_APP_CONTINUE from these functions will let the app continue
|
||||
* to run.
|
||||
*
|
||||
* See
|
||||
* [Main callbacks in SDL3](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3)
|
||||
* for complete details.
|
||||
*
|
||||
* \since This enum is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef enum SDL_AppResult
|
||||
{
|
||||
SDL_APP_CONTINUE, /**< Value that requests that the app continue from the main callbacks. */
|
||||
SDL_APP_SUCCESS, /**< Value that requests termination with success from the main callbacks. */
|
||||
SDL_APP_FAILURE /**< Value that requests termination with error from the main callbacks. */
|
||||
} SDL_AppResult;
|
||||
|
||||
/**
|
||||
* Function pointer typedef for SDL_AppInit.
|
||||
*
|
||||
* These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
|
||||
* the scenes for apps using the optional main callbacks. Apps that want to
|
||||
* use this should just implement SDL_AppInit directly.
|
||||
*
|
||||
* \param appstate a place where the app can optionally store a pointer for
|
||||
* future use.
|
||||
* \param argc the standard ANSI C main's argc; number of elements in `argv`.
|
||||
* \param argv the standard ANSI C main's argv; array of command line
|
||||
* arguments.
|
||||
* \returns SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
|
||||
* terminate with success, SDL_APP_CONTINUE to continue.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef SDL_AppResult (SDLCALL *SDL_AppInit_func)(void **appstate, int argc, char *argv[]);
|
||||
|
||||
/**
|
||||
* Function pointer typedef for SDL_AppIterate.
|
||||
*
|
||||
* These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
|
||||
* the scenes for apps using the optional main callbacks. Apps that want to
|
||||
* use this should just implement SDL_AppIterate directly.
|
||||
*
|
||||
* \param appstate an optional pointer, provided by the app in SDL_AppInit.
|
||||
* \returns SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
|
||||
* terminate with success, SDL_APP_CONTINUE to continue.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef SDL_AppResult (SDLCALL *SDL_AppIterate_func)(void *appstate);
|
||||
|
||||
/**
|
||||
* Function pointer typedef for SDL_AppEvent.
|
||||
*
|
||||
* These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
|
||||
* the scenes for apps using the optional main callbacks. Apps that want to
|
||||
* use this should just implement SDL_AppEvent directly.
|
||||
*
|
||||
* \param appstate an optional pointer, provided by the app in SDL_AppInit.
|
||||
* \param event the new event for the app to examine.
|
||||
* \returns SDL_APP_FAILURE to terminate with an error, SDL_APP_SUCCESS to
|
||||
* terminate with success, SDL_APP_CONTINUE to continue.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef SDL_AppResult (SDLCALL *SDL_AppEvent_func)(void *appstate, SDL_Event *event);
|
||||
|
||||
/**
|
||||
* Function pointer typedef for SDL_AppQuit.
|
||||
*
|
||||
* These are used by SDL_EnterAppMainCallbacks. This mechanism operates behind
|
||||
* the scenes for apps using the optional main callbacks. Apps that want to
|
||||
* use this should just implement SDL_AppEvent directly.
|
||||
*
|
||||
* \param appstate an optional pointer, provided by the app in SDL_AppInit.
|
||||
* \param result the result code that terminated the app (success or failure).
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*/
|
||||
typedef void (SDLCALL *SDL_AppQuit_func)(void *appstate, SDL_AppResult result);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the SDL library.
|
||||
*
|
||||
* SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the
|
||||
* two may be used interchangeably. Though for readability of your code
|
||||
* SDL_InitSubSystem() might be preferred.
|
||||
*
|
||||
* The file I/O (for example: SDL_IOFromFile) and threading (SDL_CreateThread)
|
||||
* subsystems are initialized by default. Message boxes
|
||||
* (SDL_ShowSimpleMessageBox) also attempt to work without initializing the
|
||||
* video subsystem, in hopes of being useful in showing an error dialog when
|
||||
* SDL_Init fails. You must specifically initialize other subsystems if you
|
||||
* use them in your application.
|
||||
*
|
||||
* Logging (such as SDL_Log) works without initialization, too.
|
||||
*
|
||||
* `flags` may be any of the following OR'd together:
|
||||
*
|
||||
* - `SDL_INIT_AUDIO`: audio subsystem; automatically initializes the events
|
||||
* subsystem
|
||||
* - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events
|
||||
* subsystem, should be initialized on the main thread.
|
||||
* - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the
|
||||
* events subsystem
|
||||
* - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem
|
||||
* - `SDL_INIT_GAMEPAD`: gamepad subsystem; automatically initializes the
|
||||
* joystick subsystem
|
||||
* - `SDL_INIT_EVENTS`: events subsystem
|
||||
* - `SDL_INIT_SENSOR`: sensor subsystem; automatically initializes the events
|
||||
* subsystem
|
||||
* - `SDL_INIT_CAMERA`: camera subsystem; automatically initializes the events
|
||||
* subsystem
|
||||
*
|
||||
* Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem()
|
||||
* for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or
|
||||
* call SDL_Quit() to force shutdown). If a subsystem is already loaded then
|
||||
* this call will increase the ref-count and return.
|
||||
*
|
||||
* Consider reporting some basic metadata about your application before
|
||||
* calling SDL_Init, using either SDL_SetAppMetadata() or
|
||||
* SDL_SetAppMetadataProperty().
|
||||
*
|
||||
* \param flags subsystem initialization flags.
|
||||
* \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_SetAppMetadata
|
||||
* \sa SDL_SetAppMetadataProperty
|
||||
* \sa SDL_InitSubSystem
|
||||
* \sa SDL_Quit
|
||||
* \sa SDL_SetMainReady
|
||||
* \sa SDL_WasInit
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_Init(SDL_InitFlags flags);
|
||||
|
||||
/**
|
||||
* Compatibility function to initialize the SDL library.
|
||||
*
|
||||
* This function and SDL_Init() are interchangeable.
|
||||
*
|
||||
* \param flags any of the flags used by SDL_Init(); see SDL_Init for details.
|
||||
* \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_Init
|
||||
* \sa SDL_Quit
|
||||
* \sa SDL_QuitSubSystem
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_InitSubSystem(SDL_InitFlags flags);
|
||||
|
||||
/**
|
||||
* Shut down specific SDL subsystems.
|
||||
*
|
||||
* You still need to call SDL_Quit() even if you close all open subsystems
|
||||
* with SDL_QuitSubSystem().
|
||||
*
|
||||
* \param flags any of the flags used by SDL_Init(); see SDL_Init for details.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_InitSubSystem
|
||||
* \sa SDL_Quit
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_QuitSubSystem(SDL_InitFlags flags);
|
||||
|
||||
/**
|
||||
* Get a mask of the specified subsystems which are currently initialized.
|
||||
*
|
||||
* \param flags any of the flags used by SDL_Init(); see SDL_Init for details.
|
||||
* \returns a mask of all initialized subsystems if `flags` is 0, otherwise it
|
||||
* returns the initialization status of the specified subsystems.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_Init
|
||||
* \sa SDL_InitSubSystem
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_InitFlags SDLCALL SDL_WasInit(SDL_InitFlags flags);
|
||||
|
||||
/**
|
||||
* Clean up all initialized subsystems.
|
||||
*
|
||||
* You should call this function even if you have already shutdown each
|
||||
* initialized subsystem with SDL_QuitSubSystem(). It is safe to call this
|
||||
* function even in the case of errors in initialization.
|
||||
*
|
||||
* You can use this function with atexit() to ensure that it is run when your
|
||||
* application is shutdown, but it is not wise to do this from a library or
|
||||
* other dynamically loaded code.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_Init
|
||||
* \sa SDL_QuitSubSystem
|
||||
*/
|
||||
extern SDL_DECLSPEC void SDLCALL SDL_Quit(void);
|
||||
|
||||
/**
|
||||
* Return whether this is the main thread.
|
||||
*
|
||||
* On Apple platforms, the main thread is the thread that runs your program's
|
||||
* main() entry point. On other platforms, the main thread is the one that
|
||||
* calls SDL_Init(SDL_INIT_VIDEO), which should usually be the one that runs
|
||||
* your program's main() entry point. If you are using the main callbacks,
|
||||
* SDL_AppInit(), SDL_AppIterate(), and SDL_AppQuit() are all called on the
|
||||
* main thread.
|
||||
*
|
||||
* \returns true if this thread is the main thread, or 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_RunOnMainThread
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_IsMainThread(void);
|
||||
|
||||
/**
|
||||
* Callback run on the main thread.
|
||||
*
|
||||
* \param userdata an app-controlled pointer that is passed to the callback.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_RunOnMainThread
|
||||
*/
|
||||
typedef void (SDLCALL *SDL_MainThreadCallback)(void *userdata);
|
||||
|
||||
/**
|
||||
* Call a function on the main thread during event processing.
|
||||
*
|
||||
* If this is called on the main thread, the callback is executed immediately.
|
||||
* If this is called on another thread, this callback is queued for execution
|
||||
* on the main thread during event processing.
|
||||
*
|
||||
* Be careful of deadlocks when using this functionality. You should not have
|
||||
* the main thread wait for the current thread while this function is being
|
||||
* called with `wait_complete` true.
|
||||
*
|
||||
* \param callback the callback to call on the main thread.
|
||||
* \param userdata a pointer that is passed to `callback`.
|
||||
* \param wait_complete true to wait for the callback to complete, false to
|
||||
* return immediately.
|
||||
* \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_IsMainThread
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_RunOnMainThread(SDL_MainThreadCallback callback, void *userdata, bool wait_complete);
|
||||
|
||||
/**
|
||||
* Specify basic metadata about your app.
|
||||
*
|
||||
* You can optionally provide metadata about your app to SDL. This is not
|
||||
* required, but strongly encouraged.
|
||||
*
|
||||
* There are several locations where SDL can make use of metadata (an "About"
|
||||
* box in the macOS menu bar, the name of the app can be shown on some audio
|
||||
* mixers, etc). Any piece of metadata can be left as NULL, if a specific
|
||||
* detail doesn't make sense for the app.
|
||||
*
|
||||
* This function should be called as early as possible, before SDL_Init.
|
||||
* Multiple calls to this function are allowed, but various state might not
|
||||
* change once it has been set up with a previous call to this function.
|
||||
*
|
||||
* Passing a NULL removes any previous metadata.
|
||||
*
|
||||
* This is a simplified interface for the most important information. You can
|
||||
* supply significantly more detailed metadata with
|
||||
* SDL_SetAppMetadataProperty().
|
||||
*
|
||||
* \param appname The name of the application ("My Game 2: Bad Guy's
|
||||
* Revenge!").
|
||||
* \param appversion The version of the application ("1.0.0beta5" or a git
|
||||
* hash, or whatever makes sense).
|
||||
* \param appidentifier A unique string in reverse-domain format that
|
||||
* identifies this app ("com.example.mygame2").
|
||||
* \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_SetAppMetadataProperty
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_SetAppMetadata(const char *appname, const char *appversion, const char *appidentifier);
|
||||
|
||||
/**
|
||||
* Specify metadata about your app through a set of properties.
|
||||
*
|
||||
* You can optionally provide metadata about your app to SDL. This is not
|
||||
* required, but strongly encouraged.
|
||||
*
|
||||
* There are several locations where SDL can make use of metadata (an "About"
|
||||
* box in the macOS menu bar, the name of the app can be shown on some audio
|
||||
* mixers, etc). Any piece of metadata can be left out, if a specific detail
|
||||
* doesn't make sense for the app.
|
||||
*
|
||||
* This function should be called as early as possible, before SDL_Init.
|
||||
* Multiple calls to this function are allowed, but various state might not
|
||||
* change once it has been set up with a previous call to this function.
|
||||
*
|
||||
* Once set, this metadata can be read using SDL_GetAppMetadataProperty().
|
||||
*
|
||||
* These are the supported properties:
|
||||
*
|
||||
* - `SDL_PROP_APP_METADATA_NAME_STRING`: The human-readable name of the
|
||||
* application, like "My Game 2: Bad Guy's Revenge!". This will show up
|
||||
* anywhere the OS shows the name of the application separately from window
|
||||
* titles, such as volume control applets, etc. This defaults to "SDL
|
||||
* Application".
|
||||
* - `SDL_PROP_APP_METADATA_VERSION_STRING`: The version of the app that is
|
||||
* running; there are no rules on format, so "1.0.3beta2" and "April 22nd,
|
||||
* 2024" and a git hash are all valid options. This has no default.
|
||||
* - `SDL_PROP_APP_METADATA_IDENTIFIER_STRING`: A unique string that
|
||||
* identifies this app. This must be in reverse-domain format, like
|
||||
* "com.example.mygame2". This string is used by desktop compositors to
|
||||
* identify and group windows together, as well as match applications with
|
||||
* associated desktop settings and icons. If you plan to package your
|
||||
* application in a container such as Flatpak, the app ID should match the
|
||||
* name of your Flatpak container as well. This has no default.
|
||||
* - `SDL_PROP_APP_METADATA_CREATOR_STRING`: The human-readable name of the
|
||||
* creator/developer/maker of this app, like "MojoWorkshop, LLC"
|
||||
* - `SDL_PROP_APP_METADATA_COPYRIGHT_STRING`: The human-readable copyright
|
||||
* notice, like "Copyright (c) 2024 MojoWorkshop, LLC" or whatnot. Keep this
|
||||
* to one line, don't paste a copy of a whole software license in here. This
|
||||
* has no default.
|
||||
* - `SDL_PROP_APP_METADATA_URL_STRING`: A URL to the app on the web. Maybe a
|
||||
* product page, or a storefront, or even a GitHub repository, for user's
|
||||
* further information This has no default.
|
||||
* - `SDL_PROP_APP_METADATA_TYPE_STRING`: The type of application this is.
|
||||
* Currently this string can be "game" for a video game, "mediaplayer" for a
|
||||
* media player, or generically "application" if nothing else applies.
|
||||
* Future versions of SDL might add new types. This defaults to
|
||||
* "application".
|
||||
*
|
||||
* \param name the name of the metadata property to set.
|
||||
* \param value the value of the property, or NULL to remove that property.
|
||||
* \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_GetAppMetadataProperty
|
||||
* \sa SDL_SetAppMetadata
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_SetAppMetadataProperty(const char *name, const char *value);
|
||||
|
||||
#define SDL_PROP_APP_METADATA_NAME_STRING "SDL.app.metadata.name"
|
||||
#define SDL_PROP_APP_METADATA_VERSION_STRING "SDL.app.metadata.version"
|
||||
#define SDL_PROP_APP_METADATA_IDENTIFIER_STRING "SDL.app.metadata.identifier"
|
||||
#define SDL_PROP_APP_METADATA_CREATOR_STRING "SDL.app.metadata.creator"
|
||||
#define SDL_PROP_APP_METADATA_COPYRIGHT_STRING "SDL.app.metadata.copyright"
|
||||
#define SDL_PROP_APP_METADATA_URL_STRING "SDL.app.metadata.url"
|
||||
#define SDL_PROP_APP_METADATA_TYPE_STRING "SDL.app.metadata.type"
|
||||
|
||||
/**
|
||||
* Get metadata about your app.
|
||||
*
|
||||
* This returns metadata previously set using SDL_SetAppMetadata() or
|
||||
* SDL_SetAppMetadataProperty(). See SDL_SetAppMetadataProperty() for the list
|
||||
* of available properties and their meanings.
|
||||
*
|
||||
* \param name the name of the metadata property to get.
|
||||
* \returns the current value of the metadata property, or the default if it
|
||||
* is not set, NULL for properties with no default.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, although
|
||||
* the string returned is not protected and could potentially be
|
||||
* freed if you call SDL_SetAppMetadataProperty() to set that
|
||||
* property from another thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SetAppMetadata
|
||||
* \sa SDL_SetAppMetadataProperty
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetAppMetadataProperty(const char *name);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <SDL3/SDL_close_code.h>
|
||||
|
||||
#endif /* SDL_init_h_ */
|
||||
-407
@@ -1,407 +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: Intrinsics */
|
||||
|
||||
/**
|
||||
* # CategoryIntrinsics
|
||||
*
|
||||
* SDL does some preprocessor gymnastics to determine if any CPU-specific
|
||||
* compiler intrinsics are available, as this is not necessarily an easy thing
|
||||
* to calculate, and sometimes depends on quirks of a system, versions of
|
||||
* build tools, and other external forces.
|
||||
*
|
||||
* Apps including SDL's headers will be able to check consistent preprocessor
|
||||
* definitions to decide if it's safe to use compiler intrinsics for a
|
||||
* specific CPU architecture. This check only tells you that the compiler is
|
||||
* capable of using those intrinsics; at runtime, you should still check if
|
||||
* they are available on the current system with the
|
||||
* [CPU info functions](https://wiki.libsdl.org/SDL3/CategoryCPUInfo)
|
||||
* , such as SDL_HasSSE() or SDL_HasNEON(). Otherwise, the process might crash
|
||||
* for using an unsupported CPU instruction.
|
||||
*
|
||||
* SDL only sets preprocessor defines for CPU intrinsics if they are
|
||||
* supported, so apps should check with `#ifdef` and not `#if`.
|
||||
*
|
||||
* SDL will also include the appropriate instruction-set-specific support
|
||||
* headers, so if SDL decides to define SDL_SSE2_INTRINSICS, it will also
|
||||
* `#include <emmintrin.h>` as well.
|
||||
*/
|
||||
|
||||
#ifndef SDL_intrin_h_
|
||||
#define SDL_intrin_h_
|
||||
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Loongarch LSX intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<lsxintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_LASX_INTRINSICS
|
||||
*/
|
||||
#define SDL_LSX_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Loongarch LSX intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<lasxintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_LASX_INTRINSICS
|
||||
*/
|
||||
#define SDL_LASX_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports ARM NEON intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<armintr.h>`
|
||||
* `<arm_neon.h>`, `<arm64intr.h>`, and `<arm64_neon.h>`, as appropriate.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_NEON_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports PowerPC Altivec intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<altivec.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_ALTIVEC_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel MMX intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<mmintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SSE_INTRINSICS
|
||||
*/
|
||||
#define SDL_MMX_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel SSE intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<xmmintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SSE2_INTRINSICS
|
||||
* \sa SDL_SSE3_INTRINSICS
|
||||
* \sa SDL_SSE4_1_INTRINSICS
|
||||
* \sa SDL_SSE4_2_INTRINSICS
|
||||
*/
|
||||
#define SDL_SSE_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel SSE2 intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<emmintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SSE_INTRINSICS
|
||||
* \sa SDL_SSE3_INTRINSICS
|
||||
* \sa SDL_SSE4_1_INTRINSICS
|
||||
* \sa SDL_SSE4_2_INTRINSICS
|
||||
*/
|
||||
#define SDL_SSE2_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel SSE3 intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<pmmintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SSE_INTRINSICS
|
||||
* \sa SDL_SSE2_INTRINSICS
|
||||
* \sa SDL_SSE4_1_INTRINSICS
|
||||
* \sa SDL_SSE4_2_INTRINSICS
|
||||
*/
|
||||
#define SDL_SSE3_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel SSE4.1 intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<smmintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SSE_INTRINSICS
|
||||
* \sa SDL_SSE2_INTRINSICS
|
||||
* \sa SDL_SSE3_INTRINSICS
|
||||
* \sa SDL_SSE4_2_INTRINSICS
|
||||
*/
|
||||
#define SDL_SSE4_1_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel SSE4.2 intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<nmmintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_SSE_INTRINSICS
|
||||
* \sa SDL_SSE2_INTRINSICS
|
||||
* \sa SDL_SSE3_INTRINSICS
|
||||
* \sa SDL_SSE4_1_INTRINSICS
|
||||
*/
|
||||
#define SDL_SSE4_2_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel AVX intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<immintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_AVX2_INTRINSICS
|
||||
* \sa SDL_AVX512F_INTRINSICS
|
||||
*/
|
||||
#define SDL_AVX_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel AVX2 intrinsics.
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<immintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_AVX_INTRINSICS
|
||||
* \sa SDL_AVX512F_INTRINSICS
|
||||
*/
|
||||
#define SDL_AVX2_INTRINSICS 1
|
||||
|
||||
/**
|
||||
* Defined if (and only if) the compiler supports Intel AVX-512F intrinsics.
|
||||
*
|
||||
* AVX-512F is also sometimes referred to as "AVX-512 Foundation."
|
||||
*
|
||||
* If this macro is defined, SDL will have already included `<immintrin.h>`
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_AVX_INTRINSICS
|
||||
* \sa SDL_AVX2_INTRINSICS
|
||||
*/
|
||||
#define SDL_AVX512F_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
/* Need to do this here because intrin.h has C++ code in it */
|
||||
/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#ifdef __clang__
|
||||
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
|
||||
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
|
||||
#ifndef __PRFCHWINTRIN_H
|
||||
#define __PRFCHWINTRIN_H
|
||||
static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
||||
_m_prefetch(void *__P)
|
||||
{
|
||||
__builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */);
|
||||
}
|
||||
#endif /* __PRFCHWINTRIN_H */
|
||||
#endif /* __clang__ */
|
||||
#include <intrin.h>
|
||||
|
||||
#elif defined(__MINGW64_VERSION_MAJOR)
|
||||
#include <intrin.h>
|
||||
#if defined(__ARM_NEON) && !defined(SDL_DISABLE_NEON)
|
||||
# define SDL_NEON_INTRINSICS 1
|
||||
# include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC to have it included. */
|
||||
#if defined(__ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC)
|
||||
#define SDL_ALTIVEC_INTRINSICS 1
|
||||
#include <altivec.h>
|
||||
#endif
|
||||
#ifndef SDL_DISABLE_NEON
|
||||
# ifdef __ARM_NEON
|
||||
# define SDL_NEON_INTRINSICS 1
|
||||
# include <arm_neon.h>
|
||||
# elif defined(SDL_PLATFORM_WINDOWS)
|
||||
/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */
|
||||
# ifdef _M_ARM
|
||||
# define SDL_NEON_INTRINSICS 1
|
||||
# include <armintr.h>
|
||||
# include <arm_neon.h>
|
||||
# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */
|
||||
# endif
|
||||
# if defined (_M_ARM64)
|
||||
# define SDL_NEON_INTRINSICS 1
|
||||
# include <arm64intr.h>
|
||||
# include <arm64_neon.h>
|
||||
# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */
|
||||
# define __ARM_ARCH 8
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif /* compiler version */
|
||||
|
||||
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
/**
|
||||
* A macro to decide if the compiler supports `__attribute__((target))`.
|
||||
*
|
||||
* Even though this is defined in SDL's public headers, it is generally not
|
||||
* used directly by apps. Apps should probably just use SDL_TARGETING
|
||||
* directly, instead.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*
|
||||
* \sa SDL_TARGETING
|
||||
*/
|
||||
#define SDL_HAS_TARGET_ATTRIBS
|
||||
|
||||
#elif defined(__clang__) && defined(__has_attribute)
|
||||
# if __has_attribute(target)
|
||||
# define SDL_HAS_TARGET_ATTRIBS
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) /* gcc >= 4.9 */
|
||||
# define SDL_HAS_TARGET_ATTRIBS
|
||||
#elif defined(__ICC) && __ICC >= 1600
|
||||
# define SDL_HAS_TARGET_ATTRIBS
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
||||
|
||||
/**
|
||||
* A macro to tag a function as targeting a specific CPU architecture.
|
||||
*
|
||||
* This is a hint to the compiler that a function should be built with support
|
||||
* for a CPU instruction set that might be different than the rest of the
|
||||
* program.
|
||||
*
|
||||
* The particulars of this are explained in the GCC documentation:
|
||||
*
|
||||
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-target-function-attribute
|
||||
*
|
||||
* An example of using this feature is to turn on SSE2 support for a specific
|
||||
* function, even if the rest of the source code is not compiled to use SSE2
|
||||
* code:
|
||||
*
|
||||
* ```c
|
||||
* #ifdef SDL_SSE2_INTRINSICS
|
||||
* static void SDL_TARGETING("sse2") DoSomethingWithSSE2(char *x) {
|
||||
* ...use SSE2 intrinsic functions, etc...
|
||||
* }
|
||||
* #endif
|
||||
*
|
||||
* // later...
|
||||
* #ifdef SDL_SSE2_INTRINSICS
|
||||
* if (SDL_HasSSE2()) {
|
||||
* DoSomethingWithSSE2(str);
|
||||
* }
|
||||
* #endif
|
||||
* ```
|
||||
*
|
||||
* The application is, on a whole, built without SSE2 instructions, so it will
|
||||
* run on Intel machines that don't support SSE2. But then at runtime, it
|
||||
* checks if the system supports the instructions, and then calls into a
|
||||
* function that uses SSE2 opcodes. The ifdefs make sure that this code isn't
|
||||
* used on platforms that don't have SSE2 at all.
|
||||
*
|
||||
* On compilers without target support, this is defined to nothing.
|
||||
*
|
||||
* This symbol is used by SDL internally, but apps and other libraries are
|
||||
* welcome to use it for their own interfaces as well.
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_TARGETING(x) __attribute__((target(x)))
|
||||
|
||||
#elif defined(SDL_HAS_TARGET_ATTRIBS)
|
||||
# define SDL_TARGETING(x) __attribute__((target(x)))
|
||||
#else
|
||||
# define SDL_TARGETING(x)
|
||||
#endif
|
||||
|
||||
#ifdef __loongarch64
|
||||
# ifndef SDL_DISABLE_LSX
|
||||
# define SDL_LSX_INTRINSICS 1
|
||||
# include <lsxintrin.h>
|
||||
# endif
|
||||
# ifndef SDL_DISABLE_LASX
|
||||
# define SDL_LASX_INTRINSICS 1
|
||||
# include <lasxintrin.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
|
||||
# if ((defined(_MSC_VER) && !defined(_M_X64)) || defined(__MMX__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_MMX)
|
||||
# define SDL_MMX_INTRINSICS 1
|
||||
# include <mmintrin.h>
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__SSE__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE)
|
||||
# define SDL_SSE_INTRINSICS 1
|
||||
# include <xmmintrin.h>
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__SSE2__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE2)
|
||||
# define SDL_SSE2_INTRINSICS 1
|
||||
# include <emmintrin.h>
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__SSE3__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE3)
|
||||
# define SDL_SSE3_INTRINSICS 1
|
||||
# include <pmmintrin.h>
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__SSE4_1__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE4_1)
|
||||
# define SDL_SSE4_1_INTRINSICS 1
|
||||
# include <smmintrin.h>
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__SSE4_2__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE4_2)
|
||||
# define SDL_SSE4_2_INTRINSICS 1
|
||||
# include <nmmintrin.h>
|
||||
# endif
|
||||
# if defined(__clang__) && (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__) && !defined(SDL_DISABLE_AVX)
|
||||
# define SDL_DISABLE_AVX /* see https://reviews.llvm.org/D20291 and https://reviews.llvm.org/D79194 */
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__AVX__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(_M_ARM64EC) && !defined(SDL_DISABLE_AVX)
|
||||
# define SDL_AVX_INTRINSICS 1
|
||||
# include <immintrin.h>
|
||||
# endif
|
||||
# if defined(__clang__) && (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX2__) && !defined(SDL_DISABLE_AVX2)
|
||||
# define SDL_DISABLE_AVX2 /* see https://reviews.llvm.org/D20291 and https://reviews.llvm.org/D79194 */
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__AVX2__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(_M_ARM64EC) && !defined(SDL_DISABLE_AVX2)
|
||||
# define SDL_AVX2_INTRINSICS 1
|
||||
# include <immintrin.h>
|
||||
# endif
|
||||
# if defined(__clang__) && (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX512F__) && !defined(SDL_DISABLE_AVX512F)
|
||||
# define SDL_DISABLE_AVX512F /* see https://reviews.llvm.org/D20291 and https://reviews.llvm.org/D79194 */
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__AVX512F__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(_M_ARM64EC) && !defined(SDL_DISABLE_AVX512F)
|
||||
# define SDL_AVX512F_INTRINSICS 1
|
||||
# include <immintrin.h>
|
||||
# endif
|
||||
#endif /* defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) */
|
||||
|
||||
#endif /* SDL_intrin_h_ */
|
||||
-1354
File diff suppressed because it is too large
Load Diff
-1202
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user