benchmark inicial per a determinar modes de baix rendiment
ajustats escenaris maxims i minims per als diferents modes automatics
This commit is contained in:
@@ -53,6 +53,13 @@ constexpr float BALL_SPAWN_MARGIN = 0.15f; // Margen lateral para spawn (0.25 =
|
|||||||
// Escenarios de número de pelotas (teclas 1-8)
|
// Escenarios de número de pelotas (teclas 1-8)
|
||||||
constexpr int BALL_COUNT_SCENARIOS[8] = {10, 50, 100, 500, 1000, 5000, 10000, 50000};
|
constexpr int BALL_COUNT_SCENARIOS[8] = {10, 50, 100, 500, 1000, 5000, 10000, 50000};
|
||||||
|
|
||||||
|
// Límites de escenario para modos automáticos (índices en BALL_COUNT_SCENARIOS)
|
||||||
|
// BALL_COUNT_SCENARIOS = {10, 50, 100, 500, 1000, 5000, 10000, 50000}
|
||||||
|
// 0 1 2 3 4 5 6 7
|
||||||
|
constexpr int DEMO_AUTO_MIN_SCENARIO = 2; // mínimo 100 bolas
|
||||||
|
constexpr int DEMO_AUTO_MAX_SCENARIO = 7; // máximo sin restricción hardware (ajustado por benchmark)
|
||||||
|
constexpr int LOGO_MIN_SCENARIO_IDX = 4; // mínimo 1000 bolas (sustituye LOGO_MODE_MIN_BALLS)
|
||||||
|
|
||||||
// Estructura para representar colores RGB
|
// Estructura para representar colores RGB
|
||||||
struct Color {
|
struct Color {
|
||||||
int r, g, b; // Componentes rojo, verde, azul (0-255)
|
int r, g, b; // Componentes rojo, verde, azul (0-255)
|
||||||
|
|||||||
@@ -283,6 +283,9 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen, AppMod
|
|||||||
app_logo_.reset();
|
app_logo_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Benchmark de rendimiento (determina max_auto_scenario_ para modos automáticos)
|
||||||
|
runPerformanceBenchmark();
|
||||||
|
|
||||||
// Precalentar caché: shapes PNG (evitar I/O en primera activación de PNG_SHAPE)
|
// Precalentar caché: shapes PNG (evitar I/O en primera activación de PNG_SHAPE)
|
||||||
{
|
{
|
||||||
unsigned char* tmp = nullptr; size_t tmp_size = 0;
|
unsigned char* tmp = nullptr; size_t tmp_size = 0;
|
||||||
@@ -1289,7 +1292,7 @@ void Engine::executeDemoAction(bool is_lite) {
|
|||||||
|
|
||||||
if (is_lite) {
|
if (is_lite) {
|
||||||
// DEMO LITE: Verificar condiciones para salto a Logo Mode
|
// DEMO LITE: Verificar condiciones para salto a Logo Mode
|
||||||
if (static_cast<int>(scene_manager_->getBallCount()) >= LOGO_MODE_MIN_BALLS &&
|
if (static_cast<int>(scene_manager_->getBallCount()) >= BALL_COUNT_SCENARIOS[LOGO_MIN_SCENARIO_IDX] &&
|
||||||
theme_manager_->getCurrentThemeIndex() == 5) { // MONOCHROME
|
theme_manager_->getCurrentThemeIndex() == 5) { // MONOCHROME
|
||||||
// 10% probabilidad de saltar a Logo Mode
|
// 10% probabilidad de saltar a Logo Mode
|
||||||
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO_LITE) {
|
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO_LITE) {
|
||||||
@@ -1299,7 +1302,7 @@ void Engine::executeDemoAction(bool is_lite) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// DEMO COMPLETO: Verificar condiciones para salto a Logo Mode
|
// DEMO COMPLETO: Verificar condiciones para salto a Logo Mode
|
||||||
if (static_cast<int>(scene_manager_->getBallCount()) >= LOGO_MODE_MIN_BALLS) {
|
if (static_cast<int>(scene_manager_->getBallCount()) >= BALL_COUNT_SCENARIOS[LOGO_MIN_SCENARIO_IDX]) {
|
||||||
// 15% probabilidad de saltar a Logo Mode
|
// 15% probabilidad de saltar a Logo Mode
|
||||||
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO) {
|
if (rand() % 100 < LOGO_JUMP_PROBABILITY_FROM_DEMO) {
|
||||||
state_manager_->enterLogoMode(true, current_screen_width_, current_screen_height_, scene_manager_->getBallCount());
|
state_manager_->enterLogoMode(true, current_screen_width_, current_screen_height_, scene_manager_->getBallCount());
|
||||||
@@ -1413,12 +1416,12 @@ void Engine::executeDemoAction(bool is_lite) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cambiar escenario (10%) - EXCLUIR índices 0, 6, 7 (1, 50K, 100K pelotas)
|
// Cambiar escenario (10%) - rango dinámico según benchmark de rendimiento
|
||||||
accumulated_weight += DEMO_WEIGHT_SCENARIO;
|
accumulated_weight += DEMO_WEIGHT_SCENARIO;
|
||||||
if (random_value < accumulated_weight) {
|
if (random_value < accumulated_weight) {
|
||||||
// Escenarios válidos: índices 1, 2, 3, 4, 5 (10, 100, 500, 1000, 10000 pelotas)
|
int auto_max = std::min(max_auto_scenario_, DEMO_AUTO_MAX_SCENARIO);
|
||||||
int valid_scenarios[] = {1, 2, 3, 4, 5};
|
int range = auto_max - DEMO_AUTO_MIN_SCENARIO + 1;
|
||||||
int new_scenario = valid_scenarios[rand() % 5];
|
int new_scenario = DEMO_AUTO_MIN_SCENARIO + (rand() % range);
|
||||||
scene_manager_->changeScenario(new_scenario, current_mode_);
|
scene_manager_->changeScenario(new_scenario, current_mode_);
|
||||||
|
|
||||||
// Si estamos en modo SHAPE, regenerar la figura con nuevo número de pelotas
|
// Si estamos en modo SHAPE, regenerar la figura con nuevo número de pelotas
|
||||||
@@ -1573,9 +1576,10 @@ void Engine::executeRandomizeOnDemoStart(bool is_lite) {
|
|||||||
// changeScenario() creará las pelotas y luego llamará a generateShape()
|
// changeScenario() creará las pelotas y luego llamará a generateShape()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Escenario (excluir índices 0, 6, 7) - AHORA con current_mode_ ya establecido correctamente
|
// 2. Escenario - rango dinámico según benchmark de rendimiento
|
||||||
int valid_scenarios[] = {1, 2, 3, 4, 5};
|
int auto_max = std::min(max_auto_scenario_, DEMO_AUTO_MAX_SCENARIO);
|
||||||
int new_scenario = valid_scenarios[rand() % 5];
|
int range = auto_max - DEMO_AUTO_MIN_SCENARIO + 1;
|
||||||
|
int new_scenario = DEMO_AUTO_MIN_SCENARIO + (rand() % range);
|
||||||
scene_manager_->changeScenario(new_scenario, current_mode_);
|
scene_manager_->changeScenario(new_scenario, current_mode_);
|
||||||
|
|
||||||
// Si estamos en modo SHAPE, generar la figura y activar atracción
|
// Si estamos en modo SHAPE, generar la figura y activar atracción
|
||||||
@@ -1621,16 +1625,80 @@ void Engine::executeToggleGravityOnOff() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// BENCHMARK DE RENDIMIENTO
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
void Engine::runPerformanceBenchmark() {
|
||||||
|
int num_displays = 0;
|
||||||
|
SDL_DisplayID* displays = SDL_GetDisplays(&num_displays);
|
||||||
|
float monitor_hz = 60.0f;
|
||||||
|
if (displays && num_displays > 0) {
|
||||||
|
const auto* dm = SDL_GetCurrentDisplayMode(displays[0]);
|
||||||
|
if (dm && dm->refresh_rate > 0) monitor_hz = dm->refresh_rate;
|
||||||
|
SDL_free(displays);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ocultar ventana y desactivar V-sync para medición limpia
|
||||||
|
SDL_HideWindow(window_);
|
||||||
|
SDL_SetRenderVSync(renderer_, 0);
|
||||||
|
|
||||||
|
const int BENCH_DURATION_MS = 600;
|
||||||
|
const int WARMUP_FRAMES = 5;
|
||||||
|
|
||||||
|
auto restore = [&]() {
|
||||||
|
SDL_SetRenderVSync(renderer_, vsync_enabled_ ? 1 : 0);
|
||||||
|
SDL_ShowWindow(window_);
|
||||||
|
scene_manager_->changeScenario(0, current_mode_);
|
||||||
|
last_frame_time_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Probar de más pesado a más ligero
|
||||||
|
for (int idx = DEMO_AUTO_MAX_SCENARIO; idx >= DEMO_AUTO_MIN_SCENARIO; --idx) {
|
||||||
|
scene_manager_->changeScenario(idx, current_mode_);
|
||||||
|
|
||||||
|
// Warmup: estabilizar física y pipeline GPU
|
||||||
|
last_frame_time_ = 0;
|
||||||
|
for (int w = 0; w < WARMUP_FRAMES; ++w) {
|
||||||
|
calculateDeltaTime();
|
||||||
|
SDL_Event e; while (SDL_PollEvent(&e)) {}
|
||||||
|
update();
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Medición
|
||||||
|
int frame_count = 0;
|
||||||
|
Uint64 start = SDL_GetTicks();
|
||||||
|
while (SDL_GetTicks() - start < static_cast<Uint64>(BENCH_DURATION_MS)) {
|
||||||
|
calculateDeltaTime();
|
||||||
|
SDL_Event e;
|
||||||
|
while (SDL_PollEvent(&e)) { /* descartar */ }
|
||||||
|
update();
|
||||||
|
render();
|
||||||
|
++frame_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
float measured_fps = static_cast<float>(frame_count) / (BENCH_DURATION_MS / 1000.0f);
|
||||||
|
if (measured_fps >= monitor_hz) {
|
||||||
|
max_auto_scenario_ = idx;
|
||||||
|
restore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback: escenario mínimo
|
||||||
|
max_auto_scenario_ = DEMO_AUTO_MIN_SCENARIO;
|
||||||
|
restore();
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// CALLBACKS PARA STATEMANAGER - LOGO MODE
|
// CALLBACKS PARA STATEMANAGER - LOGO MODE
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Callback para StateManager - Configuración visual al entrar a LOGO MODE
|
// Callback para StateManager - Configuración visual al entrar a LOGO MODE
|
||||||
void Engine::executeEnterLogoMode(size_t ball_count) {
|
void Engine::executeEnterLogoMode(size_t ball_count) {
|
||||||
// Verificar mínimo de pelotas
|
// Verificar mínimo de pelotas (LOGO_MIN_SCENARIO_IDX = índice 4 → 1000 bolas)
|
||||||
if (static_cast<int>(ball_count) < LOGO_MODE_MIN_BALLS) {
|
if (scene_manager_->getCurrentScenario() < LOGO_MIN_SCENARIO_IDX) {
|
||||||
// Ajustar a 5000 pelotas automáticamente
|
scene_manager_->changeScenario(LOGO_MIN_SCENARIO_IDX, current_mode_);
|
||||||
scene_manager_->changeScenario(5, current_mode_); // Escenario 5000 pelotas (índice 5 en BALL_COUNT_SCENARIOS)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guardar estado previo (para restaurar al salir)
|
// Guardar estado previo (para restaurar al salir)
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ class Engine {
|
|||||||
int getCurrentScreenHeight() const { return current_screen_height_; }
|
int getCurrentScreenHeight() const { return current_screen_height_; }
|
||||||
int getBaseScreenWidth() const { return base_screen_width_; }
|
int getBaseScreenWidth() const { return base_screen_width_; }
|
||||||
int getBaseScreenHeight() const { return base_screen_height_; }
|
int getBaseScreenHeight() const { return base_screen_height_; }
|
||||||
|
int getMaxAutoScenario() const { return max_auto_scenario_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// === Componentes del sistema (Composición) ===
|
// === Componentes del sistema (Composición) ===
|
||||||
@@ -172,6 +173,7 @@ class Engine {
|
|||||||
// StateManager coordina los triggers y timers, Engine ejecuta las acciones
|
// StateManager coordina los triggers y timers, Engine ejecuta las acciones
|
||||||
float demo_timer_ = 0.0f; // Contador de tiempo para próxima acción
|
float demo_timer_ = 0.0f; // Contador de tiempo para próxima acción
|
||||||
float demo_next_action_time_ = 0.0f; // Tiempo aleatorio hasta próxima acción (segundos)
|
float demo_next_action_time_ = 0.0f; // Tiempo aleatorio hasta próxima acción (segundos)
|
||||||
|
int max_auto_scenario_ = 5; // Índice máximo en modos auto (default conservador: 5000 bolas)
|
||||||
|
|
||||||
// Sistema de convergencia para LOGO MODE (escala con resolución)
|
// Sistema de convergencia para LOGO MODE (escala con resolución)
|
||||||
// Usado por performLogoAction() para detectar cuando las bolas forman el logo
|
// Usado por performLogoAction() para detectar cuando las bolas forman el logo
|
||||||
@@ -211,6 +213,9 @@ class Engine {
|
|||||||
void update();
|
void update();
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
|
// Benchmark de rendimiento (determina max_auto_scenario_ al inicio)
|
||||||
|
void runPerformanceBenchmark();
|
||||||
|
|
||||||
// Métodos auxiliares privados (llamados por la interfaz pública)
|
// Métodos auxiliares privados (llamados por la interfaz pública)
|
||||||
|
|
||||||
// Sistema de cambio de sprites dinámico - Métodos privados
|
// Sistema de cambio de sprites dinámico - Métodos privados
|
||||||
|
|||||||
@@ -276,6 +276,25 @@ void UIManager::renderDebugHUD(const Engine* engine,
|
|||||||
text_renderer_debug_->printAbsolute(margin, left_y, balls_text.c_str(), {128, 255, 128, 255}); // Verde claro
|
text_renderer_debug_->printAbsolute(margin, left_y, balls_text.c_str(), {128, 255, 128, 255}); // Verde claro
|
||||||
left_y += line_height;
|
left_y += line_height;
|
||||||
|
|
||||||
|
// Máximo de pelotas en modos automáticos (resultado del benchmark)
|
||||||
|
int max_auto_idx = engine->getMaxAutoScenario();
|
||||||
|
int max_auto_balls = BALL_COUNT_SCENARIOS[max_auto_idx];
|
||||||
|
std::string max_auto_text;
|
||||||
|
if (max_auto_balls >= 1000) {
|
||||||
|
std::string count_str = std::to_string(max_auto_balls);
|
||||||
|
std::string formatted;
|
||||||
|
int digits = count_str.length();
|
||||||
|
for (int i = 0; i < digits; i++) {
|
||||||
|
if (i > 0 && (digits - i) % 3 == 0) formatted += ',';
|
||||||
|
formatted += count_str[i];
|
||||||
|
}
|
||||||
|
max_auto_text = "Auto max: " + formatted;
|
||||||
|
} else {
|
||||||
|
max_auto_text = "Auto max: " + std::to_string(max_auto_balls);
|
||||||
|
}
|
||||||
|
text_renderer_debug_->printAbsolute(margin, left_y, max_auto_text.c_str(), {128, 255, 128, 255}); // Verde claro
|
||||||
|
left_y += line_height;
|
||||||
|
|
||||||
// V-Sync
|
// V-Sync
|
||||||
text_renderer_debug_->printAbsolute(margin, left_y, vsync_text_.c_str(), {0, 255, 255, 255}); // Cian
|
text_renderer_debug_->printAbsolute(margin, left_y, vsync_text_.c_str(), {0, 255, 255, 255}); // Cian
|
||||||
left_y += line_height;
|
left_y += line_height;
|
||||||
|
|||||||
Reference in New Issue
Block a user