GpuSpriteBatch::init() ahora acepta capacidad dinámica para soportar
--custom-balls N con N > 200000. El buffer se dimensiona a (N+1) quads,
reservando siempre un slot para el overlay. addFullscreenOverlay() calcula
overlay_index_count_ desde el delta real de indices_ en lugar de fijarlo
a 6 incondicionalmente. Engine calcula la capacidad correcta al init.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- updatePhysicalWindowSize() acepta logical_height opcional para
actualizar logical_window_height_ al entrar/salir de F4 real fullscreen
- Engine pasa current_screen_height_ a UIManager en cada cambio de
tamaño físico, propagando la resolución lógica correcta
- calculateFontSize() subdivide el rango >=900px en tres tramos más
conservadores (/40, /48, /60) para evitar texto excesivamente grande
en resoluciones como 2000x1200
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Formato uniforme [Tipo] nombre (pack/disco) en texture, textrenderer, png_shape
- Eliminar logs verbosos de logo_scaler y app_logo (resolución, escalado, etc.)
- Centralizar fuente de UI en APP_FONT (defines.hpp) con las 8 opciones comentadas
- Actualizar carpeta data/fonts con nuevas fuentes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
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>
- 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>
- 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>
- 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>
- 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>
En Windows, `find` es un comando de cmd distinto al de Unix,
causando el error "El sistema no puede encontrar la ruta especificada"
al evaluar DATA_FILES. Se condiciona el uso de find solo en sistemas
no-Windows.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- 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>
- 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>
- 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>
El fitxer era referenciat per CMakeLists.txt però mai no s'havia creat,
causant error de build immediat. Genera arrays uint8_t embeguts a partir
dels binaris .spv compilats per glslc.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
- 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>
- 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>
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>
- 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>
- 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>
5 blocs de millora: reorganitzacio de fitxers, limpieza de codi mort,
eliminacio de duplicitats Engine/ShapeManager, encapsulacio de
getBallsMutable(), i completar StateManager Phase 9.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- 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>