#ifndef WINDOW_H #define WINDOW_H #include "pch.h" #include "utils.h" #include "window/keybinds.h" struct Image { SDL_Texture *texture; Vec2 size; ~Image() { SDL_DestroyTexture(texture); } }; struct Font { TTF_Font *font; bool pixel_art; ~Font() { TTF_CloseFont(font); } }; struct Text { SDL_Texture *texture; Vec2 size; ~Text() { SDL_DestroyTexture(texture); } }; // Image pool inline Pool image_pool; // Font pool inline Pool font_pool; // Text pool inline Pool text_pool; struct Event { enum Type { NONE, QUIT, KEY_UP, KEY_DOWN, TEXT_INPUT, SCROLL, MOUSE_LEAVE, MOUSE_BUTTON_UP, MOUSE_BUTTON_DOWN, MOUSE_MOVE } type; union { struct { Key key; } key; std::string *text_input; Vec2 scroll; struct { Key button; Vec2 position; } mouse_button; struct { Vec2 position; Vec2 delta; } mouse_move; }; }; struct Animation { std::vector frames; float frame_rate; ~Animation() { for (uint64_t frame_id : frames) image_pool.release(frame_id); } }; inline Pool animation_pool; struct Window { public: // title can be free'd by the caller after the window is created, as it's copied internally. Window(Vec2 size, const char *title); void update(Vec2 new_size, const char *new_title); ~Window(); // Rendering functions std::vector load_image_set(const char *path, Vec2 tile_size, Vec2 padding, Vec2 offset, bool pixel_art); uint64_t load_image(const char *path, bool pixel_art); uint64_t create_image(Vec2 size, bool pixel_art); Vec2 get_image_size(uint64_t image_id); bool update_image(uint64_t image_id, Rect content_rect, const char *new_content, uint32_t length); uint64_t load_font(const char *path, int font_size, bool bold, bool italic, bool underline, bool pixel_art); // text is copied internally, so it can be free'd by the caller after the text is created. uint64_t create_text(uint64_t font_id, const char *text, uint32_t length, Color color); Vec2 get_text_size(uint64_t text_id); bool write(uint64_t text_id, Vec2 position, float z, float angle, Vec2 pivot, Vec2 scale, float alpha); bool draw(uint64_t image_id, Vec2 position, float z, float angle, Vec2 pivot, Vec2 scale, float alpha); bool draw_rect(Rect rect, Color color, float z, float angle, Vec2 pivot, Vec2 scale, float alpha); bool draw_scripted(uint64_t scripted_id, Vec2 position, float z, float angle, Vec2 pivot, Vec2 scale, float alpha); void render(); // the rest of the calls only build the instruction list, this actually renders everything added to the screen (following z order) void clear(); // clears the instruction list // Event handling bool poll(Event &event); // returns true if an event was polled, false otherwise // Clipboard get // To be free'd by the caller after use. const char *paste(); // Time uint64_t get_time(); // returns the time in nanoseconds since the window was created private: // internal data and functions SDL_Window *window; SDL_Renderer *renderer; Vec2 real_size; Vec2 virtual_size; Vec2 offset; float scale; // White pixel texture for drawing colored rectangles SDL_Texture *white_tex; struct RenderInstruction { enum Type { DRAW_IMAGE, DRAW_TEXT, DRAW_RECT } type; float z; float angle; Vec2 pivot; Vec2 scale; float alpha; union { struct { uint64_t image_id; Vec2 position; } draw_image; struct { uint64_t text_id; Vec2 position; } draw_text; struct { Rect rect; Color color; } draw_rect; struct { uint64_t scripted_id; Vec2 position; } draw_scripted; }; }; std::vector render_instructions; void compute_transform(); bool mouse_in_window(const Vec2 real_position, Vec2 &virtual_position); void draw_letterbox(); }; inline Window window({720, 480}, "Mysth Engine"); #endif