Commit Graph
68 Commits
Author SHA1 Message Date
JailDesigner 5ed963b53d feat(rendering): lighting module CPU + gradient config YAML 2026-05-12 20:56:27 +02:00
JailDesigner 6749780356 feat(entities): afegeix stone i column com a muros decoratius 2026-05-12 13:03:35 +02:00
JailDesigner 8bdc994b75 feat(render): sombra com a sprite 16x16 compartit 2026-05-11 17:29:05 +02:00
JailDesignerandClaude Opus 4.7 78e164fce4 feat(game): CONTINUE? + GAME OVER + fade-to-LOGO (Fase 2)
Sub-FSM nova `GameOverFsm` (CONTINUE_PROMPT → GAME_OVER → FADE_OUT →
DONE) que viu en paral·lel a la `RoomFsm`. Es dispara quan tots els
jugadors queden DISABLED durant PLAYING, mostra el rètol "Continuar?"
amb countdown reusant el panel del room text, i si ningú pulsa START
acaba en "Fi del Joc" + fade negre i sol·licita la transició a LOGO.
Pulsar START durant CONTINUE? cancel·la el countdown i fa join (revive)
del jugador. Després de GAME OVER, el HUD passa a "ESPERA / PER JUGAR"
i el START queda bloquejat fins a la transició d'escena.

Els helpers d'animació del room text (X i altura del panel) ara reben
phase + elapsed_ms per paràmetre per poder ser reaprofitats per les
dues sub-FSMs sense duplicar la lògica visual.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 20:30:37 +02:00
JailDesignerandClaude Opus 4.7 c13b11c501 feat(player): join in progress + DISABLED en agotar vidas (Fase 1)
Habilita la regla 1 de la nova FSM de joc: durant PLAYING, qualsevol
slot DISABLED pot pulsar START per entrar a partida amb spawn aeri al
seu costat de la porta i vides reseteades. Quan un jugador esgota les
vides, `respawnFromDying` el deixa a DISABLED i publica `player_disabled`
al bus; GameScene i HUD reaccionen, deixant el slot disponible per a un
nou join. Afegeix prompts al HUD ("PULSA START / PER JUGAR" o
"ESPERA / PER JUGAR") segons l'estat de la RoomFsm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 20:04:33 +02:00
JailDesigner 7871d3930e feat(whip): cabla flag whip.damage_pierces_walls a computeDamageRect
Quan el flag està actiu (default), l'iteració píxel a píxel ignora
`Map::collides` i només respecta `insidePlayfield`. El mur extern,
doncs, sempre retalla — fora del playfield no hi ha res a colpejar.

Els tests existents passen amb la nova lògica perquè els seus setups
posen el damage_rect a corredors lliures (sense sarcs a la trajectòria),
i el test W2 segueix verificant el retall del playfield.
2026-05-08 13:22:52 +02:00
JailDesigner 932b457725 feat(config): afegeix GameplayConfig persistent amb versionatge defensiu
Singleton paral·lel a UiConfig però escrivible: viu a la carpeta de
sistema (gameplay.yaml). Defaults compilats: friendly_fire,
players_collide i whip_damage_pierces_walls a true. Davant qualsevol
irregularitat (fitxer absent/buit, parse error, version absent o
desconeguda, clau requerida mal tipada o absent), reseteja a defaults
i reescriu el fitxer en lloc de preservar estat parcial.

Cablejat al Director::start després de Options::loadFromFile. Encara
sense consumidors — els flags es cablejaran a WhipAttack i al sistema
de col·lisió de jugadors en commits posteriors.
2026-05-08 13:17:28 +02:00
JailDesignerandClaude Opus 4.7 6e99fd0a8b refactor(log): migra core/resources i core/system a Log::
- resource_pack.cpp i resource_cache.cpp: tots els std::cerr passen a
  Log::error.
- director.cpp: std::cout/cerr/fprintf → Log::info / error / critical
  segons severitat.
- printWithDots (utils.cpp): ara és un wrapper sobre Log::info que
  manté l'amplada total (~50 chars) reproduint l'alineació de punts.
  Els callers pasen el tag sense " : " (ja l'afegeix el logger).
- pack_resources: afegit log.cpp i SDL3 al target perquè
  resource_pack.cpp ara depèn de Log::.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:10:03 +02:00
JailDesignerandClaude Opus 4.7 1243b457be feat(log): introdueix Log:: wrapper sobre SDL_Log
Logger lleuger a source/utils/log.{hpp,cpp} amb API basada en std::format
i filtre runtime via la variable d'entorn AEE_LOG (sintaxi
*:info,Resource::Helper:warn,scene:debug). Substitueix gradualment els
std::cout/cerr dispersos.

- Categories CUSTOM registrades sota demanda; per defecte INFO.
- Categories SDL natives no es toquen tret que l'usuari posi *:level.
- Migra resource_helper.cpp i els marcadors d'inici/fi (main.cpp) com a
  testimoni; la resta de subsistemes es migra en commits següents.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:01:09 +02:00
JailDesigner 0ec1a2548a feat(mummy): so mummy_hurt en colpejada de fuet 2026-05-07 20:25:23 +02:00
JailDesigner 9949096fba chore(rename): aee_2026 -> aee_arcade 2026-05-07 18:39:02 +02:00
JailDesigner e32cff9dac feat(logo): scanline reveal CRT amb glitch, bursts VHS i pulse de banda 2026-05-07 13:52:57 +02:00
JailDesigner b6d6ee471c refactor(scenes): flux centralitzat amb SceneId+ExitRequest; TitleScene attract → LOGO amb fade-to-black 2026-05-06 18:33:31 +02:00
JailDesigner 0618452224 feat(transitions): mosaic dissolve fade-out al final de la fase STARTING (configurable a ui.yaml) 2026-05-06 13:54:09 +02:00
JailDesigner 1fc3ab8e31 feat(effects): heat-haze sinusoidal al fons del títol (configurable a ui.yaml) 2026-05-06 11:48:29 +02:00
JailDesigner f9e09d968d fix(build): silenciats warnings en Release 2026-05-05 12:16:18 +02:00
JailDesigner c003e6665e feat(editor): mou la porta i persisteix geometry.door_col 2026-05-02 13:35:01 +02:00
JailDesigner ecb4625465 feat(editor): EntityWriter — persisteix el bloc entities: al sortir 2026-05-02 11:35:10 +02:00
JailDesigner 4da50571eb feat(hazard): nou hazard Hole — caiguda per forat amb clip rect 2026-04-30 13:32:17 +02:00
JailDesigner a53cf4b797 feat(editor): spacing, border i centrat vertical del tilepicker via editor.yaml 2026-04-30 09:51:30 +02:00
JailDesigner 37fdcb4751 feat(controls): redefinició de tecles i botons del mando des del menú de servei 2026-04-29 19:54:47 +02:00
JailDesigner 1d43a77800 feat(anim): suport de flip H/V per frame i per animació 2026-04-29 08:30:08 +02:00
JailDesigner 121558b1fd test(whip): smokes de hitbox, dany a mòmia i alreadyHit; tests de Mummy HURT 2026-04-28 16:20:22 +02:00
JailDesigner df60709e6d feat(whip): aplicació de dany amb retall de hitbox, alreadyHit i friendly fire 2026-04-28 16:20:22 +02:00
JailDesigner 9ad21eb5bb feat(attack): esquelet WhipAttack + canal d'spawn via EventBus 2026-04-28 16:20:22 +02:00
JailDesigner 4752eb8ad7 build: silencia warning de sprintf deprecat a stb_image_write 2026-04-28 12:21:33 +02:00
JailDesigner 2f3643f09c build: silencia warnings de stb a source/external/ via set_source_files_properties 2026-04-28 09:38:52 +02:00
JailDesigner d3698a1504 feat(audio): suport d'efectes (eco i reverb) per a sons puntuals
Afig una capa d'efectes oberta a la unitat d'àudio. Els sons puntuals
es poden reproduir processats per un eco o un reverb (Freeverb 8C/4AP)
sense afectar la música ni canviar el camí ràpid existent (playSound
sense efecte segueix sent una sola crida sense cost extra).

  - data/sounds.yaml: catàleg de presets nominats (echo: cave/short,
    reverb: stone_hall/small_room).
  - core/audio/audio_effects: processadors purs que prenen un Ja::Sound
    (U8/S16, mono o estèreo) i tornen PCM S16 amb la cua de l'efecte
    (cap a 800 ms eco, 1500 ms reverb).
  - core/audio/sound_effects_config: Meyers singleton que parseja
    sounds.yaml a EchoParams/ReverbParams indexats per nom; l'API
    pública d'Audio fa el lookup per nom.
  - jail_audio::Engine: nou camí playSoundWith{Echo,Reverb} que empenta
    el buffer ja processat a un canal lliure marcat com a has_effect.
    El cap MAX_EFFECT_CHANNELS limita a 4 sons amb efecte simultanis;
    si està al límit, l'engine retorna -1 i Audio cau a la versió seca.
  - Audio::playSoundWith{Echo,Reverb}(name, preset, group) com a única
    via pública. Si el preset no existeix, fallback dry amb avís.
  - director: load("data/sounds.yaml") abans d'Audio::init.
2026-04-27 08:16:16 +02:00
JailDesigner fe17c35c67 feat(levels): LevelManager amb índex de sales
Nou singleton Levels::LevelManager que llig data/maps/levels.yaml a la
primera get() i exposa currentPath/currentPyramid/currentRoom/
currentLabel + advance/restart/setIndex. És pur estat 'on sóc' — no
orquestra cap reload; la GameScene i l'Editor li preguntaran al pas
següent. Afegida constant Defaults::Pyramid::LEVELS_YAML al costat de
la MAP_YAML antiga (la substitució completa va al Step 3).
2026-04-26 14:48:15 +02:00
JailDesigner 63bb41425a test(game-scene): extracció RoomFsm i smoke test de la FSM de sala 2026-04-26 09:10:54 +02:00
JailDesigner 3e379ce129 feat(effects): polvet transitori al despegue i a l'aterratge 2026-04-25 17:51:55 +02:00
JailDesigner 91614fc545 fix(input): mou gamecontrollerdb.txt a l'arrel i el copia al build/ via CMake 2026-04-25 10:36:55 +02:00
JailDesigner 8aa4ec3daf build: aïlla la implementació de stb_vorbis en un TU propi
Mateix patró que stb_image_write: jail_audio.cpp defineix
STB_VORBIS_HEADER_ONLY i només veu les declaracions; les definicions
viuen a source/external/stb_vorbis_impl.cpp, ja exclòs del pre-commit.
Això permet retirar també la desactivació global de
clang-analyzer-core.UndefinedBinaryOperatorResult al .clang-tidy, i el
check queda actiu arreu del nostre propi codi.
2026-04-24 11:18:59 +02:00
JailDesigner 6c1c042637 build: aïlla la implementació de stb_image_write en un TU propi
screenshot.cpp ara només inclou les declaracions de stb_image_write.h;
la macro STB_IMAGE_WRITE_IMPLEMENTATION viu a un .cpp nou dins de
source/external/, que ja està exclòs del pre-commit hook (clang-format
i clang-tidy) i cobert pel seu .clang-tidy amb Checks: '-*'. Així
podem retirar la desactivació global de clang-analyzer-optin.portability
.UnixAPI i el check queda actiu arreu del nostre propi codi.
2026-04-24 11:15:32 +02:00
JailDesigner dc8a7723e3 feat(ui): captura F9, tema a data/ui.yaml i retocs estètics
Captura de pantalla amb F9: volca el canvas ARGB a
screenshots/scr_<timestamp>.png via stb_image_write.

Tot el tema d'UI (colors, timings, fonts, flag hud.bg_enabled)
passa a data/ui.yaml via UiConfig; els valors de Defaults::UI
queden com a fallbacks si el fitxer falta o li manca alguna clau.

Retocs estètics: paleta "uzebox" per a la UI, strings del HUD
(P1/P2/V/T/PIRAMIDE/SALA) traduïts a locale, i fons del marcador
opcional amb backdrop continu de franja per evitar el trencament
visual durant el shake o l'animació d'entrada dels panells.
2026-04-24 10:58:02 +02:00
JailDesigner 82b229222f feat(hud): marcador de la franja superior amb 3 blocs i animació d'entrada 2026-04-23 23:46:41 +02:00
JailDesigner 87b08a7c7c feat(map): afegeix PaintLayer com a font única del pintat 2026-04-23 13:17:47 +02:00
JailDesigner a612a8255f feat(editor): mode editor mínim amb toggle, border blau i mutex amb pausa 2026-04-23 12:09:04 +02:00
JailDesigner 6d8423764d feat(editor): writer surgical del bloc data: al YAML del tilemap 2026-04-23 11:51:49 +02:00
JailDesigner 4da05b3d76 chore(release): v0.21.0 — empaquetat de recursos (AE26) i neteja de fonts
- Nou format de pack AE26 v1 (XOR + djb2), eina `pack_resources`,
  regeneració automàtica de `build/resources.pack` a cada build.
- `Resource::Helper` amb init/shutdown, fallback a disc només en Debug
  (apunta al source tree); Release exigeix pack present.
- Callers de YAML migrats a `loadFile`+deserialize des de buffer.
- Arrel neta: el pack viu a `build/`, eliminat `sync_data`.
- Placeholder font -> `ari-w9500-condensed-display`; esborrades variants
  bold/condensed no usades a `data/fonts/`.
2026-04-23 08:51:21 +02:00
JailDesigner 4dd2b6d2a9 feat(mouse): amaga el cursor automàticament després de 3s sense moviment 2026-04-22 21:34:05 +02:00
JailDesigner 7c35ffaa74 feat(gamepad): detecció i notificacions hot-plug amb GamepadManager 2026-04-22 19:39:16 +02:00
JailDesigner fb40d0effb feat(menu): submenú Controls i bloqueig de polling amb menú obert 2026-04-22 19:05:36 +02:00
JailDesigner 350625dec0 feat(menu): primera versió del menú de servei 2026-04-22 18:15:00 +02:00
JailDesigner 6800786194 fix(resources): resoldre rutes de data/ respecte a SDL_GetBasePath
Abans el binari només arrencava si la CWD era la que contenia data/
(típicament build/). Executat des de qualsevol altra carpeta no trobava
keys.yaml, paletes, etc. i es moria al carregar el primer recurs.

Patró seguit de ../aee: Resource::Helper guarda un data root absolut
i resolve(rel) el prefixa davant de rutes no absolutes. Director fa
setDataRoot(SDL_GetBasePath()) com a primera acció del ctor, així tots
els loaders posteriors hi passen sense canvis al call site.

Migrats a Resource::Helper::resolve els loaders que obrien std::ifstream
directament amb el path rebut: Locale, KeyConfig, Player, Map, Tilemap
i EntityLoader. Els que ja usaven Resource::Helper::loadFile
(Resource::Cache, PaletteLoader) hereten el fix automàticament.

Els fitxers de system_folder_ (config.yaml, debug.yaml, postfx.yaml,
crtpi.yaml) es passen com a rutes absolutes i resolve() les deixa
intactes, així no es veuen afectats.

Test targets (test_entities_smoke, test_scene_flow) enllacen ara
resource_helper.cpp perquè el seu codi passa per Helper::resolve. Els
tests corren amb CWD = repo root, on les rutes "data/..." funcionen
amb data root buit sense canviar cap assert.

Verificat executant el binari des de build/, /tmp i / — tots tres
troben els recursos i arrenquen correctament, tant en debug com en
release (release sempre arranca a LOGO).
2026-04-22 11:29:51 +02:00
JailDesigner 2cb21211ef test(scenes): smoke del flux d'escenes i parser de debug.yaml
Cobreix les dues peces pures del flux:
- parseStartScene / resolveStartScene: tots els valors vàlids, fallback
  a GAME per valor invàlid, YAML corrupte o fitxer inexistent.
- createDefaultIfMissing: crea el fitxer amb start_scene=GAME si no
  existeix i és idempotent quan ja hi és.
- isReservedScancode: F1/F12/Escape reservats, SPACE/fletxes no, i
  UNKNOWN sempre fals.

La lògica de update/render dels placeholders no es testeja perquè
arrossegaria Screen/Notifier/RenderInfo (tot l'stack SDL). Aquesta
integració queda coberta pel smoke xvfb-run del binari.

Stand-alone target `test_scene_flow` que només enllaça els .cpp pures
necessaris, amb ctest afegit.
2026-04-22 10:35:07 +02:00
JailDesigner 87a9f098b5 feat(debug): selector d'escena inicial via debug.yaml
Director encadena LOGO → TITLE → INTRO → GAME amb factories injectades
al ctor de cada placeholder (sense que cap escena conegui el tipus de
la següent). L'escena d'arrencada surt de `debug.yaml` en debug build i
és sempre LOGO en release.

Comportament:
- Release: `debug.yaml` s'ignora; arranca sempre a LOGO.
- Debug: es llig `debug.yaml`. Si no existeix, es crea automàticament
  amb `start_scene: GAME` per no arrossegar 15 s de placeholders al dia
  a dia de gameplay. Valor invàlid o YAML corrupte → warning + GAME,
  però el fitxer no es reescriu (respectem l'edició manual).

`debug.yaml` viu a `$XDG_CONFIG_HOME/jailgames/aee_2026/`, al costat
de `config.yaml`, i queda fora del repo (ajust per màquina de dev).
2026-04-22 10:33:36 +02:00
JailDesigner d31483124e feat(scenes): afegir placeholders LogoScene/TitleScene/IntroScene
Tres escenes de 5 s cadascuna, activables al flux que precedeix GameScene.
Classes separades (sense base comuna) perquè divergiran quan es
desenvolupi contingut real.

Avancen per timeout o per qualsevol tecla no reservada. Les tecles
reservades (F1-F12, Escape) són les declarades a data/input/keys.yaml i
mantenen el seu comportament habitual via GlobalInputs. La
classificació viu a Placeholder::isReservedScancode, i KeyConfig exposa
bindings() per enumerar-les sense duplicar la llista.

Encara no integrats al Director: això es fa al següent commit quan
s'afegeix el selector d'escena inicial.
2026-04-22 10:31:48 +02:00
JailDesigner 32dcf264c4 feat(entities): caja-peus concèntrica i animacions direccionals a la momia, còpia de data/ sempre sincronitzada; v0.19.0 2026-04-21 23:21:32 +02:00
JailDesigner 7191a08618 feat(entities): integració del sistema d'entitats al GameScene 2026-04-21 13:55:21 +02:00