/** * @file util.hpp * @brief General SDL utility helpers, file I/O, and compression utilities. * * Provides mxUtil for window-attached helpers (texture loading, font loading, * joystick management) plus free functions for file reading, string * compression/decompression (zlib), and random number generation. */ #ifndef __UTIL_HPP__ #define __UTIL_HPP__ #include "SDL.h" #include "SDL_ttf.h" #include "tee_stream.hpp" #include <iostream> #include <memory> #include <optional> #include <string> #include <vector> #include <zlib.h> namespace mx { /** * @class mxUtil * @brief Utility bag for SDL-based applications. * * Holds the asset path and provides convenience wrappers for loading textures, * fonts, printing text, and managing SDL joystick handles. Non-copyable and * non-movable by design — embed one instance per window. */ class mxUtil { public: /** @brief Destructor — closes all open joystick handles. */ ~mxUtil() { closeJoystick(); } mxUtil() = default; mxUtil(const mxUtil &) = delete; mxUtil &operator=(const mxUtil &) = delete; mxUtil(mxUtil &&) = delete; mxUtil &operator=(mxUtil &&) = delete; #ifdef FOR_WASM std::string path = "/assets"; ///< Root asset directory (Emscripten). #else std::string path = "assets"; ///< Root asset directory (native). #endif /** * @brief Prepend the asset path to a filename. * @param filename Relative filename. * @return Full path string. */ std::string getFilePath(const std::string &filename); /** * @brief Render a text string onto an SDL_Renderer. * @param renderer Active renderer. * @param font TTF font to use. * @param x X position. * @param y Y position. * @param text String to draw. * @param col Text colour. */ void printText(SDL_Renderer *renderer, TTF_Font *font, int x, int y, const std::string &text, SDL_Color col); /** * @brief Load an SDL_Texture from a file. * @param renderer Active renderer. * @param filename Image file path (relative to asset root). * @return Loaded texture (caller owns it), or nullptr on failure. */ SDL_Texture *loadTexture(SDL_Renderer *renderer, const std::string &filename); /** * @brief Load an SDL_Texture with colour-key transparency. * @param renderer Active renderer. * @param filename Image file path. * @param w Output: image width. * @param h Output: image height. * @param color Apply colour key if @c true. * @param key Colour to treat as transparent. * @return Loaded texture, or nullptr on failure. */ SDL_Texture *loadTexture(SDL_Renderer *renderer, const std::string &filename, int &w, int &h, bool color, SDL_Color key); /** * @brief Load an image as an SDL_Surface. * @param name Image file path. * @return Newly allocated SDL_Surface, or nullptr on failure. */ SDL_Surface *loadSurface(const std::string &name); /** * @brief Load a TTF font at the specified point size. * @param filename Font file path. * @param size Point size. * @return Loaded TTF_Font handle (caller owns it), or nullptr on failure. */ TTF_Font *loadFont(const std::string &filename, int size); /** @brief Initialise and open SDL joysticks. */ void initJoystick(); /** @brief Close all open SDL joystick handles. */ void closeJoystick(); std::vector<SDL_Joystick *> stick; ///< Open joystick handles. }; /** * @brief Read an entire file into a byte vector. * @param filename Path to the file. * @return Vector of bytes. */ std::vector<char> readFile(const std::string &filename); /** * @brief Read an entire text file into a string. * @param filename Path to the file. * @return File contents as a string. */ std::string readFileToString(const std::string &filename); /** * @brief Decompress a zlib-compressed data block. * @param data Pointer to compressed data. * @param size_ Size of compressed data in bytes. * @return Decompressed string. */ std::string decompressString(void *data, uLong size_); /** * @brief Compress a string using zlib. * @param text Input string. * @param len Output: length of the compressed data. * @return Unique pointer to the compressed byte array. */ std::unique_ptr<char[]> compressString(const std::string &text, uLong &len); /** * @brief Generate a random float in the given range. * @param min Lower bound (inclusive). * @param max Upper bound (inclusive). * @return Random float in [min, max]. */ float generateRandomFloat(float min, float max); /** * @brief Generate a random integer in the given range. * @param min Lower bound (inclusive). * @param max Upper bound (inclusive). * @return Random integer in [min, max]. */ int generateRandomInt(int min, int max); } // namespace mx #endif