Commit Graph

178 Commits

Author SHA1 Message Date
c40eb69fc1 fix: sincronizar texto de ayuda con constantes DEFAULT_SCREEN_*/ZOOM de defines.hpp
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 22:37:31 +01:00
1d2e9c5035 feat: F7/F8 redimensionan campo lógico, F1/F2 muestran notificación de zoom
- F7/F8: nuevo setFieldScale() cambia resolución lógica en pasos del 10%
  (mín 50%, máx limitado por pantalla), reinicia escena como F4
- F1/F2: muestran notificación "Zoom X%" al cambiar escala de ventana
- Ventana física = lógico × zoom en todo momento; resizeWindowCentered()
  unifica el cálculo de posición leyendo el tamaño real con SDL_GetWindowSize
- PostFXUniforms::time renombrado a screen_height; scanlines usan la altura
  lógica actual en lugar del 720 hardcodeado — F1/F2 escalan las scanlines
  visualmente, F7/F8 las mantienen a 1 franja por píxel lógico
- Eliminados logs de debug de calculateMaxWindowScale y setWindowScale

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 22:35:40 +01:00
f71f7cd5ed fix: corregir guard de padding inferior en HelpOverlay
El guard usaba `current_y + line_height >= box_height_ - padding`,
lo que cortaba la última línea de col0 (Num/) por un solo píxel.
Cambiado a `current_y + glyph_height > box_height_ - padding` para
usar el alto visual real del glifo en lugar del line_height completo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 20:59:31 +01:00
dcea4ebbab fix: corregir padding asimétrico en HelpOverlay con getGlyphHeight()
Añade TextRenderer::getGlyphHeight() (ascent - descent, sin line_gap)
y lo usa en calculateTextDimensions() para descontar el gap sobrante
de la última línea, aproximando padding superior e inferior simétricos.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 19:29:35 +01:00
b9b5f0b29f feat: rediseño HUD ayuda — 3 columnas, colores diferenciados, font -1pt
- Reorganizar key_bindings_ en 3 columnas (SIMULACIÓN+FIGURAS3D / VISUAL+PANTALLA / MODOS+DEBUG)
- Añadir F6 (escalado entero) y corregir F5 (Toggle PostFX), X (ciclar presets)
- Teclas usan category_color, descripciones usan content_color
- Separadores vacíos avanzan media línea (fix secciones pegadas)
- Font size del overlay reducido en 1pt respecto al resto de la UI
- calculateTextDimensions y rebuildCachedTexture actualizados para 3 columnas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 19:06:48 +01:00
200672756c refactor: separar F5 (toggle) y X (ciclo modos) en PostFX
- X ya no incluye OFF en el ciclo; si PostFX está desactivado, no hace nada
- cycleShader() cicla solo entre los 4 modos usando postfx_effect_mode_
- Eliminar postfx_cycle_idx_ (redundante, causaba desincronización)
- postfx_effect_mode_ por defecto = 3 (completo) para que F5 active completo sin --postfx

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 18:36:45 +01:00
f3b029c5b6 refactor: normalizar notificaciones a castellano, title case sin dos puntos
- Todo en castellano (Vinyeta→viñeta, Cromàtica→cromática, Complet→completo, Desactivat→desactivado, Boids→boids)
- Primera letra mayúscula, resto minúscula (MODO SANDBOX→Modo sandbox, etc.)
- Sin dos puntos separador (PostFX: X→PostFX X, Escalado: X→Escalado X, Sprite: X→Textura X)
- Separadores de miles en castellano (1,000→1.000 pelotas)
- Nombres de figura en minúscula via tolower (SPHERE→sphere → "Modo sphere")
- Ajuste valores PostFX por defecto (vignette 1.5→0.8, chroma 1.0→0.2)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 18:21:28 +01:00
e46c3eb4ba fix: ajustes de rutas y guards en vscode, rc y gpu_pipeline
- c_cpp_properties.json: añadir build/generated_shaders a includePath
- vibe3.rc: corregir ruta del icono a release/icons/icon.ico
- gpu_pipeline.cpp: envolver shaders MSL con guard #ifdef __APPLE__

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 18:00:30 +01:00
c052b45a60 refactor: eliminar sistema de shaders externos (ShaderManager + GpuShaderPreset)
Elimina el sistema multi-pass de shaders runtime en favor del PostFX nativo.
Queda solo el ciclo de 5 modos nativos: OFF → Vinyeta → Scanlines → Cromàtica → Complet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 17:08:08 +01:00
5b4a970157 feat(macos): suport Metal per GpuShaderPreset via spirv-cross
- CMakeLists: bloc if(APPLE) que transpila .spv → .spv.msl amb spirv-cross
- gpu_shader_preset: carrega MSL (main0) a macOS, SPIR-V (main) a la resta
- Afegeix null-terminator als buffers MSL (SDL3 els tracta com C-string)
- README: secció de dependències de shaders per plataforma (Vulkan SDK, spirv-cross)
- Inclou .spv.msl generats per ntsc-md-rainbows

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 13:54:05 +01:00
f272bab296 feat(shaders): sistema de shaders runtime amb presets externs
- Afegir GpuShaderPreset i ShaderManager per carregar shaders des de data/shaders/
- Implementar preset ntsc-md-rainbows (2 passos: encode + decode MAME NTSC)
- Render loop multi-pass per shaders externs (targets intermedis R16G16B16A16_FLOAT)
- cycleShader(): cicla OFF→PostFX natius→shaders externs amb tecla X
- --shader <nom> per arrancar directament amb un preset extern
- CMake auto-descubreix i compila data/shaders/**/*.vert/.frag → .spv
- HUD F1 mostra 'Shader: <nom>' quan hi ha shader extern actiu

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 13:37:22 +01:00
e3f29c864b feat(postfx): debug HUD mostra PostFX, overrides persistents al ciclar, --postfx sense valor
- HUD (F1) afegeix línia PostFX: OFF o PostFX: <preset> [V:x.xx C:x.xx S:x.xx]
- applyPostFXPreset reaaplica overrides de CLI per preservar-los en ciclar amb X
- setPostFXParamOverrides guarda els valors en membres privats per persistència
- --postfx sense valor ja no dona error i utilitza complet (preset 3) per defecte

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 12:20:30 +01:00
6ffe7594ab feat(gpu): afegir suport SPIRV (Vulkan) per Linux/Windows
- Nou: shaders/sprite.vert|frag, postfx.vert|frag, ball.vert (GLSL)
- Nou: cmake/spv_to_header.cmake — converteix .spv → uint8_t C header
- CMakeLists.txt: bloc non-Apple troba glslc, compila GLSL → SPIRV en
  build-time i genera headers embeguts a build/generated_shaders/
- gpu_context.cpp: MSL|METALLIB en Apple, SPIRV en la resta
- gpu_pipeline.cpp: createShaderSPIRV() + branques #ifdef __APPLE__
  per sprite/ball/postfx pipelines
- Corregeix crash a engine.cpp:821 (Windows/Linux) causat per pipelines
  null quan init() fallava en no trobar suport MSL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:47:36 +01:00
5c0d0479ad fix(engine): implementar viewport/scissor F6 i eliminar early return toggleIntegerScaling
- Eliminar guarda !fullscreen_enabled_ de toggleIntegerScaling(): F6 ara
  cicla i notifica en mode ventana i fullscreen per igual
- Pass 2: afegir viewport+scissor SDL_GPU condicionat a fullscreen_enabled_
  per als tres modes (INTEGER pixel-perfect centrat, LETTERBOX aspect-ratio,
  STRETCH pantalla completa)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:18:11 +01:00
a51072db32 feat(postfx): redisseny sistema PostFX (X/F5/F6, --postfx CLI)
- X cicla 4 efectes (Vinyeta/Scanlines/Cromàtica/Complet), sempre activa PostFX
- F5 fa toggle PostFX on/off mantenint l'efecte seleccionat
- F6 hereta el toggle d'integer scaling (abans F5)
- Arrencada per defecte sense postprocés (tot a 0)
- --postfx <vinyeta|scanlines|cromatica|complet> per activar des de CLI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 09:06:24 +01:00
d2e7f2ff86 refactor(gpu): eliminar GPU compute boids (prevé crash macOS)
Elimina el kernel Metal O(N²) de boids en GPU que causava GPU timeout
a macOS amb >50K boles, arrossegant WindowServer fins al crash.

- Elimina gpu_boid_buffer.hpp/cpp (GpuBoidBuffer, BallComputeData, BoidParams)
- Elimina kBoidComputeMSL i kBallComputeVertMSL de gpu_pipeline
- Elimina boid_compute_pipeline_ i ball_compute_pipeline_
- Elimina use_gpu_boids_, boid_params_, ball_screen_uniforms_ de Engine
- Elimina syncAndExitGpuBoids() i tot el compute dispatch de render()
- Mode BOIDS ara usa sempre boid_manager_ (CPU, spatial hash O(N))
  i renderitza via gpu_ball_buffer_ instanced (mateix path que PHYSICS)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 08:45:01 +01:00
badf92420b feat(engine): PostFX cycle + fixes de reinicialització i overflow
- Afegir handlePostFXCycle() amb 5 presets (vinyeta/scanlines/cromàtica/complet/off)
  i tecla X per ciclar-los (input_handler + engine.hpp)
- Augmentar MAX_SPRITES de 65536 a 200000 i afegir guard d'overflow a pushQuad()
- Netejar textures/objectes UI abans de reinicialitzar (AppLogo::initialize,
  UIManager::initialize) per evitar leaks en toggleRealFullscreen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:53:13 +01:00
310c6d244e fix(engine): corregir figura 3D i text en real fullscreen
- Bug 2: moure shape_manager_->updateScreenSize() fora del bloc
  condicional SHAPE a les dues branques de toggleRealFullscreen(),
  de manera que ShapeManager sempre té les dimensions correctes quan
  s'activa una figura després d'entrar en fullscreen
- Bug text: passar base_screen_width_/height_ com a dimensions lògiques
  a ui_manager_->initialize() en recreateOffscreenTexture(), evitant
  que calculateFontSize() s'avaluï amb la resolució nativa de fullscreen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:51:31 +01:00
af0276255e feat(postfx): afegir push constants i efectes chromatic aberration + scanlines
- PostFXUniforms struct (vignette_strength, chroma_strength, scanline_strength, time)
- Shader MSL actualitzat: aberració cromàtica RGB + scanlines sin-wave + vinyeta paramètrica
- Pipeline postfx declara num_uniform_buffers=1 (buffer(0) en MSL)
- Engine acumula temps i fa SDL_PushGPUFragmentUniformData cada frame
- Valors per defecte: vignette=1.5, chroma=0, scanlines=0 (comportament idèntic a l'anterior)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:11:05 +01:00
00a5875c92 feat(gpu): migrar a SDL3_GPU amb 2-pass rendering i post-processat
- Infraestructura GPU: GpuContext, GpuPipeline, GpuSpriteBatch, GpuTexture
- Engine::render() migrat a 2-pass: sprites → offscreen R8G8B8A8 → swapchain + vignette
- UI/text via software renderer (SDL3_ttf) + upload com a textura overlay GPU
- CMakeLists.txt actualitzat per incloure subsistema gpu/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 22:08:12 +01:00
821eba3483 refactor(bloques2-5): auditoria de codi - limpieza i arquitectura
Bloque 2: eliminar codi mort comentat (shape_manager, engine)
Bloque 3: Engine shape methods com thin wrappers a ShapeManager;
          eliminar estat duplicat de shapes en Engine
Bloque 4: encapsular getBallsMutable() amb helpers a SceneManager
          (enableShapeAttractionAll, resetDepthScalesAll)
Bloque 5: StateManager Phase 9 - tota la logica DEMO/LOGO
          implementada directament amb refs a SceneManager,
          ThemeManager i ShapeManager; eliminar callbacks a Engine.
          Acoplament Engine<->StateManager passa a unidireccional.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 00:42:03 +01:00
6409b61bd5 refactor(bloque1): reorganitzar fitxers als subsistemes correctes
- app_logo.hpp/cpp i logo_scaler.hpp/cpp moguts a source/ui/
- spatial_grid.hpp/cpp mogut a source/boids_mgr/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 00:41:50 +01:00
e8a6485e88 desactivada la tecla O (png_shape) i la B (Boids) 2026-03-18 23:09:31 +01:00
6aa4a1227e ordenació per buckets 2026-03-12 22:55:33 +01:00
02fdcd4113 Ara --custom-balls N --skip-benchmark (o --max-balls N) inclou el custom escenari en la rotació automàtica de DEMO/DEMO_LITE 2026-03-12 22:35:10 +01:00
7db9e46f95 soport per a pantalles de poca resolució en mode finestra 2026-03-12 09:05:57 +01:00
ff6aaef7c6 parametres per saltarse el benchmark i per limitar el maxim de pilotes en els modes automatics 2026-03-12 08:56:59 +01:00
8e2e681b2c el benchmark es fa ara amb una figura i no amb el mode de fisica 2026-03-12 08:48:14 +01:00
cbe6dc9744 varies millores en el hud de debug 2026-03-11 23:27:02 +01:00
dfbd8a430b afegit escenari personalitzat per parametre 2026-03-11 22:44:17 +01:00
ea27a771ab benchmark inicial per a determinar modes de baix rendiment
ajustats escenaris maxims i minims per als diferents modes automatics
2026-03-11 20:30:32 +01:00
09303537a4 advertencia de modo kiosko al intentar cambiar els modes de finestra 2026-03-11 20:07:20 +01:00
ce5c4681b8 afegit mode kiosko 2026-03-11 19:14:22 +01:00
b79f1c3424 afegida cache a resource manager per evitar accessos a disc 2026-03-11 18:59:56 +01:00
a65544e8b3 fix: png_shape ja carrega de resources.pack
Amb tots els fixos anteriors, el app de macos ja funciona correctament
2026-03-08 22:36:10 +01:00
b9264c96a1 fix: no carregava correctament data/shapes/jailgames.png si s'executava desde fora del directori de l'executable 2026-03-08 22:24:41 +01:00
1a555e03f7 Fix: Mejorar escalado de fuentes para resoluciones altas y actualizar .gitignore
Problemas resueltos:
- Texto demasiado pequeño en resoluciones 2K/4K (1440p mostraba 36-41px)
- Archivos generados (resources.pack, *.zip) siendo versionados
- Carpetas temporales de empaquetado sin ignorar

Cambios realizados:

1. UIManager: Escalado más agresivo para resoluciones altas
   - Proporción mejorada: 1/40 → 1/26 (incremento ~35%)
   - Límite máximo: 36px → 72px
   - Resultados: 1080p→42px, 1440p→55px, 2160p→72px
   - Resoluciones bajas sin cambios (10-18px)

2. .gitignore: Excluir archivos generados y temporales
   - resources.pack (archivo empaquetado)
   - Archivos de distribución (*.zip, *.dmg, *.tar.gz, *.AppImage)
   - Carpetas temporales (vibe3_release/, Frameworks/)
   - Binarios de herramientas (tools/*.exe)

3. defines.hpp: Resolución por defecto actualizada
   - 640x360 (zoom 2x) → 1280x720 (zoom 1x)

Resultado:
- Texto significativamente más legible en pantallas grandes
- Repositorio limpio sin archivos generados

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 10:22:25 +02:00
af3ed6c2b3 Fix: Ajustar dimensionamiento de HelpOverlay para resoluciones bajas
Problemas resueltos:
- En 640x360, el overlay generaba textura enorme con letras grandes
- El cálculo de font size usaba dimensiones físicas (con zoom aplicado)
  en lugar de dimensiones lógicas (resolución interna)
- No había límite máximo de ancho para el overlay
- Padding fijo de 25px era excesivo en pantallas pequeñas

Cambios realizados:

1. UIManager: Usar dimensiones lógicas para calcular font size
   - Nuevo parámetro logical_width/logical_height en initialize()
   - calculateFontSize() ahora usa altura lógica sin zoom
   - Escalado híbrido: proporcional en extremos, escalonado en rango medio
   - Para 640x360: 10px (antes 18px con zoom 2x)
   - Para 640x480: 12px (antes 24px con zoom 2x)

2. HelpOverlay: Agregar límites máximos de dimensiones
   - Box width limitado al 95% del ancho físico
   - Box height limitado al 90% de la altura física
   - Padding dinámico: 25px para >=600px, escalado para menores
   - Para 360px altura: padding de 15px (antes 25px fijo)

3. Engine: Pasar dimensiones lógicas a UIManager
   - initialize() ahora recibe current_screen_width/height

Resultado:
- 640x360: Overlay compacto con fuente 10px que cabe en pantalla
- 640x480: Overlay con fuente 12px (tamaño apropiado)
- Tamaño de fuente consistente independiente del zoom de ventana

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 14:23:59 +02:00
a9d7b66e83 Refactorizar estilo del proyecto: .h → .hpp, #pragma once, includes desde raíz
Modernizar convenciones de código C++ aplicando las siguientes directivas:

## Cambios principales

**1. Renombrar headers (.h → .hpp)**
- 36 archivos renombrados a extensión .hpp (estándar C++)
- Mantenidos como .h: stb_image.h, stb_image_resize2.h (librerías C externas)

**2. Modernizar include guards (#ifndef → #pragma once)**
- resource_manager.hpp: #ifndef RESOURCE_MANAGER_H → #pragma once
- resource_pack.hpp: #ifndef RESOURCE_PACK_H → #pragma once
- spatial_grid.hpp: #ifndef SPATIAL_GRID_H → #pragma once

**3. Sistema de includes desde raíz del proyecto**
- CMakeLists.txt: añadido include_directories(${CMAKE_SOURCE_DIR}/source)
- Eliminadas rutas relativas (../) en todos los includes
- Includes ahora usan rutas absolutas desde source/

**Antes:**
```cpp
#include "../defines.h"
#include "../text/textrenderer.h"
```

**Ahora:**
```cpp
#include "defines.hpp"
#include "text/textrenderer.hpp"
```

## Archivos afectados

- 1 archivo CMakeLists.txt modificado
- 36 archivos renombrados (.h → .hpp)
- 32 archivos .cpp actualizados (includes)
- 36 archivos .hpp actualizados (includes + guards)
- 1 archivo tools/ actualizado

**Total: 70 archivos modificados**

## Verificación

 Proyecto compila sin errores
 Todas las rutas de includes correctas
 Include guards modernizados
 Librerías externas C mantienen extensión .h

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 13:49:58 +02:00
a929df6b73 Fix: Corregir inicialización de figuras en modo DEMO
Solucionar bug donde las pelotas aparecían en el centro sin formar
la figura geométrica al entrar en modo DEMO con SimulationMode::SHAPE.

## Problema
Al randomizar el estado en modo DEMO, si se elegía una figura:
1. Se configuraba el modo SHAPE
2. Se llamaba a changeScenario() que creaba pelotas en el centro
3. NO se llamaba a generateShape() para calcular los puntos de la figura
4. Resultado: pelotas amontonadas en el centro sin formar figura

## Solución
Reordenar operaciones en executeRandomizeOnDemoStart():
1. Decidir PRIMERO el modo (PHYSICS o SHAPE) antes de changeScenario
2. Si SHAPE: configurar figura manualmente sin generar puntos
3. Llamar a changeScenario() con el modo ya establecido
4. Después de changeScenario(), generar figura y activar atracción

Cambios adicionales:
- Arreglar warning de formato %zu en textrenderer.cpp (MinGW)
- Usar %lu con cast para size_t en logs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 13:22:03 +02:00
3f027d953c Eliminados warnings en textrenderer.cpp 2025-10-23 12:26:52 +02:00
1354ed82d2 Fix: Corregir carga de fuentes desde ResourceManager
Problema:
- Las fuentes TTF no se renderizaban (error "Text has zero width")
- Ocurría tanto al cargar desde resources.pack como desde disco
- El buffer de memoria se liberaba inmediatamente después de crear
  el SDL_IOStream, pero SDL_ttf necesita acceder a esos datos
  durante toda la vida de la fuente

Solución:
- Añadido campo font_data_buffer_ para mantener los datos en memoria
- Modificado init() y reinitialize() para NO liberar el buffer
  inmediatamente después de cargar la fuente
- Modificado cleanup() para liberar el buffer cuando se cierre la fuente
- Añadidos logs de debug para confirmar la carga desde ResourceManager

Archivos modificados:
- source/text/textrenderer.h: Añadido campo font_data_buffer_
- source/text/textrenderer.cpp: Correcciones en init(), reinitialize()
  y cleanup()

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 12:15:54 +02:00
2fa1684f01 Refactorizar sistema de recursos: crear ResourceManager centralizado
- Crear ResourceManager singleton para gestión centralizada de recursos
- Separar lógica de ResourcePack de la clase Texture
- Adaptar TextRenderer para cargar fuentes TTF desde pack
- Adaptar LogoScaler para cargar imágenes PNG desde pack
- Actualizar main.cpp y engine.cpp para usar ResourceManager
- Regenerar resources.pack con fuentes y logos incluidos

Fixes:
- Resuelve error de carga de fuentes desde disco
- Resuelve error de carga de logos (can't fopen)
- Implementa fallback automático a disco si no existe pack
- Todas las clases ahora pueden cargar recursos desde pack

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-23 09:16:18 +02:00
ce50a29019 Eliminado código DEPRECATED de ui_manager 2025-10-19 15:02:13 +02:00
8aa2a112b4 fix: Enlazar SDL3_ttf en Makefile + corregir declaración SDL_Renderer
**Problema 1: Símbolos no definidos de SDL_ttf** (CRÍTICO)
- Error: "Undefined symbols: _TTF_Init, _TTF_OpenFont, etc."
- Causa: LDFLAGS solo incluía -lSDL3 (faltaba -lSDL3_ttf)
- Solución: Añadido -lSDL3_ttf a LDFLAGS para Unix/macOS (línea 81)
- Afecta: Linux, macOS y otros sistemas Unix

**Problema 2: Mismatch class/struct SDL_Renderer** (WARNING)
- Warning: "class 'SDL_Renderer' was previously declared as a struct"
- Causa: ui_manager.h:7 declaraba "class SDL_Renderer"
- SDL3 lo declara como "struct SDL_Renderer" (SDL_render.h:119)
- Solución: Cambiado class → struct en ui_manager.h:7
- Evita warnings y potenciales errores de linker en MSVC

**Resultado:**
 make macos_release completa exitosamente
 DMG creado: vibe3_physics-2025-10-19-macos-apple-silicon.dmg (17.9 MB)
 Sin errores de enlazado, solo warnings menores de versión macOS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-19 09:00:01 +02:00
dfebd8ece4 chore: Mover archivos .md a .claude/ + añadir DLLs/frameworks + fix Makefile Windows
**Cambios organizativos:**
- Archivos .md movidos de raíz a .claude/ (BOIDS_ROADMAP, CLAUDE, REFACTOR_*, ROADMAP, RULES)
- .claude/ ya está en .gitignore, archivos de sesión no versionados

**Nuevos recursos para release:**
- Añadido release/frameworks/SDL3_ttf.xcframework/ para macOS
- Añadidos release/SDL3.dll y release/SDL3_ttf.dll para Windows (forzado con -f)

**Configuración:**
- defines.h: APPLOGO_DISPLAY_INTERVAL 120→90 segundos (logo aparece más frecuente)
- defines.h: Ajustes de formato/indentación (sin cambios funcionales)

**Makefile windows_release:**
- Comandos Unix reemplazados por Windows CMD nativos:
  - rm -rf → if exist + rmdir /S /Q
  - mkdir -p → mkdir
  - cp -f → copy /Y
  - rm -f → if exist + del /Q
- Ahora funciona en Windows CMD sin necesitar Git Bash/MSYS2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-19 08:51:56 +02:00
0da4b45fef fix: Usar métodos de alto nivel para inicialización CLI de modos
**Problema:**
Cuando se iniciaba con `-m demo`, `-m demo-lite` o `-m logo`, se llamaba
a `setState()` directamente, que es un método de bajo nivel que solo
cambia el estado interno SIN ejecutar las acciones de configuración.

**Resultado del bug:**
- `-m demo`: NO aleatorizaba (tema default, primer escenario)
- `-m demo-lite`: NO aleatorizaba física
- `-m logo`: NO configuraba tema, PNG_SHAPE, ni pelotas pequeñas

**Arquitectura correcta:**
- `setState()` = Método primitivo bajo nivel (solo cambia estado)
- `toggleDemoMode()` = Método alto nivel (setState + randomize)
- `toggleDemoLiteMode()` = Método alto nivel (setState + randomize)
- `enterLogoMode()` = Método alto nivel (setState + configuración completa)

**Solución implementada:**
En lugar de llamar a setState() directamente, usar los métodos de
alto nivel que ejecutan las acciones de configuración:

```cpp
if (initial_mode == AppMode::DEMO) {
    state_manager_->toggleDemoMode(...);  // Entra a DEMO + randomiza
}
else if (initial_mode == AppMode::DEMO_LITE) {
    state_manager_->toggleDemoLiteMode(...);  // Entra a DEMO_LITE + randomiza
}
else if (initial_mode == AppMode::LOGO) {
    state_manager_->enterLogoMode(...);  // Entra a LOGO + configura todo
}
```

**Archivos modificados:**
- source/engine.cpp (líneas 249-263):
  - Reemplazado setState() por toggleDemoMode/toggleDemoLiteMode/enterLogoMode
  - Agregados comentarios explicativos

**Resultado esperado:**
-  `-m demo` → Aleatoriza todo como si pulsaras D
-  `-m demo-lite` → Aleatoriza física como si pulsaras Shift+D
-  `-m logo` → Configura tema/PNG_SHAPE/pelotas como si pulsaras K
-  Comportamiento consistente entre CLI y teclas
-  Arquitectura correcta: alto nivel para acciones, bajo nivel para estado

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 20:00:27 +02:00
db8acf0331 clean: Eliminar logging debug + fix: Centro fijo para animación ZOOM
**1. Eliminado logging de debug del FADE_OUT:**
- Removido log de timer/delta_time/progress (FADE_OUT inicial)
- Removido log de alpha1/alpha2
- Removido log de animaciones (ZOOM, ELASTIC, SPIRAL, BOUNCE)
- Removido log de completado de FADE_OUT
- Consola limpia en modo producción

**2. Fix centro del logo en animación ZOOM_ONLY:**

**Problema:**
- Centro del logo se calculaba basándose en width/height escalados
- Cuando scale cambiaba (1.2 → 1.0), corner_x/corner_y se movían
- Resultado: logo se desplazaba lateralmente durante zoom

**Solución:**
- Calcular esquina BASE (sin escala): corner_x_base, corner_y_base
- Calcular centro FIJO basándose en base_width/base_height
- Calcular width/height escalados DESPUÉS (solo para vértices)
- Resultado: centro permanece fijo, zoom crece/decrece alrededor del centro

**Archivos modificados:**
- source/app_logo.cpp:
  - Líneas 343-347: Eliminado log FADE_OUT inicial
  - Línea 347: Eliminado log completado
  - Líneas 365-366: Eliminado log alphas
  - Líneas 381-383: Eliminado log ZOOM
  - Líneas 396-398: Eliminado log ELASTIC
  - Líneas 414-417: Eliminado log SPIRAL
  - Líneas 444-446: Eliminado log BOUNCE
  - Líneas 609-625: Reordenado cálculo de centro (FIJO) y tamaño (ESCALADO)

**Resultado esperado:**
- Sin spam en consola
- Animación ZOOM perfectamente centrada en esquina inferior derecha
- Logo crece/decrece sin desplazamiento lateral

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 19:40:53 +02:00
5a35cc1abf fix: Aplicar alpha del logo a través de vértices en lugar de textura
**Problema:**
- SDL_SetTextureAlphaMod() no funciona correctamente con SDL_RenderGeometry()
- El alpha de los vértices (hardcodeado a 1.0) overrideaba el alpha de textura
- Resultado: fade invisible o instantáneo a pesar de valores correctos

**Solución:**
- Eliminar SDL_SetTextureAlphaMod()
- Convertir alpha de 0-255 a 0.0-1.0 (alpha_normalized)
- Aplicar alpha_normalized directamente al canal alpha de los 4 vértices
- Ahora SDL_RenderGeometry respeta el fade correctamente

**Archivos modificados:**
- source/app_logo.cpp:
  - Línea 630: Crear alpha_normalized en lugar de SetTextureAlphaMod
  - Líneas 669, 680, 691, 702: Aplicar alpha_normalized a vértices

**Resultado esperado:**
- Fade visible y suave durante 2 segundos completos
- Logo 2 con retraso de 0.25s como esperado
- Sincronización perfecta entre animación y fade

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 19:31:28 +02:00
d30a4fd440 debug: Agregar logging detallado a FADE_OUT de AppLogo
- Log de timer_, delta_time, progress en cada frame
- Log de alpha1/alpha2 calculados
- Log de valores de animación por tipo (ZOOM/ELASTIC/SPIRAL/BOUNCE)
- Log de ease_t1 en ROTATE_SPIRAL para diagnosticar desincronización
- Log cuando FADE_OUT se completa

Propósito: Diagnosticar por qué el fade parece instantáneo
y desincronizado con la animación (serie en lugar de paralelo).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 19:26:14 +02:00