|
|
|
|
@@ -83,6 +83,9 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen) {
|
|
|
|
|
window_zoom = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Guardar zoom calculado ANTES de crear la ventana (para F1/F2/F3/F4)
|
|
|
|
|
current_window_zoom_ = window_zoom;
|
|
|
|
|
|
|
|
|
|
// Calcular tamaño de ventana
|
|
|
|
|
int window_width = logical_width * window_zoom;
|
|
|
|
|
int window_height = logical_height * window_zoom;
|
|
|
|
|
@@ -108,6 +111,11 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen) {
|
|
|
|
|
std::cout << "¡No se pudo crear la ventana! Error de SDL: " << SDL_GetError() << std::endl;
|
|
|
|
|
success = false;
|
|
|
|
|
} else {
|
|
|
|
|
// Centrar ventana en pantalla si no está en fullscreen
|
|
|
|
|
if (!fullscreen) {
|
|
|
|
|
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Crear renderizador
|
|
|
|
|
renderer_ = SDL_CreateRenderer(window_, nullptr);
|
|
|
|
|
if (renderer_ == nullptr) {
|
|
|
|
|
@@ -330,12 +338,12 @@ void Engine::handleEvents() {
|
|
|
|
|
// Si estamos en modo figura, salir a modo física SIN GRAVEDAD
|
|
|
|
|
if (current_mode_ == SimulationMode::SHAPE) {
|
|
|
|
|
toggleShapeMode(false); // Desactivar figura sin forzar gravedad ON
|
|
|
|
|
showNotificationForAction("Gravity Off");
|
|
|
|
|
showNotificationForAction("Gravedad Off");
|
|
|
|
|
} else {
|
|
|
|
|
switchBallsGravity(); // Toggle normal en modo física
|
|
|
|
|
// Determinar estado actual de gravedad (gravity_force_ != 0.0f significa ON)
|
|
|
|
|
bool gravity_on = balls_.empty() ? true : (balls_[0]->getGravityForce() != 0.0f);
|
|
|
|
|
showNotificationForAction(gravity_on ? "Gravity On" : "Gravity Off");
|
|
|
|
|
showNotificationForAction(gravity_on ? "Gravedad On" : "Gravedad Off");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
@@ -348,7 +356,7 @@ void Engine::handleEvents() {
|
|
|
|
|
enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF
|
|
|
|
|
}
|
|
|
|
|
changeGravityDirection(GravityDirection::UP);
|
|
|
|
|
showNotificationForAction("Gravity Up");
|
|
|
|
|
showNotificationForAction("Gravedad Arriba");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_DOWN:
|
|
|
|
|
@@ -359,7 +367,7 @@ void Engine::handleEvents() {
|
|
|
|
|
enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF
|
|
|
|
|
}
|
|
|
|
|
changeGravityDirection(GravityDirection::DOWN);
|
|
|
|
|
showNotificationForAction("Gravity Down");
|
|
|
|
|
showNotificationForAction("Gravedad Abajo");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_LEFT:
|
|
|
|
|
@@ -370,7 +378,7 @@ void Engine::handleEvents() {
|
|
|
|
|
enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF
|
|
|
|
|
}
|
|
|
|
|
changeGravityDirection(GravityDirection::LEFT);
|
|
|
|
|
showNotificationForAction("Gravity Left");
|
|
|
|
|
showNotificationForAction("Gravedad Izquierda");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_RIGHT:
|
|
|
|
|
@@ -381,7 +389,7 @@ void Engine::handleEvents() {
|
|
|
|
|
enableBallsGravityIfDisabled(); // Reactivar gravedad si estaba OFF
|
|
|
|
|
}
|
|
|
|
|
changeGravityDirection(GravityDirection::RIGHT);
|
|
|
|
|
showNotificationForAction("Gravity Right");
|
|
|
|
|
showNotificationForAction("Gravedad Derecha");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_V:
|
|
|
|
|
@@ -397,10 +405,11 @@ void Engine::handleEvents() {
|
|
|
|
|
toggleShapeMode();
|
|
|
|
|
// Mostrar notificación según el modo actual después del toggle
|
|
|
|
|
if (current_mode_ == SimulationMode::PHYSICS) {
|
|
|
|
|
showNotificationForAction("Physics Mode");
|
|
|
|
|
showNotificationForAction("Modo Física");
|
|
|
|
|
} else {
|
|
|
|
|
// Mostrar nombre de la figura actual
|
|
|
|
|
const char* shape_names[] = {"Sphere", "Lissajous", "Helix", "Torus", "Cube", "Cylinder", "Icosahedron", "Atom", "PNG Shape"};
|
|
|
|
|
// Mostrar nombre de la figura actual (orden debe coincidir con enum ShapeType)
|
|
|
|
|
// Índices: 0=NONE, 1=SPHERE, 2=CUBE, 3=HELIX, 4=TORUS, 5=LISSAJOUS, 6=CYLINDER, 7=ICOSAHEDRON, 8=ATOM, 9=PNG_SHAPE
|
|
|
|
|
const char* shape_names[] = {"Ninguna", "Esfera", "Cubo", "Hélice", "Toroide", "Lissajous", "Cilindro", "Icosaedro", "Átomo", "Forma PNG"};
|
|
|
|
|
showNotificationForAction(shape_names[static_cast<int>(current_shape_type_)]);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
@@ -408,7 +417,7 @@ void Engine::handleEvents() {
|
|
|
|
|
// Selección directa de figuras 3D
|
|
|
|
|
case SDLK_Q:
|
|
|
|
|
activateShape(ShapeType::SPHERE);
|
|
|
|
|
showNotificationForAction("Sphere");
|
|
|
|
|
showNotificationForAction("Esfera");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_W:
|
|
|
|
|
@@ -418,37 +427,37 @@ void Engine::handleEvents() {
|
|
|
|
|
|
|
|
|
|
case SDLK_E:
|
|
|
|
|
activateShape(ShapeType::HELIX);
|
|
|
|
|
showNotificationForAction("Helix");
|
|
|
|
|
showNotificationForAction("Hélice");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_R:
|
|
|
|
|
activateShape(ShapeType::TORUS);
|
|
|
|
|
showNotificationForAction("Torus");
|
|
|
|
|
showNotificationForAction("Toroide");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_T:
|
|
|
|
|
activateShape(ShapeType::CUBE);
|
|
|
|
|
showNotificationForAction("Cube");
|
|
|
|
|
showNotificationForAction("Cubo");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_Y:
|
|
|
|
|
activateShape(ShapeType::CYLINDER);
|
|
|
|
|
showNotificationForAction("Cylinder");
|
|
|
|
|
showNotificationForAction("Cilindro");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_U:
|
|
|
|
|
activateShape(ShapeType::ICOSAHEDRON);
|
|
|
|
|
showNotificationForAction("Icosahedron");
|
|
|
|
|
showNotificationForAction("Icosaedro");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_I:
|
|
|
|
|
activateShape(ShapeType::ATOM);
|
|
|
|
|
showNotificationForAction("Atom");
|
|
|
|
|
showNotificationForAction("Átomo");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SDLK_O:
|
|
|
|
|
activateShape(ShapeType::PNG_SHAPE);
|
|
|
|
|
showNotificationForAction("PNG Shape");
|
|
|
|
|
showNotificationForAction("Forma PNG");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Ciclar temas de color (movido de T a B)
|
|
|
|
|
@@ -594,7 +603,7 @@ void Engine::handleEvents() {
|
|
|
|
|
case SDLK_KP_DIVIDE:
|
|
|
|
|
if (current_mode_ == SimulationMode::SHAPE) {
|
|
|
|
|
depth_zoom_enabled_ = !depth_zoom_enabled_;
|
|
|
|
|
showNotificationForAction(depth_zoom_enabled_ ? "Depth Zoom On" : "Depth Zoom Off");
|
|
|
|
|
showNotificationForAction(depth_zoom_enabled_ ? "Profundidad On" : "Profundidad Off");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
@@ -818,10 +827,6 @@ 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_);
|
|
|
|
|
|
|
|
|
|
// SISTEMA DE TEXTO ANTIGUO DESHABILITADO
|
|
|
|
|
// Reemplazado completamente por el sistema de notificaciones (Notifier)
|
|
|
|
|
// El doble renderizado causaba que aparecieran textos duplicados detrás de las notificaciones
|
|
|
|
|
@@ -856,16 +861,16 @@ void Engine::render() {
|
|
|
|
|
if (show_debug_) {
|
|
|
|
|
// Obtener altura de línea para espaciado dinámico (usando fuente debug)
|
|
|
|
|
int line_height = text_renderer_debug_.getTextHeight();
|
|
|
|
|
int margin = 8; // Margen constante
|
|
|
|
|
int current_y = margin; // Y inicial
|
|
|
|
|
int margin = 8; // Margen constante en píxeles físicos
|
|
|
|
|
int current_y = margin; // Y inicial en píxeles físicos
|
|
|
|
|
|
|
|
|
|
// 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_.printPhysical(fps_x, current_y, fps_text_.c_str(), 255, 255, 0, text_scale_x, text_scale_y); // Amarillo
|
|
|
|
|
int fps_text_width = text_renderer_debug_.getTextWidthPhysical(fps_text_.c_str());
|
|
|
|
|
int fps_x = physical_window_width_ - fps_text_width - margin;
|
|
|
|
|
text_renderer_debug_.printAbsolute(fps_x, current_y, fps_text_.c_str(), {255, 255, 0, 255}); // Amarillo
|
|
|
|
|
|
|
|
|
|
// Mostrar estado V-Sync en esquina superior izquierda
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, vsync_text_.c_str(), 0, 255, 255, text_scale_x, text_scale_y); // Cian
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, vsync_text_.c_str(), {0, 255, 255, 255}); // Cian
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Debug: Mostrar valores de la primera pelota (si existe)
|
|
|
|
|
@@ -873,35 +878,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_.printPhysical(margin, current_y, grav_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, grav_text.c_str(), {255, 0, 255, 255}); // 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_.printPhysical(margin, current_y, vy_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, vy_text.c_str(), {255, 0, 255, 255}); // Magenta
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Línea 3: Estado superficie
|
|
|
|
|
std::string surface_text = balls_[0]->isOnSurface() ? "Superficie: Sí" : "Superficie: No";
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, surface_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, surface_text.c_str(), {255, 0, 255, 255}); // 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_.printPhysical(margin, current_y, loss_text.c_str(), 255, 0, 255, text_scale_x, text_scale_y); // Magenta
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, loss_text.c_str(), {255, 0, 255, 255}); // 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_.printPhysical(margin, current_y, gravity_dir_text.c_str(), 255, 255, 0, text_scale_x, text_scale_y); // Amarillo
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, gravity_dir_text.c_str(), {255, 255, 0, 255}); // 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_.printPhysical(margin, current_y, theme_text.c_str(), 255, 255, 128, text_scale_x, text_scale_y); // Amarillo claro
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, theme_text.c_str(), {255, 255, 128, 255}); // Amarillo claro
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
|
|
|
|
|
// Debug: Mostrar modo de simulación actual
|
|
|
|
|
@@ -913,14 +918,14 @@ void Engine::render() {
|
|
|
|
|
} else {
|
|
|
|
|
mode_text = "Modo: Forma";
|
|
|
|
|
}
|
|
|
|
|
text_renderer_debug_.printPhysical(margin, current_y, mode_text.c_str(), 0, 255, 128, text_scale_x, text_scale_y); // Verde claro
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, mode_text.c_str(), {0, 255, 128, 255}); // 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_.printPhysical(margin, current_y, convergence_text.c_str(), 255, 128, 0, text_scale_x, text_scale_y); // Naranja
|
|
|
|
|
text_renderer_debug_.printAbsolute(margin, current_y, convergence_text.c_str(), {255, 128, 0, 255}); // Naranja
|
|
|
|
|
current_y += line_height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -929,19 +934,19 @@ void Engine::render() {
|
|
|
|
|
int fixed_y = margin + (line_height * 2); // Tercera fila fija
|
|
|
|
|
if (current_app_mode_ == AppMode::LOGO) {
|
|
|
|
|
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_.printPhysical(logo_x, fixed_y, logo_text, 255, 128, 0, text_scale_x, text_scale_y); // Naranja
|
|
|
|
|
int logo_text_width = text_renderer_debug_.getTextWidthPhysical(logo_text);
|
|
|
|
|
int logo_x = (physical_window_width_ - logo_text_width) / 2;
|
|
|
|
|
text_renderer_debug_.printAbsolute(logo_x, fixed_y, logo_text, {255, 128, 0, 255}); // 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_.printPhysical(demo_x, fixed_y, demo_text, 255, 165, 0, text_scale_x, text_scale_y); // Naranja
|
|
|
|
|
int demo_text_width = text_renderer_debug_.getTextWidthPhysical(demo_text);
|
|
|
|
|
int demo_x = (physical_window_width_ - demo_text_width) / 2;
|
|
|
|
|
text_renderer_debug_.printAbsolute(demo_x, fixed_y, demo_text, {255, 165, 0, 255}); // 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_.printPhysical(lite_x, fixed_y, lite_text, 255, 200, 0, text_scale_x, text_scale_y); // Amarillo-naranja
|
|
|
|
|
int lite_text_width = text_renderer_debug_.getTextWidthPhysical(lite_text);
|
|
|
|
|
int lite_x = (physical_window_width_ - lite_text_width) / 2;
|
|
|
|
|
text_renderer_debug_.printAbsolute(lite_x, fixed_y, lite_text, {255, 200, 0, 255}); // Amarillo-naranja
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1160,9 +1165,10 @@ void Engine::toggleRealFullscreen() {
|
|
|
|
|
current_screen_width_ = base_screen_width_;
|
|
|
|
|
current_screen_height_ = base_screen_height_;
|
|
|
|
|
|
|
|
|
|
// Restaurar ventana normal
|
|
|
|
|
// Restaurar ventana normal con el zoom actual (no hardcoded)
|
|
|
|
|
SDL_SetWindowFullscreen(window_, false);
|
|
|
|
|
SDL_SetWindowSize(window_, base_screen_width_ * DEFAULT_WINDOW_ZOOM, base_screen_height_ * DEFAULT_WINDOW_ZOOM);
|
|
|
|
|
SDL_SetWindowSize(window_, base_screen_width_ * current_window_zoom_, base_screen_height_ * current_window_zoom_);
|
|
|
|
|
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
|
|
|
|
|
|
|
|
|
// Restaurar presentación lógica base
|
|
|
|
|
SDL_SetRenderLogicalPresentation(renderer_, base_screen_width_, base_screen_height_, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
|
|
|
|
|
@@ -1622,9 +1628,10 @@ void Engine::updateDemoMode() {
|
|
|
|
|
demo_next_action_time_ = logo_min_time_ + (rand() % 1000) / 1000.0f * interval_range;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Solo salir automáticamente si NO llegamos desde MANUAL
|
|
|
|
|
// Solo salir automáticamente si la entrada a LOGO fue automática (desde DEMO)
|
|
|
|
|
// No salir si el usuario entró manualmente con tecla K
|
|
|
|
|
// Probabilidad de salir: 60% en cada acción → sale rápido (relación DEMO:LOGO = 6:1)
|
|
|
|
|
if (previous_app_mode_ != AppMode::SANDBOX && rand() % 100 < 60) {
|
|
|
|
|
if (!logo_entered_manually_ && rand() % 100 < 60) {
|
|
|
|
|
exitLogoMode(true); // Volver a DEMO/DEMO_LITE
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -1831,6 +1838,15 @@ void Engine::performDemoAction(bool is_lite) {
|
|
|
|
|
|
|
|
|
|
// Randomizar todo al iniciar modo DEMO
|
|
|
|
|
void Engine::randomizeOnDemoStart(bool is_lite) {
|
|
|
|
|
// Si venimos de LOGO con PNG_SHAPE, cambiar figura obligatoriamente
|
|
|
|
|
// PNG_SHAPE es exclusivo del modo LOGO y no debe aparecer en DEMO/DEMO_LITE
|
|
|
|
|
if (current_shape_type_ == ShapeType::PNG_SHAPE) {
|
|
|
|
|
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::LISSAJOUS, ShapeType::HELIX,
|
|
|
|
|
ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER,
|
|
|
|
|
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
|
|
|
|
activateShape(shapes[rand() % 8]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_lite) {
|
|
|
|
|
// DEMO LITE: Solo randomizar física/figura + gravedad
|
|
|
|
|
// Elegir aleatoriamente entre modo física o figura
|
|
|
|
|
@@ -1932,18 +1948,18 @@ void Engine::enterLogoMode(bool from_demo) {
|
|
|
|
|
logo_previous_texture_index_ = current_texture_index_;
|
|
|
|
|
logo_previous_shape_scale_ = shape_scale_factor_;
|
|
|
|
|
|
|
|
|
|
// Buscar índice de textura "tiny"
|
|
|
|
|
size_t tiny_index = current_texture_index_; // Por defecto mantener actual
|
|
|
|
|
// Buscar índice de textura "small"
|
|
|
|
|
size_t small_index = current_texture_index_; // Por defecto mantener actual
|
|
|
|
|
for (size_t i = 0; i < texture_names_.size(); i++) {
|
|
|
|
|
if (texture_names_[i] == "tiny") {
|
|
|
|
|
tiny_index = i;
|
|
|
|
|
if (texture_names_[i] == "small") {
|
|
|
|
|
small_index = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aplicar configuración fija del Modo Logo
|
|
|
|
|
if (tiny_index != current_texture_index_) {
|
|
|
|
|
current_texture_index_ = tiny_index;
|
|
|
|
|
if (small_index != current_texture_index_) {
|
|
|
|
|
current_texture_index_ = small_index;
|
|
|
|
|
int old_size = current_ball_size_;
|
|
|
|
|
current_ball_size_ = textures_[current_texture_index_]->getWidth();
|
|
|
|
|
updateBallSizes(old_size, current_ball_size_);
|
|
|
|
|
@@ -1955,8 +1971,10 @@ void Engine::enterLogoMode(bool from_demo) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Cambiar a tema MONOCHROME
|
|
|
|
|
theme_manager_->switchToTheme(5); // MONOCHROME
|
|
|
|
|
// Cambiar a tema aleatorio entre: MONOCHROME, LAVENDER, CRIMSON, ESMERALDA
|
|
|
|
|
int logo_themes[] = {5, 6, 7, 8}; // MONOCHROME, LAVENDER, CRIMSON, ESMERALDA
|
|
|
|
|
int random_theme = logo_themes[rand() % 4];
|
|
|
|
|
theme_manager_->switchToTheme(random_theme);
|
|
|
|
|
|
|
|
|
|
// Establecer escala a 120%
|
|
|
|
|
shape_scale_factor_ = LOGO_MODE_SHAPE_SCALE;
|
|
|
|
|
@@ -1980,6 +1998,9 @@ void Engine::enterLogoMode(bool from_demo) {
|
|
|
|
|
logo_target_flip_percentage_ = 0.0f;
|
|
|
|
|
logo_current_flip_count_ = 0;
|
|
|
|
|
|
|
|
|
|
// Guardar si entrada fue manual (tecla K) o automática (desde DEMO)
|
|
|
|
|
logo_entered_manually_ = !from_demo;
|
|
|
|
|
|
|
|
|
|
// Cambiar a modo LOGO (guarda previous_app_mode_ automáticamente)
|
|
|
|
|
setState(AppMode::LOGO);
|
|
|
|
|
}
|
|
|
|
|
@@ -2017,12 +2038,23 @@ void Engine::exitLogoMode(bool return_to_demo) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resetear flag de entrada manual
|
|
|
|
|
logo_entered_manually_ = false;
|
|
|
|
|
|
|
|
|
|
if (!return_to_demo) {
|
|
|
|
|
// Salida manual (tecla K): volver a MANUAL
|
|
|
|
|
setState(AppMode::SANDBOX);
|
|
|
|
|
} else {
|
|
|
|
|
// Volver al modo previo (DEMO o DEMO_LITE)
|
|
|
|
|
setState(previous_app_mode_);
|
|
|
|
|
|
|
|
|
|
// Si la figura activa es PNG_SHAPE, cambiar a otra figura aleatoria
|
|
|
|
|
if (current_shape_type_ == ShapeType::PNG_SHAPE) {
|
|
|
|
|
ShapeType shapes[] = {ShapeType::SPHERE, ShapeType::LISSAJOUS, ShapeType::HELIX,
|
|
|
|
|
ShapeType::TORUS, ShapeType::CUBE, ShapeType::CYLINDER,
|
|
|
|
|
ShapeType::ICOSAHEDRON, ShapeType::ATOM};
|
|
|
|
|
activateShape(shapes[rand() % 8]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|