← index
libmx2/MX2_Project/webmx/mx2/include/mx.hpp
Source: libmx2/MX2_Project/webmx/mx2/include/mx.hpp
/**
 * @file mx.hpp
 * @brief Central SDL2 application window class and related includes.
 *
 * Pulls in all core libmx subsystems and provides mxWindow, which manages
 * the SDL2 window, renderer, event loop, and optional mixer.
 */
#ifndef __MX__H___
#define __MX__H___

#ifdef __EMSCRIPTEN__
#include "config.hpp"
#else
#include "config.h"
#endif

#include "SDL.h"
#include "SDL_ttf.h"
#include "exception.hpp"
#include "font.hpp"
#include "input.hpp"
#include "joystick.hpp"
#include "loadpng.hpp"
#include "object.hpp"
#include "tee_stream.hpp"
#include "texture.hpp"
#include "util.hpp"
#include "wrapper.hpp"
#include <iostream>
#include <memory>
#include <string>

#ifdef WITH_MIXER
#include "sound.hpp"
#endif

namespace mx {

    /**
     * @class mxWindow
     * @brief Main SDL2 application window.
     *
     * Creates and manages the SDL2 window and renderer.  Derived classes must
     * implement event() and draw() to provide application-specific behaviour.
     * The window runs a blocking loop() that drives the frame and event cycle.
     */
    class mxWindow {
      public:
        std::unique_ptr<obj::Object> object; ///< Optional attached game object.

        mxWindow() = delete;

        /**
         * @brief Create the SDL2 window.
         * @param name  Window title.
         * @param w     Window width in pixels.
         * @param h     Window height in pixels.
         * @param full  If @c true, start in fullscreen mode.
         */
        mxWindow(const std::string &name, int w, int h, bool full = false);

        /** @brief Destructor — destroys the SDL2 window and renderer. */
        virtual ~mxWindow();

        mxWindow(const mxWindow &) = delete;
        mxWindow &operator=(const mxWindow &) = delete;
        mxWindow(mxWindow &&) = delete;
        mxWindow &operator=(mxWindow &&) = delete;

        /**
         * @brief Process a single SDL event (pure virtual).
         * @param e The SDL event to handle.
         */
        virtual void event(SDL_Event &e) = 0;

        /**
         * @brief Draw the current frame (pure virtual).
         * @param ren Active SDL renderer.
         */
        virtual void draw(SDL_Renderer *ren) = 0;

        /**
         * @brief Create a streaming SDL_Texture of the given size.
         * @param w Width in pixels.
         * @param h Height in pixels.
         * @return New SDL_Texture (caller owns it).
         */
        SDL_Texture *createTexture(int w, int h);

        /**
         * @brief Enable or disable the main loop.
         * @param a @c true to keep running, @c false to stop.
         */
        void setActive(bool a) { active = a; }

        /** @brief Run the event+draw loop until setActive(false) is called. */
        void loop();

        /** @brief Process one iteration of events and drawing. */
        void proc();

        /** @brief Stop the loop on the next cycle (sets active = false). */
        void destroy() { setActive(false); }

        /**
         * @brief Prepend the asset directory to all relative file paths.
         * @param path Asset directory path.
         */
        void setPath(const std::string &path) { util.path = path; }

        /**
         * @brief Set the window icon from an SDL_Surface.
         * @param icon Surface to use as the icon.
         */
        void setIcon(SDL_Surface *icon);

        /**
         * @brief Set the window icon from an image file.
         * @param icon Image file path.
         */
        void setIcon(const std::string &icon);

        /**
         * @brief Toggle fullscreen mode.
         * @param full @c true to enable fullscreen.
         */
        void setFullScreen(bool full);

        /** @brief Request the SDL event loop to quit. */
        void quit();

        mxUtil util;                      ///< Utility/asset helper.
        Text text;                        ///< 2D text renderer.
        SDL_Renderer *renderer = nullptr; ///< Active SDL renderer.
        int width = 0;                    ///< Window width in pixels.
        int height = 0;                   ///< Window height in pixels.

        /**
         * @brief Attach an obj::Object to receive draw/event callbacks.
         * @param o Pointer to the object (window does not take ownership).
         */
        void setObject(obj::Object *o);

        SDL_Window *window = nullptr; ///< Underlying SDL window handle.

        /**
         * @brief Change the window title bar text.
         * @param title New title string.
         */
        void setWindowTitle(const std::string &title);

#ifdef WITH_MIXER
        Mixer mixer; ///< Audio mixer (only when built with WITH_MIXER).
#endif
      protected:
        /**
         * @brief Internal helper: create and initialise the SDL window+renderer.
         * @param name  Title string.
         * @param w     Width.
         * @param h     Height.
         * @param full  Fullscreen flag.
         */
        void create_window(const std::string &name, int w, int h, bool full);
        bool active = false; ///< Controls the main loop.
        SDL_Event e;         ///< Reusable SDL event structure.
    };
} // namespace mx

#endif