|
|
|
|
@@ -203,21 +203,8 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen) {
|
|
|
|
|
|
|
|
|
|
srand(static_cast<unsigned>(time(nullptr)));
|
|
|
|
|
|
|
|
|
|
// Calcular tamaño de fuente escalado según resolución
|
|
|
|
|
// Usa las constantes configurables de la clase
|
|
|
|
|
int font_size = (base_screen_height_ * TEXT_BASE_SIZE) / 240;
|
|
|
|
|
|
|
|
|
|
// Inicializar TextRenderer para display (texto centrado)
|
|
|
|
|
if (!text_renderer_.init(renderer_, TEXT_FONT_PATH, font_size, TEXT_ANTIALIASING)) {
|
|
|
|
|
SDL_Log("Error al inicializar TextRenderer (display)");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Inicializar TextRenderer para debug (HUD)
|
|
|
|
|
if (!text_renderer_debug_.init(renderer_, TEXT_FONT_PATH, font_size, TEXT_ANTIALIASING)) {
|
|
|
|
|
SDL_Log("Error al inicializar TextRenderer (debug)");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// Calcular tamaño físico de ventana y tamaño de fuente absoluto
|
|
|
|
|
updatePhysicalWindowSize();
|
|
|
|
|
|
|
|
|
|
// Inicializar ThemeManager
|
|
|
|
|
theme_manager_ = std::make_unique<ThemeManager>();
|
|
|
|
|
@@ -883,6 +870,10 @@ void Engine::render() {
|
|
|
|
|
SDL_RenderGeometry(renderer_, texture_->getSDLTexture(), batch_vertices_.data(), static_cast<int>(batch_vertices_.size()), batch_indices_.data(), static_cast<int>(batch_indices_.size()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Calcular factores de escala lógica → física para texto absoluto
|
|
|
|
|
float text_scale_x = static_cast<float>(physical_window_width_) / static_cast<float>(current_screen_width_);
|
|
|
|
|
float text_scale_y = static_cast<float>(physical_window_height_) / static_cast<float>(current_screen_height_);
|
|
|
|
|
|
|
|
|
|
if (show_text_) {
|
|
|
|
|
// Obtener datos del tema actual (delegado a ThemeManager)
|
|
|
|
|
int text_color_r, text_color_g, text_color_b;
|
|
|
|
|
@@ -894,7 +885,7 @@ void Engine::render() {
|
|
|
|
|
int margin = 8;
|
|
|
|
|
|
|
|
|
|
// Texto del número de pelotas con color del tema
|
|
|
|
|
text_renderer_.print(text_pos_, margin, text_.c_str(), text_color_r, text_color_g, text_color_b);
|
|
|
|
|
text_renderer_.printPhysical(text_pos_, margin, text_.c_str(), text_color_r, text_color_g, text_color_b, text_scale_x, text_scale_y);
|
|
|
|
|
|
|
|
|
|
// Mostrar nombre del tema en castellano debajo del número de pelotas
|
|
|
|
|
// (solo si text_ NO es ya el nombre del tema, para evitar duplicación)
|
|
|
|
|
@@ -904,7 +895,7 @@ void Engine::render() {
|
|
|
|
|
int theme_y = margin + line_height; // Espaciado dinámico
|
|
|
|
|
|
|
|
|
|
// Texto del nombre del tema con el mismo color
|
|
|
|
|
text_renderer_.print(theme_x, theme_y, theme_name_es, text_color_r, text_color_g, text_color_b);
|
|
|
|
|
text_renderer_.printPhysical(theme_x, theme_y, theme_name_es, text_color_r, text_color_g, text_color_b, text_scale_x, text_scale_y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -918,10 +909,10 @@ void Engine::render() {
|
|
|
|
|
// Mostrar contador de FPS en esquina superior derecha
|
|
|
|
|
int fps_text_width = text_renderer_debug_.getTextWidth(fps_text_.c_str());
|
|
|
|
|
int fps_x = current_screen_width_ - fps_text_width - margin;
|
|
|
|
|
text_renderer_debug_.print(fps_x, current_y, fps_text_.c_str(), 255, 255, 0); // Amarillo
|
|
|
|
|
text_renderer_debug_.printPhysical(fps_x, current_y, fps_text_.c_str(), 255, 255, 0, text_scale_x, text_scale_y); // Amarillo
|
|
|
|
|
|
|
|
|
|
// Mostrar estado V-Sync en esquina superior izquierda
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, vsync_text_.c_str(), 0, 255, 255); // Cian
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, vsync_text_.c_str(), 0, 255, 255, text_scale_x, text_scale_y); // Cian
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Debug: Mostrar valores de la primera pelota (si existe)
|
|
|
|
|
@@ -929,35 +920,35 @@ void Engine::render() {
|
|
|
|
|
// Línea 1: Gravedad
|
|
|
|
|
int grav_int = static_cast<int>(balls_[0]->getGravityForce());
|
|
|
|
|
std::string grav_text = "Gravedad: " + std::to_string(grav_int);
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, grav_text.c_str(), 255, 0, 255); // Magenta
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, grav_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Línea 2: Velocidad Y
|
|
|
|
|
int vy_int = static_cast<int>(balls_[0]->getVelocityY());
|
|
|
|
|
std::string vy_text = "Velocidad Y: " + std::to_string(vy_int);
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, vy_text.c_str(), 255, 0, 255); // Magenta
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, vy_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Línea 3: Estado superficie
|
|
|
|
|
std::string surface_text = balls_[0]->isOnSurface() ? "Superficie: Sí" : "Superficie: No";
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, surface_text.c_str(), 255, 0, 255); // Magenta
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, surface_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Línea 4: Coeficiente de rebote (loss)
|
|
|
|
|
float loss_val = balls_[0]->getLossCoefficient();
|
|
|
|
|
std::string loss_text = "Rebote: " + std::to_string(loss_val).substr(0, 4);
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, loss_text.c_str(), 255, 0, 255); // Magenta
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, loss_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Línea 5: Dirección de gravedad
|
|
|
|
|
std::string gravity_dir_text = "Dirección: " + gravityDirectionToString(current_gravity_);
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, gravity_dir_text.c_str(), 255, 255, 0); // Amarillo
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, gravity_dir_text.c_str(), 255, 255, 0, text_scale_x, text_scale_y); // Amarillo
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Debug: Mostrar tema actual (delegado a ThemeManager)
|
|
|
|
|
std::string theme_text = std::string("Tema: ") + theme_manager_->getCurrentThemeNameEN();
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, theme_text.c_str(), 255, 255, 128); // Amarillo claro
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, theme_text.c_str(), 255, 255, 128, text_scale_x, text_scale_y); // Amarillo claro
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Debug: Mostrar modo de simulación actual
|
|
|
|
|
@@ -969,14 +960,14 @@ void Engine::render() {
|
|
|
|
|
} else {
|
|
|
|
|
mode_text = "Modo: Forma";
|
|
|
|
|
}
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, mode_text.c_str(), 0, 255, 128); // Verde claro
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, mode_text.c_str(), 0, 255, 128, text_scale_x, text_scale_y); // Verde claro
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Debug: Mostrar convergencia en modo LOGO (solo cuando está activo)
|
|
|
|
|
if (current_app_mode_ == AppMode::LOGO && current_mode_ == SimulationMode::SHAPE) {
|
|
|
|
|
int convergence_percent = static_cast<int>(shape_convergence_ * 100.0f);
|
|
|
|
|
std::string convergence_text = "Convergencia: " + std::to_string(convergence_percent) + "%";
|
|
|
|
|
text_renderer_debug_.print(margin, current_y, convergence_text.c_str(), 255, 128, 0); // Naranja
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, convergence_text.c_str(), 255, 128, 0, text_scale_x, text_scale_y); // Naranja
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -987,17 +978,17 @@ void Engine::render() {
|
|
|
|
|
const char* logo_text = "Modo Logo";
|
|
|
|
|
int logo_text_width = text_renderer_debug_.getTextWidth(logo_text);
|
|
|
|
|
int logo_x = (current_screen_width_ - logo_text_width) / 2;
|
|
|
|
|
text_renderer_debug_.print(logo_x, fixed_y, logo_text, 255, 128, 0); // Naranja
|
|
|
|
|
text_renderer_debug_.printPhysical(logo_x, fixed_y, logo_text, 255, 128, 0, text_scale_x, text_scale_y); // Naranja
|
|
|
|
|
} else if (current_app_mode_ == AppMode::DEMO) {
|
|
|
|
|
const char* demo_text = "Modo Demo";
|
|
|
|
|
int demo_text_width = text_renderer_debug_.getTextWidth(demo_text);
|
|
|
|
|
int demo_x = (current_screen_width_ - demo_text_width) / 2;
|
|
|
|
|
text_renderer_debug_.print(demo_x, fixed_y, demo_text, 255, 165, 0); // Naranja
|
|
|
|
|
text_renderer_debug_.printPhysical(demo_x, fixed_y, demo_text, 255, 165, 0, text_scale_x, text_scale_y); // Naranja
|
|
|
|
|
} else if (current_app_mode_ == AppMode::DEMO_LITE) {
|
|
|
|
|
const char* lite_text = "Modo Demo Lite";
|
|
|
|
|
int lite_text_width = text_renderer_debug_.getTextWidth(lite_text);
|
|
|
|
|
int lite_x = (current_screen_width_ - lite_text_width) / 2;
|
|
|
|
|
text_renderer_debug_.print(lite_x, fixed_y, lite_text, 255, 200, 0); // Amarillo-naranja
|
|
|
|
|
text_renderer_debug_.printPhysical(lite_x, fixed_y, lite_text, 255, 200, 0, text_scale_x, text_scale_y); // Amarillo-naranja
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1174,6 +1165,9 @@ void Engine::toggleRealFullscreen() {
|
|
|
|
|
// Actualizar presentación lógica del renderizador
|
|
|
|
|
SDL_SetRenderLogicalPresentation(renderer_, current_screen_width_, current_screen_height_, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
|
|
|
|
|
|
|
|
|
|
// Actualizar tamaño físico de ventana y fuentes
|
|
|
|
|
updatePhysicalWindowSize();
|
|
|
|
|
|
|
|
|
|
// Reinicar la escena con nueva resolución
|
|
|
|
|
initBalls(scenario_);
|
|
|
|
|
}
|
|
|
|
|
@@ -1191,6 +1185,9 @@ void Engine::toggleRealFullscreen() {
|
|
|
|
|
// Restaurar presentación lógica base
|
|
|
|
|
SDL_SetRenderLogicalPresentation(renderer_, base_screen_width_, base_screen_height_, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
|
|
|
|
|
|
|
|
|
|
// Actualizar tamaño físico de ventana y fuentes
|
|
|
|
|
updatePhysicalWindowSize();
|
|
|
|
|
|
|
|
|
|
// Reinicar la escena con resolución original
|
|
|
|
|
initBalls(scenario_);
|
|
|
|
|
}
|
|
|
|
|
@@ -1376,6 +1373,9 @@ void Engine::setWindowZoom(int new_zoom) {
|
|
|
|
|
SDL_SetWindowSize(window_, new_width, new_height);
|
|
|
|
|
SDL_SetWindowPosition(window_, new_x, new_y);
|
|
|
|
|
current_window_zoom_ = new_zoom;
|
|
|
|
|
|
|
|
|
|
// Actualizar tamaño físico de ventana y fuentes
|
|
|
|
|
updatePhysicalWindowSize();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Engine::zoomIn() {
|
|
|
|
|
@@ -1386,6 +1386,31 @@ void Engine::zoomOut() {
|
|
|
|
|
setWindowZoom(current_window_zoom_ - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Engine::updatePhysicalWindowSize() {
|
|
|
|
|
if (real_fullscreen_enabled_) {
|
|
|
|
|
// En fullscreen real, usar resolución del display
|
|
|
|
|
physical_window_width_ = current_screen_width_;
|
|
|
|
|
physical_window_height_ = current_screen_height_;
|
|
|
|
|
} else {
|
|
|
|
|
// En modo ventana, obtener tamaño real de la ventana (lógica * zoom)
|
|
|
|
|
int window_w = 0, window_h = 0;
|
|
|
|
|
SDL_GetWindowSize(window_, &window_w, &window_h);
|
|
|
|
|
physical_window_width_ = window_w;
|
|
|
|
|
physical_window_height_ = window_h;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Recalcular tamaño de fuente basado en altura física
|
|
|
|
|
// Referencia: 8px a 1440p (monitor del usuario)
|
|
|
|
|
int font_size = (physical_window_height_ * TEXT_BASE_SIZE) / 1440;
|
|
|
|
|
if (font_size < 6) font_size = 6; // Tamaño mínimo legible
|
|
|
|
|
|
|
|
|
|
// Reinicializar TextRenderers con nuevo tamaño de fuente
|
|
|
|
|
text_renderer_.cleanup();
|
|
|
|
|
text_renderer_debug_.cleanup();
|
|
|
|
|
text_renderer_.init(renderer_, TEXT_FONT_PATH, font_size, TEXT_ANTIALIASING);
|
|
|
|
|
text_renderer_debug_.init(renderer_, TEXT_FONT_PATH, font_size, TEXT_ANTIALIASING);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Sistema de gestión de estados (MANUAL/DEMO/DEMO_LITE/LOGO)
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|