diff --git a/source/core/audio/audio.hpp b/source/core/audio/audio.hpp index dc02f50..21cb5d2 100644 --- a/source/core/audio/audio.hpp +++ b/source/core/audio/audio.hpp @@ -3,7 +3,6 @@ #include // Para lround #include // Para int8_t, uint8_t #include // Para string -#include // Para move // --- Clase Audio: gestor de audio (singleton) --- // Implementació canònica, byte-idèntica entre projectes. diff --git a/source/core/input/input.h b/source/core/input/input.h index 3ddcbbe..30b9318 100644 --- a/source/core/input/input.h +++ b/source/core/input/input.h @@ -59,12 +59,12 @@ class Input { ~Input(); // Destructor - void update(); // Actualiza el estado del objeto - void bindKey(Uint8 input, SDL_Scancode code); // Asigna inputs a teclas + void update(); // Actualiza el estado del objeto + void bindKey(Uint8 input, SDL_Scancode code); // Asigna inputs a teclas void bindGameControllerButton(Uint8 input, SDL_GamepadButton button); // Asigna inputs a botones del mando auto checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si un input esta activo - auto checkAnyInput(int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si hay almenos un input activo + auto checkAnyInput(int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si hay almenos un input activo auto discoverGameController() -> bool; // Busca si hay un mando conectado @@ -80,9 +80,9 @@ class Input { [[nodiscard]] auto getNumControllers() const -> int; // Obten el numero de mandos conectados auto getControllerName(int index) -> std::string; // Obten el nombre de un mando de juego - void setVerbose(bool value); // Establece si ha de mostrar mensajes - void disableUntil(InputDisable value); // Deshabilita las entradas durante un periodo de tiempo - void enable(); // Hablita las entradas + void setVerbose(bool value); // Establece si ha de mostrar mensajes + void disableUntil(InputDisable value); // Deshabilita las entradas durante un periodo de tiempo + void enable(); // Hablita las entradas private: struct KeyBindings { @@ -96,18 +96,18 @@ class Input { }; // Objetos y punteros - std::vector connected_controllers_; // Vector con todos los mandos conectados - std::vector connected_controller_ids_; // Instance IDs paralelos para mapear eventos + std::vector connected_controllers_; // Vector con todos los mandos conectados + std::vector connected_controller_ids_; // Instance IDs paralelos para mapear eventos // Variables - std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos - std::vector game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos - std::vector controller_names_; // Vector con los nombres de los mandos - int num_gamepads_{0}; // Numero de mandos conectados - std::string db_path_; // Ruta al archivo gamecontrollerdb.txt - bool verbose_{true}; // Indica si ha de mostrar mensajes - InputDisable disabled_until_{NOT_DISABLED}; // Tiempo que esta deshabilitado - bool enabled_{true}; // Indica si está habilitado + std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos + std::vector game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos + std::vector controller_names_; // Vector con los nombres de los mandos + int num_gamepads_{0}; // Numero de mandos conectados + std::string db_path_; // Ruta al archivo gamecontrollerdb.txt + bool verbose_{true}; // Indica si ha de mostrar mensajes + InputDisable disabled_until_{NOT_DISABLED}; // Tiempo que esta deshabilitado + bool enabled_{true}; // Indica si está habilitado static Input *instance; // Instancia única diff --git a/source/core/input/mouse.cpp b/source/core/input/mouse.cpp index 069015b..b14bfef 100644 --- a/source/core/input/mouse.cpp +++ b/source/core/input/mouse.cpp @@ -1,9 +1,9 @@ #include "core/input/mouse.hpp" namespace Mouse { - Uint32 cursor_hide_time = 3000; // Tiempo en milisegundos para ocultar el cursor por inactividad + Uint32 cursor_hide_time = 3000; // Tiempo en milisegundos para ocultar el cursor por inactividad Uint32 last_mouse_move_time = 0; // Última vez que el ratón se movió - bool cursor_visible = true; // Estado del cursor + bool cursor_visible = true; // Estado del cursor void handleEvent(const SDL_Event &event, bool fullscreen) { if (event.type == SDL_EVENT_MOUSE_MOTION) { diff --git a/source/core/locale/lang.h b/source/core/locale/lang.h index 1912046..760b496 100644 --- a/source/core/locale/lang.h +++ b/source/core/locale/lang.h @@ -24,8 +24,8 @@ class Lang { ~Lang(); // Destructor - auto setLang(Code lang) -> bool; // Inicializa los textos del juego en el idioma seleccionado - auto getText(int index) -> std::string; // Obtiene la cadena de texto del indice + auto setLang(Code lang) -> bool; // Inicializa los textos del juego en el idioma seleccionado + auto getText(int index) -> std::string; // Obtiene la cadena de texto del indice static auto nextLanguage(Code c) -> Code; // Devuelve el siguiente idioma del ciclo diff --git a/source/core/rendering/animatedsprite.h b/source/core/rendering/animatedsprite.h index f9e656e..3dd7847 100644 --- a/source/core/rendering/animatedsprite.h +++ b/source/core/rendering/animatedsprite.h @@ -15,7 +15,7 @@ struct Animation { int speed; // Velocidad de la animación int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva bool completed; // Indica si ha finalizado la animación - int current_frame; // Frame actual + int current_frame; // Frame actual int counter; // Contador para las animaciones }; @@ -37,9 +37,9 @@ class AnimatedSprite : public MovingSprite { ~AnimatedSprite() override; // Destructor - void animate(); // Calcula el frame correspondiente a la animación actual - auto getNumFrames() -> int; // Obtiene el numero de frames de la animación actual - void setCurrentFrame(int num); // Establece el frame actual de la animación + void animate(); // Calcula el frame correspondiente a la animación actual + auto getNumFrames() -> int; // Obtiene el numero de frames de la animación actual + void setCurrentFrame(int num); // Establece el frame actual de la animación void setAnimationCounter(const std::string &name, int num); // Establece el valor del contador void setAnimationSpeed(const std::string &name, int speed); // Establece la velocidad de una animación @@ -56,7 +56,7 @@ class AnimatedSprite : public MovingSprite { auto getAnimationClip(const std::string &name = "default", Uint8 index = 0) -> SDL_Rect; // Devuelve el rectangulo de una animación y frame concreto auto getAnimationClip(int index_a = 0, Uint8 index_f = 0) -> SDL_Rect; - auto getIndex(const std::string &name) -> int; // Obtiene el indice de la animación a partir del nombre + auto getIndex(const std::string &name) -> int; // Obtiene el indice de la animación a partir del nombre auto loadFromVector(std::vector *source) -> bool; // Carga la animación desde un vector void setCurrentAnimation(const std::string &name = "default"); // Establece la animacion actual @@ -65,12 +65,12 @@ class AnimatedSprite : public MovingSprite { void update() override; // Actualiza las variables del objeto void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h); // OLD - Establece el rectangulo para un frame de una animación - void setAnimationCounter(int value); // OLD - Establece el contador para todas las animaciones + void setAnimationCounter(int value); // OLD - Establece el contador para todas las animaciones void resetAnimation(); // Reinicia la animación private: // Variables std::vector animation_; // Vector con las diferentes animaciones - int current_animation_; // Animacion activa + int current_animation_; // Animacion activa }; diff --git a/source/core/rendering/fade.h b/source/core/rendering/fade.h index 9a7a620..8db7554 100644 --- a/source/core/rendering/fade.h +++ b/source/core/rendering/fade.h @@ -24,17 +24,17 @@ class Fade { void setFadeType(Uint8 fade_type); // Establece el tipo de fade private: - SDL_Renderer *renderer_ = nullptr; // El renderizador de la ventana - SDL_Texture *backbuffer_ = nullptr; // Textura para usar como backbuffer - Uint8 fade_type_ = FADE_FULLSCREEN; // Tipo de fade a realizar - Uint16 counter_ = 0; // Contador interno - bool enabled_ = false; // Indica si el fade está activo - bool finished_ = false; // Indica si ha terminado la transición - Uint8 r_ = 0, g_ = 0, b_ = 0; // Colores para el fade + SDL_Renderer *renderer_ = nullptr; // El renderizador de la ventana + SDL_Texture *backbuffer_ = nullptr; // Textura para usar como backbuffer + Uint8 fade_type_ = FADE_FULLSCREEN; // Tipo de fade a realizar + Uint16 counter_ = 0; // Contador interno + bool enabled_ = false; // Indica si el fade está activo + bool finished_ = false; // Indica si ha terminado la transición + Uint8 r_ = 0, g_ = 0, b_ = 0; // Colores para el fade Uint8 r_original_ = 0, g_original_ = 0, b_original_ = 0; // Colores originales para FADE_RANDOM_SQUARE - Uint32 last_square_ticks_ = 0; // Ticks del último cuadrado dibujado (FADE_RANDOM_SQUARE) - Uint16 squares_drawn_ = 0; // Número de cuadrados dibujados (FADE_RANDOM_SQUARE) - bool fullscreen_done_ = false; // Indica si el fade fullscreen ha terminado la fase de fundido - SDL_Rect rect1_{}; // Rectangulo usado para crear los efectos de transición - SDL_Rect rect2_{}; // Rectangulo usado para crear los efectos de transición + Uint32 last_square_ticks_ = 0; // Ticks del último cuadrado dibujado (FADE_RANDOM_SQUARE) + Uint16 squares_drawn_ = 0; // Número de cuadrados dibujados (FADE_RANDOM_SQUARE) + bool fullscreen_done_ = false; // Indica si el fade fullscreen ha terminado la fase de fundido + SDL_Rect rect1_{}; // Rectangulo usado para crear los efectos de transición + SDL_Rect rect2_{}; // Rectangulo usado para crear los efectos de transición }; diff --git a/source/core/rendering/movingsprite.h b/source/core/rendering/movingsprite.h index e45a6c5..ae2f762 100644 --- a/source/core/rendering/movingsprite.h +++ b/source/core/rendering/movingsprite.h @@ -21,15 +21,15 @@ class MovingSprite : public Sprite { // cppcheck-suppress duplInheritedMember [[nodiscard]] auto getPosY() const -> float; // Obten el valor de la variable - [[nodiscard]] auto getVelX() const -> float; // Obten el valor de la variable - [[nodiscard]] auto getVelY() const -> float; // Obten el valor de la variable - [[nodiscard]] auto getAccelX() const -> float; // Obten el valor de la variable - [[nodiscard]] auto getAccelY() const -> float; // Obten el valor de la variable - [[nodiscard]] auto getZoomW() const -> float; // Obten el valor de la variable - [[nodiscard]] auto getZoomH() const -> float; // Obten el valor de la variable - [[nodiscard]] auto getAngle() const -> double; // Obten el valor de la variable - [[nodiscard]] auto getRotate() const -> bool; // Obtiene el valor de la variable - [[nodiscard]] auto getRotateSpeed() const -> Uint16; // Obtiene el valor de la variable + [[nodiscard]] auto getVelX() const -> float; // Obten el valor de la variable + [[nodiscard]] auto getVelY() const -> float; // Obten el valor de la variable + [[nodiscard]] auto getAccelX() const -> float; // Obten el valor de la variable + [[nodiscard]] auto getAccelY() const -> float; // Obten el valor de la variable + [[nodiscard]] auto getZoomW() const -> float; // Obten el valor de la variable + [[nodiscard]] auto getZoomH() const -> float; // Obten el valor de la variable + [[nodiscard]] auto getAngle() const -> double; // Obten el valor de la variable + [[nodiscard]] auto getRotate() const -> bool; // Obtiene el valor de la variable + [[nodiscard]] auto getRotateSpeed() const -> Uint16; // Obtiene el valor de la variable void setRect(SDL_Rect rect) override; // Establece la posición y el tamaño del objeto void setPosX(float value); // Establece el valor de la variable @@ -50,9 +50,9 @@ class MovingSprite : public Sprite { void disableRotate(); // Quita el efecto de rotación y deja el sprite en su angulo inicial. void switchRotate(); // Cambia el sentido de la rotación - void setFlip(SDL_FlipMode flip); // Establece el valor de la variable - void flip(); // Gira el sprite horizontalmente - auto getFlip() -> SDL_FlipMode; // Obtiene el valor de la variable + void setFlip(SDL_FlipMode flip); // Establece el valor de la variable + void flip(); // Gira el sprite horizontalmente + auto getFlip() -> SDL_FlipMode; // Obtiene el valor de la variable auto getRect() -> SDL_Rect override; // Devuelve el rectangulo donde está el sprite diff --git a/source/core/rendering/screen.h b/source/core/rendering/screen.h index 5af960b..5efc0cb 100644 --- a/source/core/rendering/screen.h +++ b/source/core/rendering/screen.h @@ -43,25 +43,25 @@ class Screen { void blit(); // Vuelca el contenido del renderizador en pantalla // Video y ventana - void setVideoMode(bool fullscreen); // Establece el modo de video - void toggleVideoMode(); // Cambia entre pantalla completa y ventana - void handleCanvasResized(); // En Emscripten, reaplica setVideoMode tras un cambio del navegador (salida de fullscreen con Esc, rotación). No-op fuera de Emscripten + void setVideoMode(bool fullscreen); // Establece el modo de video + void toggleVideoMode(); // Cambia entre pantalla completa y ventana + void handleCanvasResized(); // En Emscripten, reaplica setVideoMode tras un cambio del navegador (salida de fullscreen con Esc, rotación). No-op fuera de Emscripten static void syncFullscreenFlagFromBrowser(bool is_fullscreen); // Sincroniza el flag interno de fullscreen con el estado real del navegador. Debe llamarse antes de diferir handleCanvasResized. No-op fuera de Emscripten - void toggleIntegerScale(); // Alterna el escalado entero - void setIntegerScale(bool enabled); // Establece el escalado entero - void toggleVSync(); // Alterna el V-Sync - void setVSync(bool enabled); // Establece el V-Sync - auto decWindowZoom() -> bool; // Reduce el zoom de la ventana (devuelve true si cambió) - auto incWindowZoom() -> bool; // Aumenta el zoom de la ventana (devuelve true si cambió) - auto setWindowZoom(int zoom) -> bool; // Establece el zoom de la ventana (devuelve true si cambió) + void toggleIntegerScale(); // Alterna el escalado entero + void setIntegerScale(bool enabled); // Establece el escalado entero + void toggleVSync(); // Alterna el V-Sync + void setVSync(bool enabled); // Establece el V-Sync + auto decWindowZoom() -> bool; // Reduce el zoom de la ventana (devuelve true si cambió) + auto incWindowZoom() -> bool; // Aumenta el zoom de la ventana (devuelve true si cambió) + auto setWindowZoom(int zoom) -> bool; // Establece el zoom de la ventana (devuelve true si cambió) // Borde void setBorderColor(Color color); // Cambia el color del borde // Notificaciones - void initNotifications(); // Enllaça el Text de notificacions amb `Resource`. A cridar després de `Resource::init(...)`. + void initNotifications(); // Enllaça el Text de notificacions amb `Resource`. A cridar després de `Resource::init(...)`. void notify(const std::string &text, Color text_color, Color outline_color, Uint32 duration_ms); // Muestra una notificación en la línea superior del canvas durante durationMs. Sobrescribe cualquier notificación activa (sin apilación). - void clearNotification(); // Limpia la notificación actual + void clearNotification(); // Limpia la notificación actual // GPU / shaders (post-procesado). En builds con NO_SHADERS (Emscripten) son no-op. void initShaders(); // Crea el backend GPU si no existe y lo inicializa @@ -111,24 +111,24 @@ class Screen { #endif // Objetos y punteros - SDL_Window *window_; // Ventana de la aplicación - SDL_Renderer *renderer_; // El renderizador de la ventana + SDL_Window *window_; // Ventana de la aplicación + SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Texture *game_canvas_; // Textura para completar la ventana de juego hasta la pantalla completa // Variables - int window_width_; // Ancho de la pantalla o ventana - int window_height_; // Alto de la pantalla o ventana + int window_width_; // Ancho de la pantalla o ventana + int window_height_; // Alto de la pantalla o ventana int game_canvas_width_; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego int game_canvas_height_; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego - SDL_Rect dest_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana - Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla + SDL_Rect dest_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana + Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla // Notificaciones - una sola activa, sin apilación ni animaciones Text *notification_text_; // Fuente 8bithud dedicada a las notificaciones std::string notification_message_; // Texto a mostrar - Color notification_text_color_; // Color del texto - Color notification_outline_color_; // Color del outline - Uint32 notification_end_time_; // SDL_GetTicks() hasta el cual se muestra + Color notification_text_color_; // Color del texto + Color notification_outline_color_; // Color del outline + Uint32 notification_end_time_; // SDL_GetTicks() hasta el cual se muestra int notification_y_; // Fila vertical en el canvas virtual #ifndef NO_SHADERS diff --git a/source/core/rendering/smartsprite.h b/source/core/rendering/smartsprite.h index 570c390..ceec070 100644 --- a/source/core/rendering/smartsprite.h +++ b/source/core/rendering/smartsprite.h @@ -29,7 +29,7 @@ class SmartSprite : public AnimatedSprite { int dest_x_; // Posicion de destino en el eje X int dest_y_; // Posicion de destino en el eje Y int enabled_counter_; // Contador para deshabilitarlo - bool finished_; // Indica si ya ha terminado + bool finished_; // Indica si ya ha terminado void checkMove(); // Comprueba el movimiento void checkFinished(); // Comprueba si ha terminado diff --git a/source/core/rendering/sprite.h b/source/core/rendering/sprite.h index f3ad6b9..a36a8c3 100644 --- a/source/core/rendering/sprite.h +++ b/source/core/rendering/sprite.h @@ -24,21 +24,21 @@ class Sprite { void setWidth(int w); // Establece el valor de la variable void setHeight(int h); // Establece el valor de la variable - auto getSpriteClip() -> SDL_Rect; // Obten el valor de la variable - void setSpriteClip(SDL_Rect rect); // Establece el valor de la variable - void setSpriteClip(int x, int y, int w, int h); // Establece el valor de la variable + auto getSpriteClip() -> SDL_Rect; // Obten el valor de la variable + void setSpriteClip(SDL_Rect rect); // Establece el valor de la variable + void setSpriteClip(int x, int y, int w, int h); // Establece el valor de la variable - auto getTexture() -> Texture *; // Obten el valor de la variable - void setTexture(Texture *texture); // Establece el valor de la variable + auto getTexture() -> Texture *; // Obten el valor de la variable + void setTexture(Texture *texture); // Establece el valor de la variable - auto getRenderer() -> SDL_Renderer *; // Obten el valor de la variable - void setRenderer(SDL_Renderer *renderer); // Establece el valor de la variable + auto getRenderer() -> SDL_Renderer *; // Obten el valor de la variable + void setRenderer(SDL_Renderer *renderer); // Establece el valor de la variable - virtual void setEnabled(bool value); // Establece el valor de la variable - virtual auto isEnabled() -> bool; // Comprueba si el objeto está habilitado + virtual void setEnabled(bool value); // Establece el valor de la variable + virtual auto isEnabled() -> bool; // Comprueba si el objeto está habilitado - virtual auto getRect() -> SDL_Rect; // Devuelve el rectangulo donde está el sprite - virtual void setRect(SDL_Rect rect); // Establece los valores de posición y tamaño del sprite + virtual auto getRect() -> SDL_Rect; // Devuelve el rectangulo donde está el sprite + virtual void setRect(SDL_Rect rect); // Establece los valores de posición y tamaño del sprite protected: int x_; // Posición en el eje X donde dibujar el sprite diff --git a/source/core/rendering/text.h b/source/core/rendering/text.h index 1fe8998..18040ae 100644 --- a/source/core/rendering/text.h +++ b/source/core/rendering/text.h @@ -47,18 +47,18 @@ class Text { Text(const Text &) = delete; auto operator=(const Text &) -> Text & = delete; - void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla - void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con colores - void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra - void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x + void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla + void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con colores + void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra + void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(255, 255, 255), Uint8 shadow_distance = 1, Color shadow_color = Color(0, 0, 0), int lenght = -1); // Escribe texto con extras auto lenght(const std::string &text, int kerning = 1) -> int; // Obtiene la longitud en pixels de una cadena [[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el valor de la variable - void reLoadTexture(); // Recarga la textura - void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra + void reLoadTexture(); // Recarga la textura + void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra private: // Objetos y punteros @@ -66,8 +66,8 @@ class Text { Texture *texture_; // Textura con los bitmaps del texto // Variables - int box_width_; // Anchura de la caja de cada caracter en el png - int box_height_; // Altura de la caja de cada caracter en el png - bool fixed_width_; // Indica si el texto se ha de escribir con longitud fija en todas las letras + int box_width_; // Anchura de la caja de cada caracter en el png + int box_height_; // Altura de la caja de cada caracter en el png + bool fixed_width_; // Indica si el texto se ha de escribir con longitud fija en todas las letras Offset offset_[128]; // Vector con las posiciones y ancho de cada letra }; diff --git a/source/core/rendering/texture.h b/source/core/rendering/texture.h index 4f0f15a..29d6f94 100644 --- a/source/core/rendering/texture.h +++ b/source/core/rendering/texture.h @@ -12,26 +12,26 @@ class Texture { static void setGlobalScaleMode(SDL_ScaleMode mode); // Establece el modo de escalado global para nuevas texturas - explicit Texture(SDL_Renderer *renderer, const std::string &path = "", bool verbose = false); // Constructor - Texture(SDL_Renderer *renderer, const std::vector &bytes, bool verbose = false); // Constructor desde bytes (PNG en memoria) - ~Texture(); // Destructor + explicit Texture(SDL_Renderer *renderer, const std::string &path = "", bool verbose = false); // Constructor + Texture(SDL_Renderer *renderer, const std::vector &bytes, bool verbose = false); // Constructor desde bytes (PNG en memoria) + ~Texture(); // Destructor - auto loadFromFile(const std::string &path, SDL_Renderer *renderer, bool verbose = false) -> bool; // Carga una imagen desde un fichero - auto loadFromMemory(const uint8_t *data, size_t size, SDL_Renderer *renderer, bool verbose = false) -> bool; // Carga una imagen desde bytes en memoria - auto createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess /*access*/ = SDL_TEXTUREACCESS_STREAMING) -> bool; // Crea una textura en blanco - void unload(); // Libera la memoria de la textura + auto loadFromFile(const std::string &path, SDL_Renderer *renderer, bool verbose = false) -> bool; // Carga una imagen desde un fichero + auto loadFromMemory(const uint8_t *data, size_t size, SDL_Renderer *renderer, bool verbose = false) -> bool; // Carga una imagen desde bytes en memoria + auto createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess /*access*/ = SDL_TEXTUREACCESS_STREAMING) -> bool; // Crea una textura en blanco + void unload(); // Libera la memoria de la textura - void setColor(Uint8 red, Uint8 green, Uint8 blue); // Establece el color para la modulacion - void setBlendMode(SDL_BlendMode blending); // Establece el blending - void setAlpha(Uint8 alpha); // Establece el alpha para la modulación + void setColor(Uint8 red, Uint8 green, Uint8 blue); // Establece el color para la modulacion + void setBlendMode(SDL_BlendMode blending); // Establece el blending + void setAlpha(Uint8 alpha); // Establece el alpha para la modulación void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = nullptr, float zoom_w = 1, float zoom_h = 1, double angle = 0.0, SDL_Point *center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Renderiza la textura en un punto específico - void setAsRenderTarget(SDL_Renderer *renderer); // Establece la textura como objetivo de renderizado + void setAsRenderTarget(SDL_Renderer *renderer); // Establece la textura como objetivo de renderizado [[nodiscard]] auto getWidth() const -> int; // Obtiene el ancho de la imagen [[nodiscard]] auto getHeight() const -> int; // Obtiene el alto de la imagen - auto reLoad() -> bool; // Recarga la textura + auto reLoad() -> bool; // Recarga la textura auto getSDLTexture() -> SDL_Texture *; // Obtiene la textura private: diff --git a/source/core/rendering/writer.h b/source/core/rendering/writer.h index 74e7320..2a01ff4 100644 --- a/source/core/rendering/writer.h +++ b/source/core/rendering/writer.h @@ -19,7 +19,7 @@ class Writer { void setEnabled(bool value); // Establece el valor de la variable [[nodiscard]] auto isEnabled() const -> bool; // Obtiene el valor de la variable - void setEnabledCounter(int time); // Establece el valor de la variable + void setEnabledCounter(int time); // Establece el valor de la variable [[nodiscard]] auto getEnabledCounter() const -> int; // Obtiene el valor de la variable void center(int x); // Centra la cadena de texto a un punto X @@ -32,14 +32,14 @@ class Writer { // Variables int pos_x_{0}; // Posicion en el eje X donde empezar a escribir el texto int pos_y_{0}; // Posicion en el eje Y donde empezar a escribir el texto - int kerning_{0}; // Kerning del texto, es decir, espaciado entre caracteres - std::string caption_; // El texto para escribir - int speed_{0}; // Velocidad de escritura + int kerning_{0}; // Kerning del texto, es decir, espaciado entre caracteres + std::string caption_; // El texto para escribir + int speed_{0}; // Velocidad de escritura int writing_counter_{0}; // Temporizador de escritura para cada caracter - int index_{0}; // Posición del texto que se está escribiendo - int length_{0}; // Longitud de la cadena a escribir - bool completed_{false}; // Indica si se ha escrito todo el texto - bool enabled_{false}; // Indica si el objeto está habilitado + int index_{0}; // Posición del texto que se está escribiendo + int length_{0}; // Longitud de la cadena a escribir + bool completed_{false}; // Indica si se ha escrito todo el texto + bool enabled_{false}; // Indica si el objeto está habilitado int enabled_counter_{0}; // Temporizador para deshabilitar el objeto - bool finished_{false}; // Indica si ya ha terminado + bool finished_{false}; // Indica si ya ha terminado }; diff --git a/source/core/resources/asset.cpp b/source/core/resources/asset.cpp index 5e33fc2..a656587 100644 --- a/source/core/resources/asset.cpp +++ b/source/core/resources/asset.cpp @@ -147,17 +147,27 @@ auto Asset::checkFile(const std::string &path) const -> bool { // Devuelve el nombre del tipo de recurso auto Asset::getTypeName(Type type) -> std::string { switch (type) { - case Type::BITMAP: return "BITMAP"; - case Type::MUSIC: return "MUSIC"; - case Type::SOUND: return "SOUND"; - case Type::FONT: return "FONT"; - case Type::LANG: return "LANG"; - case Type::DATA: return "DATA"; - case Type::ROOM: return "ROOM"; - case Type::ENEMY: return "ENEMY"; - case Type::ITEM: return "ITEM"; + case Type::BITMAP: + return "BITMAP"; + case Type::MUSIC: + return "MUSIC"; + case Type::SOUND: + return "SOUND"; + case Type::FONT: + return "FONT"; + case Type::LANG: + return "LANG"; + case Type::DATA: + return "DATA"; + case Type::ROOM: + return "ROOM"; + case Type::ENEMY: + return "ENEMY"; + case Type::ITEM: + return "ITEM"; case Type::COUNT: - default: return "ERROR"; + default: + return "ERROR"; } } diff --git a/source/core/resources/resource_loader.h b/source/core/resources/resource_loader.h index 2270815..a4e9bea 100644 --- a/source/core/resources/resource_loader.h +++ b/source/core/resources/resource_loader.h @@ -9,14 +9,6 @@ class ResourcePack; class ResourceLoader { - private: - static std::unique_ptr instance; - ResourcePack* resource_pack_{nullptr}; - std::string pack_path_; - bool fallback_to_files_{true}; - - ResourceLoader(); - public: static auto getInstance() -> ResourceLoader&; ~ResourceLoader(); @@ -34,6 +26,13 @@ class ResourceLoader { [[nodiscard]] auto getAvailableResources() const -> std::vector; private: + ResourceLoader(); // Constructor privado (singleton) + static auto loadFromFile(const std::string& filename) -> std::vector; static auto getDataPath(const std::string& filename) -> std::string; + + static std::unique_ptr instance; + ResourcePack* resource_pack_{nullptr}; + std::string pack_path_; + bool fallback_to_files_{true}; }; diff --git a/source/core/resources/resource_pack.h b/source/core/resources/resource_pack.h index 925b167..9119bf9 100644 --- a/source/core/resources/resource_pack.h +++ b/source/core/resources/resource_pack.h @@ -14,15 +14,6 @@ struct ResourceEntry { }; class ResourcePack { - private: - std::unordered_map resources_; - std::vector data_; - bool loaded_{false}; - - static auto calculateChecksum(const std::vector& data) -> uint32_t; - static void encryptData(std::vector& data, const std::string& key); - static void decryptData(std::vector& data, const std::string& key); - public: ResourcePack(); ~ResourcePack(); @@ -41,4 +32,13 @@ class ResourcePack { auto getResourceList() const -> std::vector; static const std::string DEFAULT_ENCRYPT_KEY; + + private: + static auto calculateChecksum(const std::vector& data) -> uint32_t; + static void encryptData(std::vector& data, const std::string& key); + static void decryptData(std::vector& data, const std::string& key); + + std::unordered_map resources_; + std::vector data_; + bool loaded_{false}; }; diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 8e39d27..f25df00 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -41,8 +41,8 @@ Director::Director(int argc, const char *argv[]) { std::cout << "Game start" << '\n'; // Inicializa variables - section = new Section(); - section->name = SECTION_PROG_LOGO; + section_ = new Section(); + section_->name = SECTION_PROG_LOGO; // Inicializa las opciones del programa (defaults + dispositivos d'entrada) Options::init(); @@ -54,7 +54,7 @@ Director::Director(int argc, const char *argv[]) { executablePath = ""; #else const char *base_path = SDL_GetBasePath(); - executablePath = (base_path != nullptr) ? base_path : ""; + executable_path_ = (base_path != nullptr) ? base_path : ""; #endif // Comprueba los parametros del programa (pot activar console) @@ -70,13 +70,13 @@ Director::Director(int argc, const char *argv[]) { // Estableix el fitxer de configuració i carrega les opcions (o crea el // YAML amb defaults si no existeix). - Options::setConfigFile(systemFolder + "/config.yaml"); + Options::setConfigFile(system_folder_ + "/config.yaml"); Options::loadFromFile(); // Presets de shaders (creats amb defaults si no existeixen). - Options::setPostFXFile(systemFolder + "/postfx.yaml"); + Options::setPostFXFile(system_folder_ + "/postfx.yaml"); Options::loadPostFXFromFile(); - Options::setCrtPiFile(systemFolder + "/crtpi.yaml"); + Options::setCrtPiFile(system_folder_ + "/crtpi.yaml"); Options::loadCrtPiFromFile(); // Inicializa el sistema de recursos (pack + fallback). @@ -93,7 +93,7 @@ Director::Director(int argc, const char *argv[]) { #ifdef MACOS_BUNDLE const std::string PACK_PATH = executablePath + "../Resources/resources.pack"; #else - const std::string PACK_PATH = executablePath + "resources.pack"; + const std::string PACK_PATH = executable_path_ + "resources.pack"; #endif if (!ResourceHelper::initializeResourceSystem(PACK_PATH, ENABLE_FALLBACK)) { std::cerr << "Fatal: resource system init failed (missing resources.pack?)" << '\n'; @@ -102,7 +102,7 @@ Director::Director(int argc, const char *argv[]) { } // Crea el objeto que controla los ficheros de recursos - Asset::init(executablePath); + Asset::init(executable_path_); Asset::get()->setVerbose(Options::settings.console); // Si falta algún fichero no inicia el programa @@ -127,7 +127,7 @@ Director::Director(int argc, const char *argv[]) { Input::init("/gamecontrollerdb.txt"); #else { - const std::string BIN_DIR = std::filesystem::path(executablePath).parent_path().string(); + const std::string BIN_DIR = std::filesystem::path(executable_path_).parent_path().string(); #ifdef MACOS_BUNDLE Input::init(BIN_DIR + "/../Resources/gamecontrollerdb.txt"); #else @@ -145,7 +145,7 @@ Director::Director(int argc, const char *argv[]) { // // Por eso el constructor de Screen NO carga notificationText desde // Resource; se enlaza después vía `Screen::get()->initNotifications()`. - Screen::init(window, renderer); + Screen::init(window_, renderer_); #ifndef NO_SHADERS if (Options::video.gpu.acceleration) { @@ -155,13 +155,13 @@ Director::Director(int argc, const char *argv[]) { // Ahora sí, precarga todos los recursos en memoria (texturas, sonidos, // música, ...). Vivirán durante toda la vida de la app. - Resource::init(renderer); + Resource::init(renderer_); // Completa el enlazado de Screen con recursos que necesitan Resource // inicializado (actualmente sólo el Text de las notificaciones). Screen::get()->initNotifications(); - activeSection = ActiveSection::None; + active_section_ = ActiveSection::NONE; } Director::~Director() { @@ -170,10 +170,10 @@ Director::~Director() { // Libera las secciones primero: sus destructores tocan audio/render SDL // (p.ej. Intro::~Intro llama a JA_DeleteMusic) y deben ejecutarse antes // de SDL_Quit(). - logo.reset(); - intro.reset(); - title.reset(); - game.reset(); + logo_.reset(); + intro_.reset(); + title_.reset(); + game_.reset(); // Screen puede tener referencias a Text propiedad de Resource: destruir // Screen antes que Resource. @@ -185,12 +185,12 @@ Director::~Director() { Asset::destroy(); Input::destroy(); Lang::destroy(); - delete section; + delete section_; Audio::destroy(); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); + SDL_DestroyRenderer(renderer_); + SDL_DestroyWindow(window_); SDL_Quit(); @@ -270,23 +270,23 @@ auto Director::initSDL() -> bool { std::srand(static_cast(SDL_GetTicks())); // Crea la ventana - window = SDL_CreateWindow( + window_ = SDL_CreateWindow( Options::window.caption.c_str(), GAMECANVAS_WIDTH * Options::window.zoom, GAMECANVAS_HEIGHT * Options::window.zoom, 0); - if (window == nullptr) { + if (window_ == nullptr) { if (Options::settings.console) { std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << '\n'; } success = false; } else { - SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); // Crea un renderizador para la ventana - renderer = SDL_CreateRenderer(window, nullptr); + renderer_ = SDL_CreateRenderer(window_, nullptr); - if (renderer == nullptr) { + if (renderer_ == nullptr) { if (Options::settings.console) { std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << '\n'; } @@ -294,21 +294,21 @@ auto Director::initSDL() -> bool { } else { // Modo de blending por defecto (consistente con CCAE): // permite alpha blending para fades y notificaciones. - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); // Activa vsync si es necesario if (Options::video.vsync) { - SDL_SetRenderVSync(renderer, 1); + SDL_SetRenderVSync(renderer_, 1); } // Inicializa el color de renderizado - SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); // Establece el tamaño del buffer de renderizado - SDL_SetRenderLogicalPresentation(renderer, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX); + SDL_SetRenderLogicalPresentation(renderer_, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX); // Establece el modo de mezcla - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); } } } @@ -328,7 +328,7 @@ auto Director::setFileList() -> bool { #endif // Ficheros de configuración - Asset::get()->add(systemFolder + "/score.bin", Asset::Type::DATA, false, true); + Asset::get()->add(system_folder_ + "/score.bin", Asset::Type::DATA, false, true); Asset::get()->add(PREFIX + "/data/demo/demo.bin", Asset::Type::DATA); // Musicas @@ -470,7 +470,7 @@ void Director::createSystemFolder(const std::string &folder) { #elif __linux__ struct passwd *pw = getpwuid(getuid()); const char *homedir = pw->pw_dir; - systemFolder = std::string(homedir) + "/.config/" + folder; + system_folder_ = std::string(homedir) + "/.config/" + folder; { // Intenta crear ".config", per si no existeix @@ -488,12 +488,12 @@ void Director::createSystemFolder(const std::string &folder) { (void)folder; #else struct stat st = {.st_dev = 0}; - if (stat(systemFolder.c_str(), &st) == -1) { + if (stat(system_folder_.c_str(), &st) == -1) { errno = 0; #ifdef _WIN32 int ret = mkdir(systemFolder.c_str()); #else - int ret = mkdir(systemFolder.c_str(), S_IRWXU); + int ret = mkdir(system_folder_.c_str(), S_IRWXU); #endif if (ret == -1) { @@ -522,53 +522,53 @@ void Director::createSystemFolder(const std::string &folder) { // Gestiona las transiciones entre secciones void Director::handleSectionTransition() { // Determina qué sección debería estar activa - ActiveSection target_section = ActiveSection::None; - switch (section->name) { + ActiveSection target_section = ActiveSection::NONE; + switch (section_->name) { case SECTION_PROG_LOGO: - target_section = ActiveSection::Logo; + target_section = ActiveSection::LOGO; break; case SECTION_PROG_INTRO: - target_section = ActiveSection::Intro; + target_section = ActiveSection::INTRO; break; case SECTION_PROG_TITLE: - target_section = ActiveSection::Title; + target_section = ActiveSection::TITLE; break; case SECTION_PROG_GAME: - target_section = ActiveSection::Game; + target_section = ActiveSection::GAME; break; default: break; } // Si no ha cambiado, no hay nada que hacer - if (target_section == activeSection) { + if (target_section == active_section_) { return; } // Destruye la sección anterior - logo.reset(); - intro.reset(); - title.reset(); - game.reset(); + logo_.reset(); + intro_.reset(); + title_.reset(); + game_.reset(); // Crea la nueva sección - activeSection = target_section; - switch (activeSection) { - case ActiveSection::Logo: - logo = std::make_unique(renderer, section); + active_section_ = target_section; + switch (active_section_) { + case ActiveSection::LOGO: + logo_ = std::make_unique(renderer_, section_); break; - case ActiveSection::Intro: - intro = std::make_unique(renderer, section); + case ActiveSection::INTRO: + intro_ = std::make_unique(renderer_, section_); break; - case ActiveSection::Title: - title = std::make_unique(renderer, section); + case ActiveSection::TITLE: + title_ = std::make_unique<Title>(renderer_, section_); break; - case ActiveSection::Game: { - const int NUM_PLAYERS = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2; - game = std::make_unique<Game>(NUM_PLAYERS, 0, renderer, false, section); + case ActiveSection::GAME: { + const int NUM_PLAYERS = section_->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2; + game_ = std::make_unique<Game>(NUM_PLAYERS, 0, renderer_, false, section_); break; } - case ActiveSection::None: + case ActiveSection::NONE: break; } } @@ -581,7 +581,7 @@ auto Director::iterate() -> SDL_AppResult { section->name = SECTION_PROG_LOGO; } #else - if (section->name == SECTION_PROG_QUIT) { + if (section_->name == SECTION_PROG_QUIT) { return SDL_APP_SUCCESS; } #endif @@ -593,20 +593,20 @@ auto Director::iterate() -> SDL_AppResult { handleSectionTransition(); // Ejecuta un frame de la sección activa - switch (activeSection) { - case ActiveSection::Logo: - logo->iterate(); + switch (active_section_) { + case ActiveSection::LOGO: + logo_->iterate(); break; - case ActiveSection::Intro: - intro->iterate(); + case ActiveSection::INTRO: + intro_->iterate(); break; - case ActiveSection::Title: - title->iterate(); + case ActiveSection::TITLE: + title_->iterate(); break; - case ActiveSection::Game: - game->iterate(); + case ActiveSection::GAME: + game_->iterate(); break; - case ActiveSection::None: + case ActiveSection::NONE: break; } @@ -618,7 +618,7 @@ auto Director::handleEvent(SDL_Event *event) -> SDL_AppResult { #ifndef __EMSCRIPTEN__ // Evento de salida de la aplicación if (event->type == SDL_EVENT_QUIT) { - section->name = SECTION_PROG_QUIT; + section_->name = SECTION_PROG_QUIT; return SDL_APP_SUCCESS; } #endif @@ -646,20 +646,20 @@ auto Director::handleEvent(SDL_Event *event) -> SDL_AppResult { Mouse::handleEvent(*event, Options::video.fullscreen); // Reenvía el evento a la sección activa - switch (activeSection) { - case ActiveSection::Logo: - logo->handleEvent(event); + switch (active_section_) { + case ActiveSection::LOGO: + logo_->handleEvent(event); break; - case ActiveSection::Intro: - intro->handleEvent(event); + case ActiveSection::INTRO: + intro_->handleEvent(event); break; - case ActiveSection::Title: - title->handleEvent(event); + case ActiveSection::TITLE: + title_->handleEvent(event); break; - case ActiveSection::Game: - game->handleEvent(event); + case ActiveSection::GAME: + game_->handleEvent(event); break; - case ActiveSection::None: + case ActiveSection::NONE: break; } diff --git a/source/core/system/director.h b/source/core/system/director.h index ca999b3..2f75d73 100644 --- a/source/core/system/director.h +++ b/source/core/system/director.h @@ -11,65 +11,48 @@ class Logo; class Title; struct Section; -// Secciones activas del Director -enum class ActiveSection : std::uint8_t { None, - Logo, - Intro, - Title, - Game }; - class Director { - private: - // Objetos y punteros - SDL_Window *window; // La ventana donde dibujamos - SDL_Renderer *renderer; // El renderizador de la ventana - Section *section; // Sección y subsección actual del programa; - - // Secciones del juego - ActiveSection activeSection; - std::unique_ptr<Logo> logo; - std::unique_ptr<Intro> intro; - std::unique_ptr<Title> title; - std::unique_ptr<Game> game; - - // Variables - std::string executablePath; // Path del ejecutable - std::string systemFolder; // Carpeta del sistema donde guardar datos - - // Inicializa jail_audio - static void initJailAudio(); - - // Arranca SDL y crea la ventana - auto initSDL() -> bool; - - // Inicializa el objeto input - static void initInput(); - - // Crea el indice de ficheros - auto setFileList() -> bool; - - // Comprueba los parametros del programa - static void checkProgramArguments(int argc, const char *argv[]); - - // Crea la carpeta del sistema donde guardar datos - void createSystemFolder(const std::string &folder); - - // Gestiona las transiciones entre secciones - void handleSectionTransition(); - public: - // Constructor - Director(int argc, const char *argv[]); - - // Destructor - ~Director(); + Director(int argc, const char *argv[]); // Constructor + ~Director(); // Destructor Director(const Director &) = delete; auto operator=(const Director &) -> Director & = delete; - // Ejecuta un frame del juego - auto iterate() -> SDL_AppResult; + auto iterate() -> SDL_AppResult; // Ejecuta un frame del juego + auto handleEvent(SDL_Event *event) -> SDL_AppResult; // Procesa un evento - // Procesa un evento - auto handleEvent(SDL_Event *event) -> SDL_AppResult; + private: + // Secciones activas del Director + enum class ActiveSection : std::uint8_t { + NONE, + LOGO, + INTRO, + TITLE, + GAME + }; + + static void initJailAudio(); // Inicializa jail_audio + auto initSDL() -> bool; // Arranca SDL y crea la ventana + static void initInput(); // Inicializa el objeto input + auto setFileList() -> bool; // Crea el indice de ficheros + static void checkProgramArguments(int argc, const char *argv[]); // Comprueba los parametros del programa + void createSystemFolder(const std::string &folder); // Crea la carpeta del sistema donde guardar datos + void handleSectionTransition(); // Gestiona las transiciones entre secciones + + // Objetos y punteros + SDL_Window *window_; // La ventana donde dibujamos + SDL_Renderer *renderer_; // El renderizador de la ventana + Section *section_; // Sección y subsección actual del programa; + + // Secciones del juego + ActiveSection active_section_; + std::unique_ptr<Logo> logo_; + std::unique_ptr<Intro> intro_; + std::unique_ptr<Title> title_; + std::unique_ptr<Game> game_; + + // Variables + std::string executable_path_; // Path del ejecutable + std::string system_folder_; // Carpeta del sistema donde guardar datos }; diff --git a/source/game/game.h b/source/game/game.h index f42ef54..7ec38e3 100644 --- a/source/game/game.h +++ b/source/game/game.h @@ -21,36 +21,47 @@ class Texture; struct JA_Music_t; struct JA_Sound_t; -// Cantidad de elementos a escribir en los ficheros de datos -constexpr int TOTAL_SCORE_DATA = 3; -constexpr int TOTAL_DEMO_DATA = 2000; - -// Contadores -constexpr int STAGE_COUNTER = 200; -constexpr int SHAKE_COUNTER = 10; -constexpr int HELP_COUNTER = 1000; -constexpr int GAME_COMPLETED_START_FADE = 500; -constexpr int GAME_COMPLETED_END = 700; - -// Formaciones enemigas -constexpr int NUMBER_OF_ENEMY_FORMATIONS = 100; -constexpr int MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION = 50; - -// Porcentaje de aparición de los objetos -constexpr int ITEM_POINTS_1_DISK_ODDS = 10; -constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6; -constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3; -constexpr int ITEM_CLOCK_ODDS = 5; -constexpr int ITEM_COFFEE_ODDS = 5; -constexpr int ITEM_POWER_BALL_ODDS = 0; -constexpr int ITEM_COFFEE_MACHINE_ODDS = 4; - -// Valores para las variables asociadas a los objetos -constexpr int TIME_STOPPED_COUNTER = 300; - // Clase Game class Game { + public: + Game(int num_players, int current_stage, SDL_Renderer *renderer, bool demo, Section *section); // Constructor + ~Game(); // Destructor + + Game(const Game &) = delete; + auto operator=(const Game &) -> Game & = delete; + + void run(); // Bucle para el juego + void iterate(); // Ejecuta un frame del juego + [[nodiscard]] auto hasFinished() const -> bool; // Indica si el juego ha terminado + void handleEvent(const SDL_Event *event); // Procesa un evento + private: + // Cantidad de elementos a escribir en los ficheros de datos + static constexpr int TOTAL_SCORE_DATA = 3; + static constexpr int TOTAL_DEMO_DATA = 2000; + + // Contadores + static constexpr int STAGE_COUNTER = 200; + static constexpr int SHAKE_COUNTER = 10; + static constexpr int HELP_COUNTER = 1000; + static constexpr int GAME_COMPLETED_START_FADE = 500; + static constexpr int GAME_COMPLETED_END = 700; + + // Formaciones enemigas + static constexpr int NUMBER_OF_ENEMY_FORMATIONS = 100; + static constexpr int MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION = 50; + + // Porcentaje de aparición de los objetos + static constexpr int ITEM_POINTS_1_DISK_ODDS = 10; + static constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6; + static constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3; + static constexpr int ITEM_CLOCK_ODDS = 5; + static constexpr int ITEM_COFFEE_ODDS = 5; + static constexpr int ITEM_COFFEE_MACHINE_ODDS = 4; + + // Valores para las variables asociadas a los objetos + static constexpr int TIME_STOPPED_COUNTER = 300; + struct EnemyInit { int x; // Posición en el eje X donde crear al enemigo int y; // Posición en el eje Y donde crear al enemigo @@ -128,6 +139,125 @@ class Game { DemoKeys data_file[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo }; + void update(); // Actualiza el juego + void render(); // Dibuja el juego + void init(); // Inicializa las variables necesarias para la sección 'Game' + void loadMedia(); // Carga los recursos necesarios para la sección 'Game' + + auto loadScoreFile() -> bool; // Carga el fichero de puntos + auto loadDemoFile() -> bool; // Carga el fichero de datos para la demo + auto saveScoreFile() -> bool; // Guarda el fichero de puntos + auto saveDemoFile() -> bool; // Guarda el fichero de datos para la demo + + void initEnemyFormations(); // Inicializa las formaciones enemigas + void initEnemyFormationsZero(); // Helper de initEnemyFormations + void initEnemyFormationsLinear(); // Helper de initEnemyFormations + void initEnemyFormationsSymmetric(); // Helper de initEnemyFormations + void initEnemyFormationsHexagonsAndTest(); // Helper de initEnemyFormations + + void initEnemyPools(); // Inicializa los conjuntos de formaciones + void initGameStages(); // Inicializa las fases del juego + void deployEnemyFormation(); // Crea una formación de enemigos + void increaseStageCurrentPower(Uint8 power); // Aumenta el poder de la fase + + void setHiScore(Uint32 score); // Establece el valor de la variable + void updateHiScore(); // Actualiza el valor de HiScore en caso necesario + static auto updateScoreText(Uint32 num) -> std::string; // Transforma un valor numérico en una cadena de 6 cifras + void renderScoreBoard(); // Pinta el marcador en pantalla usando un objeto texto + + void updatePlayers(); // Actualiza las variables del jugador + void renderPlayers(); // Dibuja a los jugadores + + void updateStage(); // Actualiza las variables de la fase + void updateDeath(); // Actualiza el estado de muerte + void renderDeathFade(int counter); // Renderiza el fade final cuando se acaba la partida + + void updateBalloons(); // Actualiza los globos + void renderBalloons(); // Pinta en pantalla todos los globos activos + auto createBalloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer) -> Uint8; // Crea un globo nuevo en el vector de globos + void createPowerBall(); // Crea una PowerBall + void setBalloonSpeed(float speed); // Establece la velocidad de los globos + void incBalloonSpeed(); // Incrementa la velocidad de los globos + void updateBalloonSpeed(); // Actualiza la velocidad de los globos en funcion del poder acumulado de la fase + void popBalloon(Balloon *balloon); // Explosiona un globo. Lo destruye y crea otros dos si es el caso + void destroyBalloon(Balloon *balloon); // Explosiona un globo. Lo destruye + void destroyAllBalloons(); // Destruye todos los globos + void stopAllBalloons(Uint16 time); // Detiene todos los globos + void startAllBalloons(); // Pone en marcha todos los globos + void freeBalloons(); // Vacia el vector de globos + + auto checkPlayerBalloonCollision(Player *player) -> bool; // Comprueba la colisión entre el jugador y los globos activos + void checkPlayerItemCollision(Player *player); // Comprueba la colisión entre el jugador y los items + void checkBulletBalloonCollision(); // Comprueba la colisión entre las balas y los globos + void resolveBulletBalloonHit(Bullet *bullet, Balloon *balloon); // Resuelve un impacto bala-globo (helper de checkBulletBalloonCollision) + + void moveBullets(); // Mueve las balas activas + void renderBullets(); // Pinta las balas activas + void createBullet(int x, int y, Bullet::Kind kind, bool powered_up, int owner); // Crea un objeto bala + void freeBullets(); // Vacia el vector de balas + + void updateItems(); // Actualiza los items + void renderItems(); // Pinta los items activos + auto dropItem() -> Item::Id; // Devuelve un item en función del azar + void createItem(Item::Id kind, float x, float y); // Crea un objeto item + void freeItems(); // Vacia el vector de items + + void createItemScoreSprite(int x, int y, const SmartSprite *sprite); // Crea un objeto SmartSprite + void freeSmartSprites(); // Vacia el vector de smartsprites + + void renderFlashEffect(); // Dibuja el efecto de flash + void updateShakeEffect(); // Actualiza el efecto de agitar la pantalla + void throwCoffee(int x, int y); // Crea un SmartSprite para arrojar el item café al recibir un impacto + void updateSmartSprites(); // Actualiza los SmartSprites + void renderSmartSprites(); // Pinta los SmartSprites activos + + void killPlayer(Player *player); // Acciones a realizar cuando el jugador muere + void evaluateAndSetMenace(); // Calcula y establece el valor de amenaza en funcion de los globos activos + [[nodiscard]] auto getMenace() const -> Uint8; // Obtiene el valor de la variable + + void setTimeStopped(bool value); // Establece el valor de la variable + [[nodiscard]] auto isTimeStopped() const -> bool; // Obtiene el valor de la variable + void setTimeStoppedCounter(Uint16 value); // Establece el valor de la variable + void incTimeStoppedCounter(Uint16 value); // Incrementa el valor de la variable + + void updateEnemyDeployCounter(); // Actualiza la variable EnemyDeployCounter + void updateTimeStoppedCounter(); // Actualiza y comprueba el valor de la variable + void updateMenace(); // Gestiona el nivel de amenaza + void updateBackground(); // Actualiza el fondo + void renderBackground(); // Dibuja el fondo + + void checkGameInput(); // Gestiona la entrada durante el juego + void processDemoInput(); // Helper de checkGameInput + void processLiveInput(); // Helper de checkGameInput + void processPlayerLiveInput(Player *player, int i); // Helper de checkGameInput + + void renderMessages(); // Pinta diferentes mensajes en la pantalla + void enableTimeStopItem(); // Habilita el efecto del item de detener el tiempo + void disableTimeStopItem(); // Deshabilita el efecto del item de detener el tiempo + void shakeScreen(); // Inicia el efecto de agitación intensa de la pantalla + void updateDeathShake(); // Actualiza el efecto de agitación intensa + [[nodiscard]] auto isDeathShaking() const -> bool; // Indica si el efecto de agitación intensa está activo + void updateDeathSequence(); // Actualiza la secuencia de muerte del jugador + + void updatePausedGame(); // Actualiza las variables del menu de pausa del juego + void updateLeavingPauseMenu(); // Helper de updatePausedGame + void updatePauseMenuUI(); // Helper de updatePausedGame + void renderPausedGame(); // Dibuja el menu de pausa del juego + void enterPausedGame(); // Inicializa el estado de pausa del juego + + void updateGameOverScreen(); // Actualiza los elementos de la pantalla de game over + void renderGameOverScreen(); // Dibuja los elementos de la pantalla de game over + void enterGameOverScreen(); // Inicializa el estado de game over + + auto canPowerBallBeCreated() -> bool; // Indica si se puede crear una powerball + auto calculateScreenPower() -> int; // Calcula el poder actual de los globos en pantalla + void initPaths(); // Inicializa las variables que contienen puntos de ruta para mover objetos + void updateGameCompleted(); // Actualiza el tramo final de juego, una vez completado + void updateHelper(); // Actualiza las variables de ayuda + auto allPlayersAreDead() -> bool; // Comprueba si todos los jugadores han muerto + void deleteAllVectorObjects(); // Elimina todos los objetos contenidos en vectores + void setHiScore(); // Establece la máxima puntuación desde fichero o desde las puntuaciones online + // Objetos y punteros SDL_Renderer *renderer_; // El renderizador de la ventana Section *section_; // Seccion actual dentro del juego @@ -255,308 +385,4 @@ class Game { #ifdef PAUSE bool pause; #endif - - // Actualiza el juego - void update(); - - // Dibuja el juego - void render(); - - // Inicializa las variables necesarias para la sección 'Game' - void init(); - - // Carga los recursos necesarios para la sección 'Game' - void loadMedia(); - - // Carga el fichero de puntos - auto loadScoreFile() -> bool; - - // Carga el fichero de datos para la demo - auto loadDemoFile() -> bool; - - // Guarda el fichero de puntos - auto saveScoreFile() -> bool; - - // Guarda el fichero de datos para la demo - auto saveDemoFile() -> bool; - - // Inicializa las formaciones enemigas - void initEnemyFormations(); - - // Helpers de initEnemyFormations - void initEnemyFormationsZero(); - void initEnemyFormationsLinear(); - void initEnemyFormationsSymmetric(); - void initEnemyFormationsHexagonsAndTest(); - - // Inicializa los conjuntos de formaciones - void initEnemyPools(); - - // Inicializa las fases del juego - void initGameStages(); - - // Crea una formación de enemigos - void deployEnemyFormation(); - - // Aumenta el poder de la fase - void increaseStageCurrentPower(Uint8 power); - - // Establece el valor de la variable - void setHiScore(Uint32 score); - - // Actualiza el valor de HiScore en caso necesario - void updateHiScore(); - - // Transforma un valor numérico en una cadena de 6 cifras - static auto updateScoreText(Uint32 num) -> std::string; - - // Pinta el marcador en pantalla usando un objeto texto - void renderScoreBoard(); - - // Actualiza las variables del jugador - void updatePlayers(); - - // Dibuja a los jugadores - void renderPlayers(); - - // Actualiza las variables de la fase - void updateStage(); - - // Actualiza el estado de muerte - void updateDeath(); - - // Renderiza el fade final cuando se acaba la partida - void renderDeathFade(int counter); - - // Actualiza los globos - void updateBalloons(); - - // Pinta en pantalla todos los globos activos - void renderBalloons(); - - // Crea un globo nuevo en el vector de globos - auto createBalloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer) -> Uint8; - - // Crea una PowerBall - void createPowerBall(); - - // Establece la velocidad de los globos - void setBalloonSpeed(float speed); - - // Incrementa la velocidad de los globos - void incBalloonSpeed(); - - // Actualiza la velocidad de los globos en funcion del poder acumulado de la fase - void updateBalloonSpeed(); - - // Explosiona un globo. Lo destruye y crea otros dos si es el caso - void popBalloon(Balloon *balloon); - - // Explosiona un globo. Lo destruye - void destroyBalloon(Balloon *balloon); - - // Destruye todos los globos - void destroyAllBalloons(); - - // Detiene todos los globos - void stopAllBalloons(Uint16 time); - - // Pone en marcha todos los globos - void startAllBalloons(); - - // Vacia el vector de globos - void freeBalloons(); - - // Comprueba la colisión entre el jugador y los globos activos - auto checkPlayerBalloonCollision(Player *player) -> bool; - - // Comprueba la colisión entre el jugador y los items - void checkPlayerItemCollision(Player *player); - - // Comprueba la colisión entre las balas y los globos - void checkBulletBalloonCollision(); - - // Resuelve un impacto bala-globo (helper de checkBulletBalloonCollision) - void resolveBulletBalloonHit(Bullet *bullet, Balloon *balloon); - - // Mueve las balas activas - void moveBullets(); - - // Pinta las balas activas - void renderBullets(); - - // Crea un objeto bala - void createBullet(int x, int y, Bullet::Kind kind, bool powered_up, int owner); - - // Vacia el vector de balas - void freeBullets(); - - // Actualiza los items - void updateItems(); - - // Pinta los items activos - void renderItems(); - - // Devuelve un item en función del azar - auto dropItem() -> Item::Id; - - // Crea un objeto item - void createItem(Item::Id kind, float x, float y); - - // Vacia el vector de items - void freeItems(); - - // Crea un objeto SmartSprite - void createItemScoreSprite(int x, int y, const SmartSprite *sprite); - - // Vacia el vector de smartsprites - void freeSmartSprites(); - - // Dibuja el efecto de flash - void renderFlashEffect(); - - // Actualiza el efecto de agitar la pantalla - void updateShakeEffect(); - - // Crea un SmartSprite para arrojar el item café al recibir un impacto - void throwCoffee(int x, int y); - - // Actualiza los SmartSprites - void updateSmartSprites(); - - // Pinta los SmartSprites activos - void renderSmartSprites(); - - // Acciones a realizar cuando el jugador muere - void killPlayer(Player *player); - - // Calcula y establece el valor de amenaza en funcion de los globos activos - void evaluateAndSetMenace(); - - // Obtiene el valor de la variable - [[nodiscard]] auto getMenace() const -> Uint8; - - // Establece el valor de la variable - void setTimeStopped(bool value); - - // Obtiene el valor de la variable - [[nodiscard]] auto isTimeStopped() const -> bool; - - // Establece el valor de la variable - void setTimeStoppedCounter(Uint16 value); - - // Incrementa el valor de la variable - void incTimeStoppedCounter(Uint16 value); - - // Actualiza la variable EnemyDeployCounter - void updateEnemyDeployCounter(); - - // Actualiza y comprueba el valor de la variable - void updateTimeStoppedCounter(); - - // Gestiona el nivel de amenaza - void updateMenace(); - - // Actualiza el fondo - void updateBackground(); - - // Dibuja el fondo - void renderBackground(); - - // Gestiona la entrada durante el juego - void checkGameInput(); - - // Helpers de checkGameInput - void processDemoInput(); - void processLiveInput(); - void processPlayerLiveInput(Player *player, int i); - - // Pinta diferentes mensajes en la pantalla - void renderMessages(); - - // Habilita el efecto del item de detener el tiempo - void enableTimeStopItem(); - - // Deshabilita el efecto del item de detener el tiempo - void disableTimeStopItem(); - - // Inicia el efecto de agitación intensa de la pantalla - void shakeScreen(); - - // Actualiza el efecto de agitación intensa - void updateDeathShake(); - - // Indica si el efecto de agitación intensa está activo - [[nodiscard]] auto isDeathShaking() const -> bool; - - // Actualiza la secuencia de muerte del jugador - void updateDeathSequence(); - - // Actualiza las variables del menu de pausa del juego - void updatePausedGame(); - - // Helpers de updatePausedGame - void updateLeavingPauseMenu(); - void updatePauseMenuUI(); - - // Dibuja el menu de pausa del juego - void renderPausedGame(); - - // Inicializa el estado de pausa del juego - void enterPausedGame(); - - // Actualiza los elementos de la pantalla de game over - void updateGameOverScreen(); - - // Dibuja los elementos de la pantalla de game over - void renderGameOverScreen(); - - // Inicializa el estado de game over - void enterGameOverScreen(); - - // Indica si se puede crear una powerball - auto canPowerBallBeCreated() -> bool; - - // Calcula el poder actual de los globos en pantalla - auto calculateScreenPower() -> int; - - // Inicializa las variables que contienen puntos de ruta para mover objetos - void initPaths(); - - // Actualiza el tramo final de juego, una vez completado - void updateGameCompleted(); - - // Actualiza las variables de ayuda - void updateHelper(); - - // Comprueba si todos los jugadores han muerto - auto allPlayersAreDead() -> bool; - - // Elimina todos los objetos contenidos en vectores - void deleteAllVectorObjects(); - - // Establece la máxima puntuación desde fichero o desde las puntuaciones online - void setHiScore(); - - public: - // Constructor - Game(int num_players, int current_stage, SDL_Renderer *renderer, bool demo, Section *section); - - // Destructor - ~Game(); - - Game(const Game &) = delete; - auto operator=(const Game &) -> Game & = delete; - - // Bucle para el juego - void run(); - - // Ejecuta un frame del juego - void iterate(); - - // Indica si el juego ha terminado - [[nodiscard]] auto hasFinished() const -> bool; - - // Procesa un evento - void handleEvent(const SDL_Event *event); }; diff --git a/source/game/ui/menu.cpp b/source/game/ui/menu.cpp index 117da16..06e1527 100644 --- a/source/game/ui/menu.cpp +++ b/source/game/ui/menu.cpp @@ -14,50 +14,50 @@ // Constructor Menu::Menu(SDL_Renderer *renderer, const std::string &file) - : colorGreyed{128, 128, 128} { + : color_greyed_{128, 128, 128} { // Copia punteros - this->renderer = renderer; + this->renderer_ = renderer; // Inicializa punteros - soundMove = nullptr; - soundAccept = nullptr; - soundCancel = nullptr; + sound_move_ = nullptr; + sound_accept_ = nullptr; + sound_cancel_ = nullptr; // Inicializa variables - selector.index = 0; - selector.previousIndex = 0; - itemSelected = MENU_NO_OPTION; - x = 0; - y = 0; - w = 0; - rectBG.rect = {.x = 0, .y = 0, .w = 0, .h = 0}; - rectBG.color = {0, 0, 0}; - rectBG.a = 0; - backgroundType = MENU_BACKGROUND_SOLID; - isCenteredOnX = false; - isCenteredOnY = false; - areElementsCenteredOnX = false; - centerX = 0; - centerY = 0; - widestItem = 0; - defaultActionWhenCancel = 0; + selector_.index = 0; + selector_.previous_index = 0; + item_selected_ = MENU_NO_OPTION; + x_ = 0; + y_ = 0; + w_ = 0; + rect_bg_.rect = {.x = 0, .y = 0, .w = 0, .h = 0}; + rect_bg_.color = {0, 0, 0}; + rect_bg_.a = 0; + background_type_ = MENU_BACKGROUND_SOLID; + is_centered_on_x_ = false; + is_centered_on_y_ = false; + are_elements_centered_on_x_ = false; + center_x_ = 0; + center_y_ = 0; + widest_item_ = 0; + default_action_when_cancel = 0; // Selector - selector.originY = 0; - selector.targetY = 0; - selector.despY = 0; - selector.originH = 0; - selector.targetH = 0; - selector.incH = 0; - selector.y = 0.0F; - selector.h = 0.0F; - selector.numJumps = 8; - selector.moving = false; - selector.resizing = false; - selector.rect = {.x = 0, .y = 0, .w = 0, .h = 0}; - selector.color = {0, 0, 0}; - selector.itemColor = {0, 0, 0}; - selector.a = 255; + selector_.origin_y = 0; + selector_.target_y = 0; + selector_.desp_y = 0; + selector_.origin_h = 0; + selector_.target_h = 0; + selector_.inc_h = 0; + selector_.y = 0.0F; + selector_.h = 0.0F; + selector_.num_jumps = 8; + selector_.moving = false; + selector_.resizing = false; + selector_.rect = {.x = 0, .y = 0, .w = 0, .h = 0}; + selector_.color = {0, 0, 0}; + selector_.item_color = {0, 0, 0}; + selector_.a = 255; // Inicializa las variables desde un fichero. Si no se pasa fichero, el // llamante (p.ej. Resource::preloadAll) usará loadFromBytes después — @@ -70,21 +70,21 @@ Menu::Menu(SDL_Renderer *renderer, const std::string &file) } Menu::~Menu() { - renderer = nullptr; + renderer_ = nullptr; - if (soundMove != nullptr) { - JA_DeleteSound(soundMove); + if (sound_move_ != nullptr) { + JA_DeleteSound(sound_move_); } - if (soundAccept != nullptr) { - JA_DeleteSound(soundAccept); + if (sound_accept_ != nullptr) { + JA_DeleteSound(sound_accept_); } - if (soundCancel != nullptr) { - JA_DeleteSound(soundCancel); + if (sound_cancel_ != nullptr) { + JA_DeleteSound(sound_cancel_); } - delete text; + delete text_; } // Parser compartido (recibe cualquier istream) @@ -109,10 +109,10 @@ auto Menu::parseFromStream(std::istream &file, const std::string &filename) -> b if (line == "[item]") { Item newItem; newItem.label = ""; - newItem.hPaddingDown = 1; + newItem.h_padding_down = 1; newItem.selectable = true; newItem.greyed = false; - newItem.linkedDown = false; + newItem.linked_down = false; newItem.visible = true; newItem.line = false; @@ -136,10 +136,10 @@ auto Menu::parseFromStream(std::istream &file, const std::string &filename) -> b // Crea el objeto text tan pronto como se pueda. Necesario para añadir items. // Carga via ResourceHelper para que funcione tanto con pack como con filesystem. - if (!font_png.empty() && !font_txt.empty() && !textAllocated) { - auto pngBytes = ResourceHelper::loadFile(Asset::get()->get(font_png)); - auto txtBytes = ResourceHelper::loadFile(Asset::get()->get(font_txt)); - text = new Text(pngBytes, txtBytes, renderer); + if (!font_png_.empty() && !font_txt_.empty() && !textAllocated) { + auto pngBytes = ResourceHelper::loadFile(Asset::get()->get(font_png_)); + auto txtBytes = ResourceHelper::loadFile(Asset::get()->get(font_txt_)); + text_ = new Text(pngBytes, txtBytes, renderer_); textAllocated = true; } } @@ -180,7 +180,7 @@ auto Menu::setItem(Item *item, const std::string &var, const std::string &value) } else if (var == "hPaddingDown") { - item->hPaddingDown = std::stoi(value); + item->h_padding_down = std::stoi(value); } else if (var == "selectable") { @@ -192,7 +192,7 @@ auto Menu::setItem(Item *item, const std::string &var, const std::string &value) } else if (var == "linkedDown") { - item->linkedDown = value == "true"; + item->linked_down = value == "true"; } else if (var == "visible") { @@ -219,56 +219,56 @@ auto Menu::setVars(const std::string &var, const std::string &value) -> bool { bool success = true; if (var == "font_png") { - font_png = value; + font_png_ = value; } else if (var == "font_txt") { - font_txt = value; + font_txt_ = value; } else if (var == "sound_cancel") { auto bytes = ResourceHelper::loadFile(Asset::get()->get(value)); if (!bytes.empty()) { - soundCancel = JA_LoadSound(bytes.data(), (uint32_t)bytes.size()); + sound_cancel_ = JA_LoadSound(bytes.data(), (uint32_t)bytes.size()); } } else if (var == "sound_accept") { auto bytes = ResourceHelper::loadFile(Asset::get()->get(value)); if (!bytes.empty()) { - soundAccept = JA_LoadSound(bytes.data(), (uint32_t)bytes.size()); + sound_accept_ = JA_LoadSound(bytes.data(), (uint32_t)bytes.size()); } } else if (var == "sound_move") { auto bytes = ResourceHelper::loadFile(Asset::get()->get(value)); if (!bytes.empty()) { - soundMove = JA_LoadSound(bytes.data(), (uint32_t)bytes.size()); + sound_move_ = JA_LoadSound(bytes.data(), (uint32_t)bytes.size()); } } else if (var == "name") { - name = value; + name_ = value; } else if (var == "x") { - x = std::stoi(value); + x_ = std::stoi(value); } else if (var == "centerX") { - centerX = std::stoi(value); + center_x_ = std::stoi(value); } else if (var == "centerY") { - centerY = std::stoi(value); + center_y_ = std::stoi(value); } else if (var == "y") { - y = std::stoi(value); + y_ = std::stoi(value); } else if (var == "backgroundType") { - backgroundType = std::stoi(value); + background_type_ = std::stoi(value); } else if (var == "backgroundColor") { @@ -276,13 +276,13 @@ auto Menu::setVars(const std::string &var, const std::string &value) -> bool { std::stringstream ss(value); std::string tmp; getline(ss, tmp, ','); - rectBG.color.r = std::stoi(tmp); + rect_bg_.color.r = std::stoi(tmp); getline(ss, tmp, ','); - rectBG.color.g = std::stoi(tmp); + rect_bg_.color.g = std::stoi(tmp); getline(ss, tmp, ','); - rectBG.color.b = std::stoi(tmp); + rect_bg_.color.b = std::stoi(tmp); getline(ss, tmp, ','); - rectBG.a = std::stoi(tmp); + rect_bg_.a = std::stoi(tmp); } else if (var == "selector_color") { @@ -290,13 +290,13 @@ auto Menu::setVars(const std::string &var, const std::string &value) -> bool { std::stringstream ss(value); std::string tmp; getline(ss, tmp, ','); - selector.color.r = std::stoi(tmp); + selector_.color.r = std::stoi(tmp); getline(ss, tmp, ','); - selector.color.g = std::stoi(tmp); + selector_.color.g = std::stoi(tmp); getline(ss, tmp, ','); - selector.color.b = std::stoi(tmp); + selector_.color.b = std::stoi(tmp); getline(ss, tmp, ','); - selector.a = std::stoi(tmp); + selector_.a = std::stoi(tmp); } else if (var == "selector_text_color") { @@ -304,27 +304,27 @@ auto Menu::setVars(const std::string &var, const std::string &value) -> bool { std::stringstream ss(value); std::string tmp; getline(ss, tmp, ','); - selector.itemColor.r = std::stoi(tmp); + selector_.item_color.r = std::stoi(tmp); getline(ss, tmp, ','); - selector.itemColor.g = std::stoi(tmp); + selector_.item_color.g = std::stoi(tmp); getline(ss, tmp, ','); - selector.itemColor.b = std::stoi(tmp); + selector_.item_color.b = std::stoi(tmp); } else if (var == "areElementsCenteredOnX") { - areElementsCenteredOnX = value == "true"; + are_elements_centered_on_x_ = value == "true"; } else if (var == "isCenteredOnX") { - isCenteredOnX = value == "true"; + is_centered_on_x_ = value == "true"; } else if (var == "isCenteredOnY") { - isCenteredOnY = value == "true"; + is_centered_on_y_ = value == "true"; } else if (var == "defaultActionWhenCancel") { - defaultActionWhenCancel = std::stoi(value); + default_action_when_cancel = std::stoi(value); } else if (var.empty()) { @@ -341,15 +341,15 @@ auto Menu::setVars(const std::string &var, const std::string &value) -> bool { void Menu::loadAudioFile(const std::string &file, int sound) { switch (sound) { case SOUND_ACCEPT: - soundAccept = JA_LoadSound(file.c_str()); + sound_accept_ = JA_LoadSound(file.c_str()); break; case SOUND_CANCEL: - soundCancel = JA_LoadSound(file.c_str()); + sound_cancel_ = JA_LoadSound(file.c_str()); break; case SOUND_MOVE: - soundMove = JA_LoadSound(file.c_str()); + sound_move_ = JA_LoadSound(file.c_str()); break; default: @@ -359,115 +359,115 @@ void Menu::loadAudioFile(const std::string &file, int sound) { // Obtiene el nombre del menu auto Menu::getName() const -> const std::string & { - return name; + return name_; } // Obtiene el valor de la variable auto Menu::getItemSelected() -> int { // Al llamar a esta funcion, se obtiene el valor y se borra - const int temp = itemSelected; - itemSelected = MENU_NO_OPTION; + const int temp = item_selected_; + item_selected_ = MENU_NO_OPTION; return temp; } // Actualiza la posicion y el estado del selector void Menu::updateSelector() { - if (selector.moving) { + if (selector_.moving) { // Calcula el desplazamiento en Y - selector.y += selector.despY; - if (selector.despY > 0) // Va hacia abajo + selector_.y += selector_.desp_y; + if (selector_.desp_y > 0) // Va hacia abajo { - if (selector.y > selector.targetY) // Ha llegado al destino + if (selector_.y > selector_.target_y) // Ha llegado al destino { - selector.originY = selector.y = selector.targetY; - selector.moving = false; + selector_.origin_y = selector_.y = selector_.target_y; + selector_.moving = false; } } - else if (selector.despY < 0) // Va hacia arriba + else if (selector_.desp_y < 0) // Va hacia arriba { - if (selector.y < selector.targetY) // Ha llegado al destino + if (selector_.y < selector_.target_y) // Ha llegado al destino { - selector.originY = selector.y = selector.targetY; - selector.moving = false; + selector_.origin_y = selector_.y = selector_.target_y; + selector_.moving = false; } } - selector.rect.y = int(selector.y); + selector_.rect.y = int(selector_.y); // Actualiza el color del item - selector.itemColorIndex++; - selector.itemColorIndex = std::min(selector.numJumps - 1, selector.itemColorIndex); - selector.itemColor = selector.jumpItemColors[selector.itemColorIndex]; - selector.previousItemColor = selector.jumpItemColors[selector.numJumps - 1 - selector.itemColorIndex]; + selector_.item_color_index++; + selector_.item_color_index = std::min(selector_.num_jumps - 1, selector_.item_color_index); + selector_.item_color = selector_.jump_item_colors[selector_.item_color_index]; + selector_.previous_item_color = selector_.jump_item_colors[selector_.num_jumps - 1 - selector_.item_color_index]; } else { - selector.rect.y = int(selector.y); - selector.itemColorIndex = 0; - selector.itemColor = selector.jumpItemColors[selector.numJumps - 1]; - selector.previousItemColor = selector.jumpItemColors[0]; + selector_.rect.y = int(selector_.y); + selector_.item_color_index = 0; + selector_.item_color = selector_.jump_item_colors[selector_.num_jumps - 1]; + selector_.previous_item_color = selector_.jump_item_colors[0]; } - if (selector.resizing) { + if (selector_.resizing) { // Calcula el incremento en H - selector.h += selector.incH; - if (selector.incH > 0) // Crece + selector_.h += selector_.inc_h; + if (selector_.inc_h > 0) // Crece { - if (selector.h > selector.targetH) // Ha llegado al destino + if (selector_.h > selector_.target_h) // Ha llegado al destino { // selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index); - selector.originH = selector.h = selector.targetH; - selector.resizing = false; + selector_.origin_h = selector_.h = selector_.target_h; + selector_.resizing = false; } } - else if (selector.incH < 0) // Decrece + else if (selector_.inc_h < 0) // Decrece { - if (selector.h < selector.targetH) // Ha llegado al destino + if (selector_.h < selector_.target_h) // Ha llegado al destino { // selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index); - selector.originH = selector.h = selector.targetH; - selector.resizing = false; + selector_.origin_h = selector_.h = selector_.target_h; + selector_.resizing = false; } } - selector.rect.h = int(selector.h); + selector_.rect.h = int(selector_.h); } else { - selector.rect.h = getSelectorHeight(selector.index); + selector_.rect.h = getSelectorHeight(selector_.index); } } // Coloca el selector en una posición específica void Menu::setSelectorPos(int index) { - if (index < (int)item.size()) { - selector.index = index; - selector.rect.y = selector.y = selector.originY = selector.targetY = item[selector.index].rect.y; - selector.rect.w = rectBG.rect.w; - selector.rect.x = rectBG.rect.x; - selector.originH = selector.targetH = selector.rect.h = getSelectorHeight(selector.index); - selector.moving = false; - selector.resizing = false; + if (index < (int)items_.size()) { + selector_.index = index; + selector_.rect.y = selector_.y = selector_.origin_y = selector_.target_y = items_[selector_.index].rect.y; + selector_.rect.w = rect_bg_.rect.w; + selector_.rect.x = rect_bg_.rect.x; + selector_.origin_h = selector_.target_h = selector_.rect.h = getSelectorHeight(selector_.index); + selector_.moving = false; + selector_.resizing = false; } } // Obtiene la anchura del elemento más ancho del menu auto Menu::getWidestItem() -> int { - return std::accumulate(item.begin(), item.end(), 0, [](int acc, const Item &i) { return std::max(acc, i.rect.w); }); + return std::accumulate(items_.begin(), items_.end(), 0, [](int acc, const Item &i) { return std::max(acc, i.rect.w); }); } // Deja el menu apuntando al primer elemento void Menu::reset() { - itemSelected = MENU_NO_OPTION; - selector.index = 0; - if (item.empty()) { + item_selected_ = MENU_NO_OPTION; + selector_.index = 0; + if (items_.empty()) { return; } - selector.originY = selector.targetY = selector.y = item[0].rect.y; - selector.originH = selector.targetH = item[0].rect.h; - selector.moving = false; - selector.resizing = false; + selector_.origin_y = selector_.target_y = selector_.y = items_[0].rect.y; + selector_.origin_h = selector_.target_h = items_[0].rect.h; + selector_.moving = false; + selector_.resizing = false; // Si el primer elemento no es seleccionable, incrementa el selector - if (!item[selector.index].selectable) { + if (!items_[selector_.index].selectable) { increaseSelectorIndex(); - setSelectorPos(selector.index); + setSelectorPos(selector_.index); } } @@ -475,15 +475,15 @@ void Menu::reset() { void Menu::reorganize() { setRectSize(); - if (isCenteredOnX) { - centerMenuOnX(centerX); + if (is_centered_on_x_) { + centerMenuOnX(center_x_); } - if (isCenteredOnY) { - centerMenuOnY(centerY); + if (is_centered_on_y_) { + centerMenuOnY(center_y_); } - if (areElementsCenteredOnX) { + if (are_elements_centered_on_x_) { centerMenuElementsOnX(); } } @@ -491,65 +491,65 @@ void Menu::reorganize() { // Deja el menu apuntando al siguiente elemento void Menu::increaseSelectorIndex() { // Guarda el indice actual antes de modificarlo - selector.previousIndex = selector.index; + selector_.previous_index = selector_.index; // Obten las coordenadas del elemento actual - selector.y = selector.originY = item[selector.index].rect.y; - selector.h = selector.originH = getSelectorHeight(selector.index); + selector_.y = selector_.origin_y = items_[selector_.index].rect.y; + selector_.h = selector_.origin_h = getSelectorHeight(selector_.index); // Calcula cual es el siguiente elemento - ++selector.index %= item.size(); - while (!item[selector.index].selectable) { - ++selector.index %= item.size(); + ++selector_.index %= items_.size(); + while (!items_[selector_.index].selectable) { + ++selector_.index %= items_.size(); } // Establece las coordenadas y altura de destino - selector.targetY = item[selector.index].rect.y; - selector.despY = (selector.targetY - selector.originY) / selector.numJumps; + selector_.target_y = items_[selector_.index].rect.y; + selector_.desp_y = (selector_.target_y - selector_.origin_y) / selector_.num_jumps; - selector.targetH = getSelectorHeight(selector.index); - selector.incH = (selector.targetH - selector.originH) / selector.numJumps; + selector_.target_h = getSelectorHeight(selector_.index); + selector_.inc_h = (selector_.target_h - selector_.origin_h) / selector_.num_jumps; - selector.moving = true; - if (selector.incH != 0) { - selector.resizing = true; + selector_.moving = true; + if (selector_.inc_h != 0) { + selector_.resizing = true; } } // Deja el menu apuntando al elemento anterior void Menu::decreaseSelectorIndex() { // Guarda el indice actual antes de modificarlo - selector.previousIndex = selector.index; + selector_.previous_index = selector_.index; // Obten las coordenadas del elemento actual - selector.y = selector.originY = item[selector.index].rect.y; - selector.h = selector.originH = getSelectorHeight(selector.index); + selector_.y = selector_.origin_y = items_[selector_.index].rect.y; + selector_.h = selector_.origin_h = getSelectorHeight(selector_.index); // Calcula cual es el siguiente elemento - if (selector.index == 0) { - selector.index = item.size() - 1; + if (selector_.index == 0) { + selector_.index = items_.size() - 1; } else { - selector.index--; + selector_.index--; } - while (!item[selector.index].selectable) { - if (selector.index == 0) { - selector.index = item.size() - 1; + while (!items_[selector_.index].selectable) { + if (selector_.index == 0) { + selector_.index = items_.size() - 1; } else { - selector.index--; + selector_.index--; } } // Establece las coordenadas y altura de destino - selector.targetY = item[selector.index].rect.y; - selector.despY = (selector.targetY - selector.originY) / selector.numJumps; + selector_.target_y = items_[selector_.index].rect.y; + selector_.desp_y = (selector_.target_y - selector_.origin_y) / selector_.num_jumps; - selector.targetH = getSelectorHeight(selector.index); - selector.incH = (selector.targetH - selector.originH) / selector.numJumps; + selector_.target_h = getSelectorHeight(selector_.index); + selector_.inc_h = (selector_.target_h - selector_.origin_h) / selector_.num_jumps; - selector.moving = true; - if (selector.incH != 0) { - selector.resizing = true; + selector_.moving = true; + if (selector_.inc_h != 0) { + selector_.resizing = true; } } @@ -562,64 +562,64 @@ void Menu::update() { // Pinta el menu en pantalla void Menu::render() { // Rendereritza el fondo del menu - if (backgroundType == MENU_BACKGROUND_SOLID) { - SDL_FRect fBG = {(float)rectBG.rect.x, (float)rectBG.rect.y, (float)rectBG.rect.w, (float)rectBG.rect.h}; - SDL_SetRenderDrawColor(renderer, rectBG.color.r, rectBG.color.g, rectBG.color.b, rectBG.a); - SDL_RenderFillRect(renderer, &fBG); + if (background_type_ == MENU_BACKGROUND_SOLID) { + SDL_FRect fBG = {(float)rect_bg_.rect.x, (float)rect_bg_.rect.y, (float)rect_bg_.rect.w, (float)rect_bg_.rect.h}; + SDL_SetRenderDrawColor(renderer_, rect_bg_.color.r, rect_bg_.color.g, rect_bg_.color.b, rect_bg_.a); + SDL_RenderFillRect(renderer_, &fBG); } // Renderiza el rectangulo del selector - const SDL_FRect fTemp = {(float)selector.rect.x, (float)(selector.rect.y - 1), (float)selector.rect.w, (float)(selector.rect.h + 1)}; - SDL_SetRenderDrawColor(renderer, selector.color.r, selector.color.g, selector.color.b, selector.a); - SDL_RenderFillRect(renderer, &fTemp); + const SDL_FRect fTemp = {(float)selector_.rect.x, (float)(selector_.rect.y - 1), (float)selector_.rect.w, (float)(selector_.rect.h + 1)}; + SDL_SetRenderDrawColor(renderer_, selector_.color.r, selector_.color.g, selector_.color.b, selector_.a); + SDL_RenderFillRect(renderer_, &fTemp); // Renderiza el borde del fondo - if (backgroundType == MENU_BACKGROUND_SOLID) { - SDL_FRect fBGBorder = {(float)rectBG.rect.x, (float)rectBG.rect.y, (float)rectBG.rect.w, (float)rectBG.rect.h}; - SDL_SetRenderDrawColor(renderer, rectBG.color.r, rectBG.color.g, rectBG.color.b, 255); - SDL_RenderRect(renderer, &fBGBorder); + if (background_type_ == MENU_BACKGROUND_SOLID) { + SDL_FRect fBGBorder = {(float)rect_bg_.rect.x, (float)rect_bg_.rect.y, (float)rect_bg_.rect.w, (float)rect_bg_.rect.h}; + SDL_SetRenderDrawColor(renderer_, rect_bg_.color.r, rect_bg_.color.g, rect_bg_.color.b, 255); + SDL_RenderRect(renderer_, &fBGBorder); } // Crea una linea por si hay que dibujarla entre los items HorizontalLine line; - line.x1 = selector.rect.x + (selector.rect.w / 6); - line.x2 = line.x1 + ((selector.rect.w / 6) * 4); + line.x1 = selector_.rect.x + (selector_.rect.w / 6); + line.x2 = line.x1 + ((selector_.rect.w / 6) * 4); // Renderiza el texto - for (int i = 0; i < (int)item.size(); ++i) { - if (item[i].visible) { + for (int i = 0; i < (int)items_.size(); ++i) { + if (items_[i].visible) { // Comprueba si ha de dibujar una linea en el elemento del menu - if (item[i].line) { - line.y = item[i].rect.y + item[i].rect.h + (item[i].hPaddingDown / 2) - 1; - SDL_SetRenderDrawColor(renderer, 255, 255, 255, 64); - SDL_RenderLine(renderer, line.x1, line.y, line.x2, line.y); + if (items_[i].line) { + line.y = items_[i].rect.y + items_[i].rect.h + (items_[i].h_padding_down / 2) - 1; + SDL_SetRenderDrawColor(renderer_, 255, 255, 255, 64); + SDL_RenderLine(renderer_, line.x1, line.y, line.x2, line.y); } // Dibuja el elemento - if (item[i].greyed) { // Tiene prioridad si el elemento es gris - text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, colorGreyed); + if (items_[i].greyed) { // Tiene prioridad si el elemento es gris + text_->writeColored(items_[i].rect.x, items_[i].rect.y, items_[i].label, color_greyed_); } - else if (i == selector.index) { // A continuación si tiene el indice - const Color color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b}; - text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, color); + else if (i == selector_.index) { // A continuación si tiene el indice + const Color color = {selector_.item_color.r, selector_.item_color.g, selector_.item_color.b}; + text_->writeColored(items_[i].rect.x, items_[i].rect.y, items_[i].label, color); } - else if (i == selector.previousIndex) { // O si lo ha tenido - const Color color = {selector.previousItemColor.r, selector.previousItemColor.g, selector.previousItemColor.b}; - text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, color); + else if (i == selector_.previous_index) { // O si lo ha tenido + const Color color = {selector_.previous_item_color.r, selector_.previous_item_color.g, selector_.previous_item_color.b}; + text_->writeColored(items_[i].rect.x, items_[i].rect.y, items_[i].label, color); } - else if (item[i].selectable) { // O si simplemente es un elemento normal - text->write(item[i].rect.x, item[i].rect.y, item[i].label); + else if (items_[i].selectable) { // O si simplemente es un elemento normal + text_->write(items_[i].rect.x, items_[i].rect.y, items_[i].label); } else { // Si no es seleccionable - if ((item[i].linkedUp) && (i == selector.index + 1)) { // Si el elemento está enlazado con el elemento superior se pinta del color del selector - const Color color = {selector.itemColor.r, selector.itemColor.g, selector.itemColor.b}; - text->writeColored(item[i].rect.x, item[i].rect.y, item[i].label, color); + if ((items_[i].linked_up) && (i == selector_.index + 1)) { // Si el elemento está enlazado con el elemento superior se pinta del color del selector + const Color color = {selector_.item_color.r, selector_.item_color.g, selector_.item_color.b}; + text_->writeColored(items_[i].rect.x, items_[i].rect.y, items_[i].label, color); } else { // Si no está enlazado con el elemento superior se pinta con el color normal - text->write(item[i].rect.x, item[i].rect.y, item[i].label); + text_->write(items_[i].rect.x, items_[i].rect.y, items_[i].label); } } } @@ -630,95 +630,95 @@ void Menu::render() { void Menu::setRectSize(int w, int h) { // Establece el ancho if (w == 0) { // Si no se pasa un valor, se busca si hay uno prefijado - if (this->w == 0) { // Si no hay prefijado, coge el item mas ancho - rectBG.rect.w = findWidth() + text->getCharacterSize(); + if (this->w_ == 0) { // Si no hay prefijado, coge el item mas ancho + rect_bg_.rect.w = findWidth() + text_->getCharacterSize(); } else { // Si hay prefijado, coge ese - rectBG.rect.w = this->w; + rect_bg_.rect.w = this->w_; } } else { // Si se pasa un valor, se usa y se prefija - rectBG.rect.w = w; - this->w = w; + rect_bg_.rect.w = w; + this->w_ = w; } // Establece el alto if (h == 0) { // Si no se pasa un valor, se busca de manera automatica - rectBG.rect.h = findHeight() + text->getCharacterSize(); + rect_bg_.rect.h = findHeight() + text_->getCharacterSize(); } else { // Si se pasa un valor, se aplica - rectBG.rect.h = h; + rect_bg_.rect.h = h; } // La posición X es la del menú menos medio caracter - if (this->w != 0) { // Si el ancho esta prefijado, la x coinccide - rectBG.rect.x = x; + if (this->w_ != 0) { // Si el ancho esta prefijado, la x coinccide + rect_bg_.rect.x = x_; } else { // Si el ancho es automatico, se le da un poco de margen - rectBG.rect.x = x - (text->getCharacterSize() / 2); + rect_bg_.rect.x = x_ - (text_->getCharacterSize() / 2); } // La posición Y es la del menu menos la altura de medio caracter - rectBG.rect.y = y - (text->getCharacterSize() / 2); + rect_bg_.rect.y = y_ - (text_->getCharacterSize() / 2); // Establecemos los valores del rectangulo del selector a partir de los valores del rectangulo de fondo - setSelectorPos(selector.index); + setSelectorPos(selector_.index); } // Establece el color del rectangulo de fondo void Menu::setBackgroundColor(Color color, int alpha) { - rectBG.color = color; - rectBG.a = alpha; + rect_bg_.color = color; + rect_bg_.a = alpha; } // Establece el color del rectangulo del selector void Menu::setSelectorColor(Color color, int alpha) { - selector.color = color; - selector.a = alpha; + selector_.color = color; + selector_.a = alpha; } // Establece el color del texto del selector void Menu::setSelectorTextColor(Color color) { - selector.itemColor = color; + selector_.item_color = color; } // Centra el menu respecto un punto en el eje X void Menu::centerMenuOnX(int value) { - isCenteredOnX = true; + is_centered_on_x_ = true; if (value != 0) { - centerX = value; - } else if (centerX == 0) { + center_x_ = value; + } else if (center_x_ == 0) { return; } // Establece la nueva posición centrada en funcion del elemento más ancho o del ancho fijo del menu - if (w != 0) { // Si se ha definido un ancho fijo - x = (centerX) - (w / 2); + if (w_ != 0) { // Si se ha definido un ancho fijo + x_ = (center_x_) - (w_ / 2); } else { // Si se actua en función del elemento más ancho - x = (centerX) - (findWidth() / 2); + x_ = (center_x_) - (findWidth() / 2); } // Actualiza el rectangulo de fondo y del selector - rectBG.rect.x = x; - selector.rect.x = x; + rect_bg_.rect.x = x_; + selector_.rect.x = x_; // Reposiciona los elementos del menu - for (auto &i : item) { - i.rect.x = x; + for (auto &i : items_) { + i.rect.x = x_; } // Recalcula el rectangulo de fondo setRectSize(); // Vuelve a centrar los elementos si fuera el caso - if (areElementsCenteredOnX) { + if (are_elements_centered_on_x_) { centerMenuElementsOnX(); } } // Centra el menu respecto un punto en el eje Y void Menu::centerMenuOnY(int value) { - isCenteredOnY = true; - centerY = value; + is_centered_on_y_ = true; + center_y_ = value; // Establece la nueva posición centrada en funcion del elemento más ancho - y = (value) - (findHeight() / 2); + y_ = (value) - (findHeight() / 2); // Reposiciona los elementos del menu replaceElementsOnY(); @@ -729,77 +729,77 @@ void Menu::centerMenuOnY(int value) { // Centra los elementos del menu en el eje X void Menu::centerMenuElementsOnX() { - areElementsCenteredOnX = true; + are_elements_centered_on_x_ = true; - for (auto &i : item) { - i.rect.x = (centerX - (i.rect.w / 2)); + for (auto &i : items_) { + i.rect.x = (center_x_ - (i.rect.w / 2)); } } // Añade un item al menu void Menu::addItem(Item new_item) { - if (item.empty()) { // Si es el primer item coge la posición en el eje Y del propio menu - new_item.rect.y = y; + if (items_.empty()) { // Si es el primer item coge la posición en el eje Y del propio menu + new_item.rect.y = y_; } else { // En caso contrario, coge la posición en el eje Y a partir del último elemento - new_item.rect.y = item.back().rect.y + item.back().rect.h + item.back().hPaddingDown; + new_item.rect.y = items_.back().rect.y + items_.back().rect.h + items_.back().h_padding_down; } - new_item.rect.x = x; + new_item.rect.x = x_; - item.push_back(new_item); + items_.push_back(new_item); - setItemCaption(item.size() - 1, new_item.label); + setItemCaption(items_.size() - 1, new_item.label); - if (item.size() > 1) { - if (item[item.size() - 2].linkedDown) { - item.back().linkedUp = true; + if (items_.size() > 1) { + if (items_[items_.size() - 2].linked_down) { + items_.back().linked_up = true; } } - centerX = x + (findWidth() / 2); + center_x_ = x_ + (findWidth() / 2); reorganize(); } // Cambia el texto de un item void Menu::setItemCaption(int index, const std::string &text) { - item[index].label = text; - item[index].rect.w = this->text->lenght(item[index].label); - item[index].rect.h = this->text->getCharacterSize(); + items_[index].label = text; + items_[index].rect.w = this->text_->lenght(items_[index].label); + items_[index].rect.h = this->text_->getCharacterSize(); reorganize(); } // Establece el indice del itemm que se usará por defecto al cancelar el menu void Menu::setDefaultActionWhenCancel(int item) { - defaultActionWhenCancel = item; + default_action_when_cancel = item; } // Gestiona la entrada de teclado y mando durante el menu void Menu::checkInput() { if (Input::get()->checkInput(UP, REPEAT_FALSE)) { decreaseSelectorIndex(); - if (soundMove != nullptr) { - Audio::get()->playSound(soundMove); + if (sound_move_ != nullptr) { + Audio::get()->playSound(sound_move_); } } if (Input::get()->checkInput(DOWN, REPEAT_FALSE)) { increaseSelectorIndex(); - if (soundMove != nullptr) { - Audio::get()->playSound(soundMove); + if (sound_move_ != nullptr) { + Audio::get()->playSound(sound_move_); } } if (Input::get()->checkInput(ACCEPT, REPEAT_FALSE)) { - itemSelected = selector.index; - if (soundAccept != nullptr) { - Audio::get()->playSound(soundAccept); + item_selected_ = selector_.index; + if (sound_accept_ != nullptr) { + Audio::get()->playSound(sound_accept_); } } if (Input::get()->checkInput(CANCEL, REPEAT_FALSE)) { - itemSelected = defaultActionWhenCancel; - if (soundCancel != nullptr) { - Audio::get()->playSound(soundCancel); + item_selected_ = default_action_when_cancel; + if (sound_cancel_ != nullptr) { + Audio::get()->playSound(sound_cancel_); } } } @@ -811,85 +811,85 @@ auto Menu::findWidth() -> int { // Calcula el alto del menu auto Menu::findHeight() -> int { - const int height = std::accumulate(item.begin(), item.end(), 0, [](int acc, const Item &i) { return acc + i.rect.h + i.hPaddingDown; }); + const int height = std::accumulate(items_.begin(), items_.end(), 0, [](int acc, const Item &i) { return acc + i.rect.h + i.h_padding_down; }); - return height - item.back().hPaddingDown; + return height - items_.back().h_padding_down; } // Recoloca los elementos del menu en el eje Y void Menu::replaceElementsOnY() { - item[0].rect.y = y; + items_[0].rect.y = y_; - for (int i = 1; i < (int)item.size(); i++) { - item[i].rect.y = item[i - 1].rect.y + item[i - 1].rect.h + item[i - 1].hPaddingDown; + for (int i = 1; i < (int)items_.size(); i++) { + items_[i].rect.y = items_[i - 1].rect.y + items_[i - 1].rect.h + items_[i - 1].h_padding_down; } } // Establece el estado seleccionable de un item void Menu::setSelectable(int index, bool value) { - item[index].selectable = value; + items_[index].selectable = value; } // Establece el estado agrisado de un item void Menu::setGreyed(int index, bool value) { - item[index].greyed = value; + items_[index].greyed = value; } // Establece el estado de enlace de un item void Menu::setLinkedDown(int index, bool value) { - item[index].linkedDown = value; + items_[index].linked_down = value; } // Establece el estado de visibilidad de un item void Menu::setVisible(int index, bool value) { - item[index].visible = value; + items_[index].visible = value; } // Calcula la altura del selector auto Menu::getSelectorHeight(int value) -> int { - if (item[value].linkedDown) { - return item[value].rect.h + item[value].hPaddingDown + item[value + 1].rect.h; + if (items_[value].linked_down) { + return items_[value].rect.h + items_[value].h_padding_down + items_[value + 1].rect.h; } - return item[value].rect.h; + return items_[value].rect.h; } // Establece el nombre del menu void Menu::setName(const std::string &name) { - this->name = name; + this->name_ = name; } // Establece la posición del menu void Menu::setPos(int x, int y) { - this->x = x; - this->y = y; + this->x_ = x; + this->y_ = y; } // Establece el tipo de fondo del menu void Menu::setBackgroundType(int value) { - backgroundType = value; + background_type_ = value; } // Establece la fuente de texto que se utilizará void Menu::setText(const std::string &font_png, const std::string &font_txt) { - if (text == nullptr) { - text = new Text(Asset::get()->get(font_png), Asset::get()->get(font_txt), renderer); + if (text_ == nullptr) { + text_ = new Text(Asset::get()->get(font_png), Asset::get()->get(font_txt), renderer_); } } // Calcula los colores del selector para el degradado void Menu::setSelectorItemColors() { const Color colorFrom = {255, 255, 255}; - const Color colorTo = selector.itemColor; + const Color colorTo = selector_.item_color; - for (int i = 0; i < selector.numJumps; ++i) { - const float step = ((float)i / (selector.numJumps - 1)); + for (int i = 0; i < selector_.num_jumps; ++i) { + const float step = ((float)i / (selector_.num_jumps - 1)); const int r = colorFrom.r + ((colorTo.r - colorFrom.r) * step); const int g = colorFrom.g + ((colorTo.g - colorFrom.g) * step); const int b = colorFrom.b + ((colorTo.b - colorFrom.b) * step); - selector.jumpItemColors[i].r = r; - selector.jumpItemColors[i].g = g; - selector.jumpItemColors[i].b = b; + selector_.jump_item_colors[i].r = r; + selector_.jump_item_colors[i].g = g; + selector_.jump_item_colors[i].b = b; } - selector.itemColorIndex = 0; + selector_.item_color_index = 0; } \ No newline at end of file diff --git a/source/game/ui/menu.h b/source/game/ui/menu.h index ccc0c3a..6dfc923 100644 --- a/source/game/ui/menu.h +++ b/source/game/ui/menu.h @@ -24,6 +24,56 @@ constexpr int MENU_NO_OPTION = -1; // Clase Menu class Menu { + public: + explicit Menu(SDL_Renderer *renderer, const std::string &file = ""); // Constructor + ~Menu(); // Destructor + + auto loadFromBytes(const std::vector<uint8_t> &bytes, const std::string &name_for_logs = "") -> bool; // Carga el menu desde bytes en memoria + void loadAudioFile(const std::string &file, int sound); // Carga los ficheros de audio + + [[nodiscard]] auto getName() const -> const std::string &; // Obtiene el nombre del menu + auto getItemSelected() -> int; // Obtiene el valor de la variable + + void reset(); // Deja el menu apuntando al primer elemento + void checkInput(); // Gestiona la entrada de teclado y mando durante el menu + void update(); // Actualiza la logica del menu + void render(); // Pinta el menu en pantalla + + void setBackgroundColor(Color color, int alpha); // Establece el color del rectangulo de fondo + void setSelectorColor(Color color, int alpha); // Establece el color del rectangulo del selector + void setSelectorTextColor(Color color); // Establece el color del texto del selector + + void centerMenuOnX(int value = 0); // Centra el menu respecto a un punto en el eje X + void centerMenuOnY(int value); // Centra el menu respecto a un punto en el eje Y + void centerMenuElementsOnX(); // Centra los elementos del menu en el eje X + + struct Item { + std::string label; // Texto + SDL_Rect rect; // Rectangulo que delimita el elemento + int h_padding_down; // Espaciado bajo el elemento + bool selectable; // Indica si se puede seleccionar + bool greyed; // Indica si ha de aparecer con otro color mas oscuro + bool linked_down; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector + bool linked_up; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector + bool visible; // Indica si el elemento es visible + bool line; // Indica si el elemento lleva una linea a continuación + }; + + void addItem(Item new_item); // Añade un item al menu + void setItemCaption(int index, const std::string &text); // Cambia el texto de un item + void setDefaultActionWhenCancel(int item); // Establece el indice del item que se usará por defecto al cancelar el menu + void setSelectorPos(int index); // Coloca el selector en una posición específica + void setSelectable(int index, bool value); // Establece el estado seleccionable de un item + void setGreyed(int index, bool value); // Establece el estado agrisado de un item + void setLinkedDown(int index, bool value); // Establece el estado de enlace de un item + void setVisible(int index, bool value); // Establece el estado de visibilidad de un item + + void setName(const std::string &name); // Establece el nombre del menu + void setPos(int x, int y); // Establece la posición del menu + void setBackgroundType(int value); // Establece el tipo de fondo del menu + void setText(const std::string &font_png, const std::string &font_txt); // Establece la fuente de texto que se utilizará + void setRectSize(int w = 0, int h = 0); // Establece el rectangulo de fondo del menu + private: struct Rectangle { SDL_Rect rect; // Rectangulo @@ -31,200 +81,72 @@ class Menu { int a; // Transparencia }; - struct Item { - std::string label; // Texto - SDL_Rect rect; // Rectangulo que delimita el elemento - int hPaddingDown; // Espaciado bajo el elemento - bool selectable; // Indica si se puede seleccionar - bool greyed; // Indica si ha de aparecer con otro color mas oscuro - bool linkedDown; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector - bool linkedUp; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector - bool visible; // Indica si el elemento es visible - bool line; // Indica si el elemento lleva una linea a continuación - }; - struct Selector { - float originY; // Coordenada de origen - float targetY; // Coordenada de destino - float despY; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps + float origin_y; // Coordenada de origen + float target_y; // Coordenada de destino + float desp_y; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps bool moving; // Indica si el selector está avanzando hacia el destino - float originH; // Altura de origen - float targetH; // Altura de destino - float incH; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto + float origin_h; // Altura de origen + float target_h; // Altura de destino + float inc_h; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto bool resizing; // Indica si el selector está cambiando de tamaño float y; // Coordenada actual, usado para el desplazamiento float h; // Altura actual, usado para el cambio de tamaño - int numJumps; // Numero de pasos preestablecido para llegar al destino + int num_jumps; // Numero de pasos preestablecido para llegar al destino int index; // Elemento del menu que tiene el foco - int previousIndex; // Elemento que tenia el foco previamente - Color previousItemColor; // Color del item nque tenia el foco previamente + int previous_index; // Elemento que tenia el foco previamente + Color previous_item_color; // Color del item nque tenia el foco previamente SDL_Rect rect; // Rectangulo del selector Color color; // Color del selector - Color itemColor; // Color del item - Color jumpItemColors[8]; // Transición de colores para el item seleccionado - int itemColorIndex; // Indice del color de transición para el item seleccionado + Color item_color; // Color del item + Color jump_item_colors[8]; // Transición de colores para el item seleccionado + int item_color_index; // Indice del color de transición para el item seleccionado int a; // Cantidad de transparencia para el rectangulo del selector }; + auto load(const std::string &file_path) -> bool; // Carga la configuración del menu desde un archivo de texto + auto parseFromStream(std::istream &file, const std::string &filename) -> bool; // Parser compartido (recibe cualquier istream) + auto setVars(const std::string &var, const std::string &value) -> bool; // Asigna variables a partir de dos cadenas + static auto setItem(Item *item, const std::string &var, const std::string &value) -> bool; // Asigna variables a partir de dos cadenas + + void reorganize(); // Actualiza el menu para recolocarlo correctamente y establecer el tamaño + void increaseSelectorIndex(); // Deja el menu apuntando al siguiente elemento + void decreaseSelectorIndex(); // Deja el menu apuntando al elemento anterior + void updateSelector(); // Actualiza la posicion y el estado del selector + auto getWidestItem() -> int; // Obtiene la anchura del elemento más ancho del menu + void checkMenuInput(Menu *menu); // Gestiona la entrada de teclado y mando durante el menu + auto findWidth() -> int; // Calcula el ancho del menu + auto findHeight() -> int; // Calcula el alto del menu + void replaceElementsOnY(); // Recoloca los elementos del menu en el eje Y + auto getSelectorHeight(int value) -> int; // Calcula la altura del selector + void setSelectorItemColors(); // Calcula los colores del selector para el degradado + // Objetos y punteros - SDL_Renderer *renderer; // Puntero al renderizador de la ventana - Text *text; // Texto para poder escribir los items del menu + SDL_Renderer *renderer_; // Puntero al renderizador de la ventana + Text *text_; // Texto para poder escribir los items del menu // Variables - std::string name; // Nombre del menu - int x; // Posición en el eje X de la primera letra del primer elemento - int y; // Posición en el eje Y de la primera letra del primer elemento - int h; // Altura del menu - int w; // Anchura del menu - int itemSelected; // Índice del item del menu que ha sido seleccionado - int defaultActionWhenCancel; // Indice del item del menu que se selecciona cuando se cancela el menu - int backgroundType; // Tipo de fondo para el menu - int centerX; // Centro del menu en el eje X - int centerY; // Centro del menu en el eje Y - bool isCenteredOnX; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X - bool isCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y - bool areElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X - int widestItem; // Anchura del elemento más ancho - JA_Sound_t *soundAccept; // Sonido al aceptar o elegir una opción del menu - JA_Sound_t *soundCancel; // Sonido al cancelar el menu - JA_Sound_t *soundMove; // Sonido al mover el selector - Color colorGreyed; // Color para los elementos agrisados - Rectangle rectBG; // Rectangulo de fondo del menu - std::vector<Item> item; // Estructura para cada elemento del menu - Selector selector; // Variables para pintar el selector del menu - std::string font_png; - std::string font_txt; - - // Carga la configuración del menu desde un archivo de texto - auto load(const std::string &file_path) -> bool; - - // Parser compartido (recibe cualquier istream) - auto parseFromStream(std::istream &file, const std::string &filename) -> bool; - - // Asigna variables a partir de dos cadenas - auto setVars(const std::string &var, const std::string &value) -> bool; - - // Asigna variables a partir de dos cadenas - static auto setItem(Item *item, const std::string &var, const std::string &value) -> bool; - - // Actualiza el menu para recolocarlo correctamente y establecer el tamaño - void reorganize(); - - // Deja el menu apuntando al siguiente elemento - void increaseSelectorIndex(); - - // Deja el menu apuntando al elemento anterior - void decreaseSelectorIndex(); - - // Actualiza la posicion y el estado del selector - void updateSelector(); - - // Obtiene la anchura del elemento más ancho del menu - auto getWidestItem() -> int; - - // Gestiona la entrada de teclado y mando durante el menu - void checkMenuInput(Menu *menu); - - // Calcula el ancho del menu - auto findWidth() -> int; - - // Calcula el alto del menu - auto findHeight() -> int; - - // Recoloca los elementos del menu en el eje Y - void replaceElementsOnY(); - - // Calcula la altura del selector - auto getSelectorHeight(int value) -> int; - - // Calcula los colores del selector para el degradado - void setSelectorItemColors(); - - public: - // Constructor - explicit Menu(SDL_Renderer *renderer, const std::string &file = ""); - - // Destructor - ~Menu(); - - // Carga el menu desde bytes en memoria - auto loadFromBytes(const std::vector<uint8_t> &bytes, const std::string &nameForLogs = "") -> bool; - - // Carga los ficheros de audio - void loadAudioFile(const std::string &file, int sound); - - // Obtiene el nombre del menu - [[nodiscard]] auto getName() const -> const std::string &; - - // Obtiene el valor de la variable - auto getItemSelected() -> int; - - // Deja el menu apuntando al primer elemento - void reset(); - - // Gestiona la entrada de teclado y mando durante el menu - void checkInput(); - - // Actualiza la logica del menu - void update(); - - // Pinta el menu en pantalla - void render(); - - // Establece el color del rectangulo de fondo - void setBackgroundColor(Color color, int alpha); - - // Establece el color del rectangulo del selector - void setSelectorColor(Color color, int alpha); - - // Establece el color del texto del selector - void setSelectorTextColor(Color color); - - // Centra el menu respecto a un punto en el eje X - void centerMenuOnX(int value = 0); - - // Centra el menu respecto a un punto en el eje Y - void centerMenuOnY(int value); - - // Centra los elementos del menu en el eje X - void centerMenuElementsOnX(); - - // Añade un item al menu - void addItem(Item new_item); - - // Cambia el texto de un item - void setItemCaption(int index, const std::string &text); - - // Establece el indice del item que se usará por defecto al cancelar el menu - void setDefaultActionWhenCancel(int item); - - // Coloca el selector en una posición específica - void setSelectorPos(int index); - - // Establece el estado seleccionable de un item - void setSelectable(int index, bool value); - - // Establece el estado agrisado de un item - void setGreyed(int index, bool value); - - // Establece el estado de enlace de un item - void setLinkedDown(int index, bool value); - - // Establece el estado de visibilidad de un item - void setVisible(int index, bool value); - - // Establece el nombre del menu - void setName(const std::string &name); - - // Establece la posición del menu - void setPos(int x, int y); - - // Establece el tipo de fondo del menu - void setBackgroundType(int value); - - // Establece la fuente de texto que se utilizará - void setText(const std::string &font_png, const std::string &font_txt); - - // Establece el rectangulo de fondo del menu - void setRectSize(int w = 0, int h = 0); + std::string name_; // Nombre del menu + int x_; // Posición en el eje X de la primera letra del primer elemento + int y_; // Posición en el eje Y de la primera letra del primer elemento + int h_; // Altura del menu + int w_; // Anchura del menu + int item_selected_; // Índice del item del menu que ha sido seleccionado + int default_action_when_cancel_; // Indice del item del menu que se selecciona cuando se cancela el menu + int background_type_; // Tipo de fondo para el menu + int center_x_; // Centro del menu en el eje X + int center_y_; // Centro del menu en el eje Y + bool is_centered_on_x_; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X + bool is_centered_on_y_; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y + bool are_elements_centered_on_x_; // Variable para saber si los elementos van centrados en el eje X + int widest_item_; // Anchura del elemento más ancho + JA_Sound_t *sound_accept_; // Sonido al aceptar o elegir una opción del menu + JA_Sound_t *sound_cancel_; // Sonido al cancelar el menu + JA_Sound_t *sound_move_; // Sonido al mover el selector + Color color_greyed_; // Color para los elementos agrisados + Rectangle rect_bg_; // Rectangulo de fondo del menu + std::vector<Item> items_; // Estructura para cada elemento del menu + Selector selector_; // Variables para pintar el selector del menu + std::string font_png_; + std::string font_txt_; }; diff --git a/source/utils/utils.h b/source/utils/utils.h index 349a61a..a291de5 100644 --- a/source/utils/utils.h +++ b/source/utils/utils.h @@ -70,8 +70,8 @@ struct DemoKeys { // Estructura para albergar métodos de control struct InputDevice { - int id; // Identificador en el vector de mandos - std::string name; // Nombre del dispositivo + int id; // Identificador en el vector de mandos + std::string name; // Nombre del dispositivo Uint8 device_type; // Tipo de dispositivo (teclado o mando) };