refactor: constantes SCENE_BALLS_N y fix HUD overlay en SHAPE mode

- defines.hpp: añadir SCENE_BALLS_1..8 (topado en 50K), SCENARIO_COUNT,
  reconstruir BALL_COUNT_SCENARIOS con esas constantes
- theme_manager: añadir max_ball_count_ y setMaxBallCount() para capturar
  colores hasta el máximo real (custom incluido), eliminando literal 50000
- engine.cpp: llamar setMaxBallCount() tras inicializar ThemeManager
- gpu_sprite_batch: addFullscreenOverlay() escribe vértices directamente
  sin pasar por el guard de pushQuad(), igual que addBackground(); esto
  corrige el HUD/overlay invisible en SHAPE mode con escenario 8 (50K bolas)
- Textos UI actualizados: tecla 8, help overlay y --skip-benchmark → 50.000

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 00:55:57 +01:00
parent 093b982e01
commit e1f6fd0f39
5 changed files with 46 additions and 16 deletions

View File

@@ -9,10 +9,10 @@
bool GpuSpriteBatch::init(SDL_GPUDevice* device, int max_sprites) {
max_sprites_ = max_sprites;
// Pre-allocate GPU buffers large enough for (max_sprites_ + 1) quads.
// The +1 reserves a guaranteed slot for the fullscreen overlay.
Uint32 max_verts = static_cast<Uint32>(max_sprites_ + 1) * 4;
Uint32 max_indices = static_cast<Uint32>(max_sprites_ + 1) * 6;
// Pre-allocate GPU buffers large enough for (max_sprites_ + 2) quads.
// The +2 reserves one slot for the background quad and one for the fullscreen overlay.
Uint32 max_verts = static_cast<Uint32>(max_sprites_ + 2) * 4;
Uint32 max_indices = static_cast<Uint32>(max_sprites_ + 2) * 6;
Uint32 vb_size = max_verts * sizeof(GpuVertex);
Uint32 ib_size = max_indices * sizeof(uint32_t);
@@ -55,8 +55,8 @@ bool GpuSpriteBatch::init(SDL_GPUDevice* device, int max_sprites) {
return false;
}
vertices_.reserve(static_cast<size_t>(max_sprites_ + 1) * 4);
indices_.reserve(static_cast<size_t>(max_sprites_ + 1) * 6);
vertices_.reserve(static_cast<size_t>(max_sprites_ + 2) * 4);
indices_.reserve(static_cast<size_t>(max_sprites_ + 2) * 6);
return true;
}
@@ -130,10 +130,17 @@ void GpuSpriteBatch::addSprite(float x, float y, float w, float h,
}
void GpuSpriteBatch::addFullscreenOverlay() {
// El overlay es un slot reservado fuera del espacio de max_sprites_, igual que el background.
// Escribe directamente sin pasar por el guard de pushQuad().
overlay_index_offset_ = static_cast<int>(indices_.size());
size_t before = indices_.size();
pushQuad(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
overlay_index_count_ = static_cast<int>(indices_.size() - before); // 0 si pushQuad falló, 6 si ok
uint32_t vi = static_cast<uint32_t>(vertices_.size());
vertices_.push_back({ -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f });
vertices_.push_back({ 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f });
vertices_.push_back({ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f });
vertices_.push_back({ -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f });
indices_.push_back(vi + 0); indices_.push_back(vi + 1); indices_.push_back(vi + 2);
indices_.push_back(vi + 2); indices_.push_back(vi + 3); indices_.push_back(vi + 0);
overlay_index_count_ = 6;
}
bool GpuSpriteBatch::uploadBatch(SDL_GPUDevice* device, SDL_GPUCommandBuffer* cmd_buf) {
@@ -182,7 +189,8 @@ void GpuSpriteBatch::toNDC(float px, float py,
void GpuSpriteBatch::pushQuad(float ndx0, float ndy0, float ndx1, float ndy1,
float u0, float v0, float u1, float v1,
float r, float g, float b, float a) {
if (vertices_.size() + 4 > static_cast<size_t>(max_sprites_) * 4) return;
// +1 reserva el slot del background que ya entró sin pasar por este guard.
if (vertices_.size() + 4 > static_cast<size_t>(max_sprites_ + 1) * 4) return;
uint32_t vi = static_cast<uint32_t>(vertices_.size());
// TL, TR, BR, BL