403 lines
7.9 KiB
C++
403 lines
7.9 KiB
C++
#ifndef WINDOW_H
|
|
#define WINDOW_H
|
|
|
|
#include "pch.h"
|
|
#include "utils.h"
|
|
|
|
struct Image {
|
|
SDL_Texture *texture;
|
|
Vec2<float> size;
|
|
|
|
~Image() {
|
|
SDL_DestroyTexture(texture);
|
|
}
|
|
};
|
|
|
|
struct Font {
|
|
TTF_Font *font;
|
|
bool pixel_art;
|
|
|
|
~Font() {
|
|
TTF_CloseFont(font);
|
|
}
|
|
};
|
|
|
|
struct Text {
|
|
SDL_Texture *texture;
|
|
Vec2<float> size;
|
|
|
|
~Text() {
|
|
SDL_DestroyTexture(texture);
|
|
}
|
|
};
|
|
|
|
// Image pool
|
|
inline Pool<Image> image_pool;
|
|
|
|
// Font pool
|
|
inline Pool<Font> font_pool;
|
|
|
|
// Text pool
|
|
inline Pool<Text> text_pool;
|
|
|
|
enum Key : uint16_t {
|
|
Unknown = SDL_SCANCODE_UNKNOWN,
|
|
|
|
A = SDL_SCANCODE_A,
|
|
B,
|
|
C,
|
|
D,
|
|
E,
|
|
F,
|
|
G,
|
|
H,
|
|
I,
|
|
J,
|
|
K,
|
|
L,
|
|
M,
|
|
N,
|
|
O,
|
|
P,
|
|
Q,
|
|
R,
|
|
S,
|
|
T,
|
|
U,
|
|
V,
|
|
W,
|
|
X,
|
|
Y,
|
|
Z,
|
|
|
|
Num0 = SDL_SCANCODE_0,
|
|
Num1,
|
|
Num2,
|
|
Num3,
|
|
Num4,
|
|
Num5,
|
|
Num6,
|
|
Num7,
|
|
Num8,
|
|
Num9,
|
|
|
|
Space = SDL_SCANCODE_SPACE,
|
|
Enter = SDL_SCANCODE_RETURN,
|
|
Escape = SDL_SCANCODE_ESCAPE,
|
|
Tab = SDL_SCANCODE_TAB,
|
|
Backspace = SDL_SCANCODE_BACKSPACE,
|
|
|
|
LeftShift = SDL_SCANCODE_LSHIFT,
|
|
RightShift = SDL_SCANCODE_RSHIFT,
|
|
LeftCtrl = SDL_SCANCODE_LCTRL,
|
|
RightCtrl = SDL_SCANCODE_RCTRL,
|
|
LeftAlt = SDL_SCANCODE_LALT,
|
|
RightAlt = SDL_SCANCODE_RALT,
|
|
CapsLock = SDL_SCANCODE_CAPSLOCK,
|
|
|
|
Up = SDL_SCANCODE_UP,
|
|
Down = SDL_SCANCODE_DOWN,
|
|
Left = SDL_SCANCODE_LEFT,
|
|
Right = SDL_SCANCODE_RIGHT,
|
|
Home = SDL_SCANCODE_HOME,
|
|
End = SDL_SCANCODE_END,
|
|
PageUp = SDL_SCANCODE_PAGEUP,
|
|
PageDown = SDL_SCANCODE_PAGEDOWN,
|
|
|
|
Delete = SDL_SCANCODE_DELETE,
|
|
Insert = SDL_SCANCODE_INSERT,
|
|
|
|
Minus = SDL_SCANCODE_MINUS,
|
|
Equals = SDL_SCANCODE_EQUALS,
|
|
LeftBracket = SDL_SCANCODE_LEFTBRACKET,
|
|
RightBracket = SDL_SCANCODE_RIGHTBRACKET,
|
|
Semicolon = SDL_SCANCODE_SEMICOLON,
|
|
Apostrophe = SDL_SCANCODE_APOSTROPHE,
|
|
Grave = SDL_SCANCODE_GRAVE,
|
|
Comma = SDL_SCANCODE_COMMA,
|
|
Period = SDL_SCANCODE_PERIOD,
|
|
Slash = SDL_SCANCODE_SLASH,
|
|
Backslash = SDL_SCANCODE_NONUSBACKSLASH,
|
|
|
|
F1 = SDL_SCANCODE_F1,
|
|
F2,
|
|
F3,
|
|
F4,
|
|
F5,
|
|
F6,
|
|
F7,
|
|
F8,
|
|
F9,
|
|
F10,
|
|
F11,
|
|
F12,
|
|
|
|
MouseLeft = 513,
|
|
MouseMiddle,
|
|
MouseRight
|
|
};
|
|
|
|
constexpr std::pair<std::string, Key> KEY_NAMES[] = {
|
|
{"a", Key::A},
|
|
{"b", Key::B},
|
|
{"c", Key::C},
|
|
{"d", Key::D},
|
|
{"e", Key::E},
|
|
{"f", Key::F},
|
|
{"g", Key::G},
|
|
{"h", Key::H},
|
|
{"i", Key::I},
|
|
{"j", Key::J},
|
|
{"k", Key::K},
|
|
{"l", Key::L},
|
|
{"m", Key::M},
|
|
{"n", Key::N},
|
|
{"o", Key::O},
|
|
{"p", Key::P},
|
|
{"q", Key::Q},
|
|
{"r", Key::R},
|
|
{"s", Key::S},
|
|
{"t", Key::T},
|
|
{"u", Key::U},
|
|
{"v", Key::V},
|
|
{"w", Key::W},
|
|
{"x", Key::X},
|
|
{"y", Key::Y},
|
|
{"z", Key::Z},
|
|
|
|
{"num0", Key::Num0},
|
|
{"num1", Key::Num1},
|
|
{"num2", Key::Num2},
|
|
{"num3", Key::Num3},
|
|
{"num4", Key::Num4},
|
|
{"num5", Key::Num5},
|
|
{"num6", Key::Num6},
|
|
{"num7", Key::Num7},
|
|
{"num8", Key::Num8},
|
|
{"num9", Key::Num9},
|
|
|
|
{"space", Key::Space},
|
|
{"enter", Key::Enter},
|
|
{"escape", Key::Escape},
|
|
{"tab", Key::Tab},
|
|
{"backspace", Key::Backspace},
|
|
|
|
{"left_shift", Key::LeftShift},
|
|
{"right_shift", Key::RightShift},
|
|
{"left_ctrl", Key::LeftCtrl},
|
|
{"right_ctrl", Key::RightCtrl},
|
|
{"left_alt", Key::LeftAlt},
|
|
{"right_alt", Key::RightAlt},
|
|
{"capslock", Key::CapsLock},
|
|
|
|
{"up", Key::Up},
|
|
{"down", Key::Down},
|
|
{"left", Key::Left},
|
|
{"right", Key::Right},
|
|
{"home", Key::Home},
|
|
{"end", Key::End},
|
|
{"page_up", Key::PageUp},
|
|
{"page_down", Key::PageDown},
|
|
|
|
{"delete", Key::Delete},
|
|
{"insert", Key::Insert},
|
|
|
|
{"minus", Key::Minus},
|
|
{"equals", Key::Equals},
|
|
{"left_bracket", Key::LeftBracket},
|
|
{"right_bracket", Key::RightBracket},
|
|
{"semicolon", Key::Semicolon},
|
|
{"apostrophe", Key::Apostrophe},
|
|
{"grave", Key::Grave},
|
|
{"comma", Key::Comma},
|
|
{"period", Key::Period},
|
|
{"slash", Key::Slash},
|
|
{"backslash", Key::Backslash},
|
|
|
|
{"f1", Key::F1},
|
|
{"f2", Key::F2},
|
|
{"f3", Key::F3},
|
|
{"f4", Key::F4},
|
|
{"f5", Key::F5},
|
|
{"f6", Key::F6},
|
|
{"f7", Key::F7},
|
|
{"f8", Key::F8},
|
|
{"f9", Key::F9},
|
|
{"f10", Key::F10},
|
|
{"f11", Key::F11},
|
|
{"f12", Key::F12},
|
|
|
|
{"mouse_left", Key::MouseLeft},
|
|
{"mouse_middle", Key::MouseMiddle},
|
|
{"mouse_right", Key::MouseRight}
|
|
};
|
|
|
|
inline Key get_key_from_name(std::string_view name) {
|
|
for (const auto &[key_name, key] : KEY_NAMES)
|
|
if (key_name == name)
|
|
return key;
|
|
return Key::Unknown;
|
|
}
|
|
|
|
inline std::unordered_map<std::string, Key> action_key_map;
|
|
|
|
inline void set_action_mapping(const std::string &action_name, const std::string &key_name) {
|
|
Key key = get_key_from_name(key_name);
|
|
if (key != Key::Unknown)
|
|
action_key_map[action_name] = key;
|
|
}
|
|
|
|
inline Key get_key(std::string &name) {
|
|
auto it = action_key_map.find(name);
|
|
if (it != action_key_map.end())
|
|
return it->second;
|
|
return get_key_from_name(name);
|
|
}
|
|
|
|
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<float> scroll;
|
|
|
|
struct {
|
|
Key button;
|
|
Vec2<float> position;
|
|
} mouse_button;
|
|
|
|
struct {
|
|
Vec2<float> position;
|
|
Vec2<float> delta;
|
|
} mouse_move;
|
|
};
|
|
};
|
|
|
|
struct Animation {
|
|
std::vector<uint64_t> frames;
|
|
float frame_rate;
|
|
|
|
~Animation() {
|
|
for (uint64_t frame_id : frames)
|
|
image_pool.release(frame_id);
|
|
}
|
|
};
|
|
|
|
inline Pool<Animation> 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<float> size, const char *title);
|
|
|
|
void update(Vec2<float> new_size, const char *new_title);
|
|
|
|
~Window();
|
|
|
|
// Rendering functions
|
|
uint64_t load_image(const char *path, bool pixel_art);
|
|
Vec2<float> get_image_size(uint64_t image_id);
|
|
|
|
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<float> get_text_size(uint64_t text_id);
|
|
|
|
bool write(uint64_t text_id, Vec2<float> position, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha);
|
|
|
|
bool draw(uint64_t image_id, Vec2<float> position, float z, float angle, Vec2<float> pivot, Vec2<float> scale, float alpha);
|
|
|
|
bool draw_rect(Rect rect, Color color, float z, float angle, Vec2<float> pivot, Vec2<float> 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
|
|
uint64_t delta_time(); // returns the time in nanoseconds since the last render call
|
|
|
|
private:
|
|
// internal data and functions
|
|
SDL_Window *window;
|
|
SDL_Renderer *renderer;
|
|
|
|
Vec2<float> real_size;
|
|
Vec2<float> virtual_size;
|
|
Vec2<float> 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<float> pivot;
|
|
Vec2<float> scale;
|
|
float alpha;
|
|
|
|
union {
|
|
struct {
|
|
uint64_t image_id;
|
|
Vec2<float> position;
|
|
} draw_image;
|
|
|
|
struct {
|
|
uint64_t text_id;
|
|
Vec2<float> position;
|
|
} draw_text;
|
|
|
|
struct {
|
|
Rect rect;
|
|
Color color;
|
|
} draw_rect;
|
|
};
|
|
};
|
|
|
|
std::vector<struct RenderInstruction> render_instructions;
|
|
|
|
void compute_transform();
|
|
|
|
bool mouse_in_window(const Vec2<float> real_position, Vec2<float> &virtual_position);
|
|
|
|
void draw_letterbox();
|
|
};
|
|
|
|
inline Window window({720, 480}, "Mysth Engine");
|
|
|
|
#endif
|