diff --git a/CMakeLists.txt b/CMakeLists.txt index 06e68e2..3ec08e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(engine LANGUAGES CXX VERSION "0.1.0" ) -add_library(${PROJECT_NAME} SHARED +add_library(${PROJECT_NAME} STATIC "src/engine.cpp" "src/window.cpp" @@ -74,6 +74,8 @@ add_library(${PROJECT_NAME} SHARED target_compile_definitions(${PROJECT_NAME} PRIVATE DEFINITIONS "ENGINE_EXPORTS") +set_property(TARGET ${PROJECT_NAME} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON) + set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) @@ -143,8 +145,8 @@ add_subdirectory(dependencies/glm) target_include_directories(${PROJECT_NAME} PUBLIC dependencies/glm) # spdlog -set(SPDLOG_BUILD_SHARED ON CACHE INTERNAL "" FORCE) -set(BUILD_SHARED_LIBS ON) +set(SPDLOG_BUILD_SHARED OFF CACHE INTERNAL "" FORCE) +set(BUILD_SHARED_LIBS OFF) add_subdirectory(dependencies/spdlog) target_link_libraries(${PROJECT_NAME} PUBLIC spdlog) target_include_directories(${PROJECT_NAME} PUBLIC dependencies/spdlog/include) diff --git a/include/components/component.hpp b/include/components/component.hpp index 5d3f950..3c0af10 100644 --- a/include/components/component.hpp +++ b/include/components/component.hpp @@ -2,9 +2,12 @@ #include "engine_api.h" +namespace engine { + class Window; + class Input; +} + class Object; -class Window; -class Input; class ResourceManager; class ENGINE_API Component { @@ -30,8 +33,8 @@ public: Object& parent; protected: - Window& win; - Input& inp; + engine::Window& win; + engine::Input& inp; ResourceManager& res; private: diff --git a/include/engine_api.h b/include/engine_api.h index 366c7c1..1e2719d 100644 --- a/include/engine_api.h +++ b/include/engine_api.h @@ -11,3 +11,5 @@ # define ENGINE_API # endif #endif + +#define ENGINE_API \ No newline at end of file diff --git a/include/gfx_device.hpp b/include/gfx_device.hpp index 14a4bd8..a4d896f 100644 --- a/include/gfx_device.hpp +++ b/include/gfx_device.hpp @@ -8,7 +8,7 @@ struct SDL_Window; -namespace engine::gfx { +namespace engine { class ENGINE_API GFXDevice { diff --git a/include/input.hpp b/include/input.hpp index bc4cb08..86ca3d2 100644 --- a/include/input.hpp +++ b/include/input.hpp @@ -9,81 +9,85 @@ #include #include -class Window; +namespace engine { -enum class InputDevice : int { - MOUSE, - KEYBOARD, - CONTROLLER, - SIZE -}; + class Window; -// This class should be used to get platform/input-device independent input -class ENGINE_API Input { - -public: - - // requires a window reference to get input from - Input(const Window& win); - Input(const Input&) = delete; - Input& operator=(const Input&) = delete; - ~Input(); - - // Add a mouse input - void addInputButton(const std::string& name, inputs::MouseButton button); - void addInputAxis(const std::string& name, inputs::MouseAxis axis); - void addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low); - // Add a keyboard input - void addInputButton(const std::string& name, inputs::Key button); - void addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low); - - void delInputButton(int index); - void delInputAxis(int index); - - void setDeviceActive(enum InputDevice device, bool active); - bool getDeviceActive(enum InputDevice device) const; - - float getAxis(const std::string& axisName) const; - bool getButton(const std::string& buttonName) const; - bool getButtonPress(const std::string& buttonName) const; - bool getButtonRelease(const std::string& buttonName) const; - - -private: - - struct ButtonEntry { - std::string name; - enum InputDevice device; - int button; // enumeration of device buttons or axes + enum class InputDevice : int { + MOUSE, + KEYBOARD, + CONTROLLER, + SIZE }; - struct AxisEntry { - std::string name; - enum InputDevice device; - int axis; - bool isButtonAxis; - int high; - int low; + // This class should be used to get platform/input-device independent input + class ENGINE_API Input { + + public: + + // requires a window reference to get input from + Input(const Window& win); + Input(const Input&) = delete; + Input& operator=(const Input&) = delete; + ~Input(); + + // Add a mouse input + void addInputButton(const std::string& name, inputs::MouseButton button); + void addInputAxis(const std::string& name, inputs::MouseAxis axis); + void addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low); + // Add a keyboard input + void addInputButton(const std::string& name, inputs::Key button); + void addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low); + + void delInputButton(int index); + void delInputAxis(int index); + + void setDeviceActive(enum InputDevice device, bool active); + bool getDeviceActive(enum InputDevice device) const; + + float getAxis(const std::string& axisName) const; + bool getButton(const std::string& buttonName) const; + bool getButtonPress(const std::string& buttonName) const; + bool getButtonRelease(const std::string& buttonName) const; + + + private: + + struct ButtonEntry { + std::string name; + enum InputDevice device; + int button; // enumeration of device buttons or axes + }; + + struct AxisEntry { + std::string name; + enum InputDevice device; + int axis; + bool isButtonAxis; + int high; + int low; + }; + + const Window& m_win; + + std::vector m_buttonEntries; + std::vector m_axisEntries; + + std::array(InputDevice::SIZE)> m_enabledDevices; + + // private methods + + float getDeviceAxis(enum InputDevice device, int axis) const; + bool getDeviceButton(enum InputDevice device, int button) const; + bool getDeviceButtonDown(enum InputDevice device, int button) const; + bool getDeviceButtonUp(enum InputDevice device, int button) const; + + float getButtonAxis(enum InputDevice device, int high, int low) const; + + void addInputButton(const std::string& name, InputDevice device, int button); + void addInputAxis(const std::string& name, InputDevice device, int axis); + void addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low); + }; - const Window& m_win; - - std::vector m_buttonEntries; - std::vector m_axisEntries; - - std::array(InputDevice::SIZE)> m_enabledDevices; - - // private methods - - float getDeviceAxis(enum InputDevice device, int axis) const; - bool getDeviceButton(enum InputDevice device, int button) const; - bool getDeviceButtonDown(enum InputDevice device, int button) const; - bool getDeviceButtonUp(enum InputDevice device, int button) const; - - float getButtonAxis(enum InputDevice device, int high, int low) const; - - void addInputButton(const std::string& name, InputDevice device, int button); - void addInputAxis(const std::string& name, InputDevice device, int axis); - void addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low); - -}; +} \ No newline at end of file diff --git a/include/object.hpp b/include/object.hpp index cfc28f4..e835738 100644 --- a/include/object.hpp +++ b/include/object.hpp @@ -12,8 +12,10 @@ #include #include -class Window; -class Input; +namespace engine { + class Window; + class Input; +} class ResourceManager; class SceneRoot; @@ -28,8 +30,8 @@ namespace components { } struct GameIO { - Window * const win; - Input * const input; + engine::Window * const win; + engine::Input * const input; ResourceManager * const resMan; }; @@ -43,8 +45,8 @@ public: Object& operator=(const Object&) = delete; ~Object(); - Window& win; - Input& inp; + engine::Window& win; + engine::Input& inp; ResourceManager& res; SceneRoot& root; diff --git a/include/window.hpp b/include/window.hpp index a7190a6..39640c9 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -17,183 +17,187 @@ ENGINE_API extern const uint64_t BILLION; -class ENGINE_API Window { +namespace engine { -public: - Window(const std::string& title); - Window(const Window&) = delete; - Window& operator=(const Window&) = delete; - ~Window(); + class ENGINE_API Window { - // Return the title name - std::string getTitle() const; + public: + Window(const std::string& title); + Window(const Window&) = delete; + Window& operator=(const Window&) = delete; + ~Window(); - // Update the window state to capture any events that have occurred. - // Run this on every frame. - void getInputAndEvents(); + // Return the title name + std::string getTitle() const; - void setTitle(std::string title); + // Update the window state to capture any events that have occurred. + // Run this on every frame. + void getInputAndEvents(); - // Hides the window (it will appear closed to the user). - void hide(); - // Shows the window again. - void show(); - // Raises the window above other windows and sets the input focus - void focus(); - // Returns true if the window has focus - bool hasFocus() const; + void setTitle(std::string title); - // Sets the close flag, check this with shouldClose() - void setCloseFlag(); - // Returns true if the window should remain open - bool isRunning() const; + // Hides the window (it will appear closed to the user). + void hide(); + // Shows the window again. + void show(); + // Raises the window above other windows and sets the input focus + void focus(); + // Returns true if the window has focus + bool hasFocus() const; - void setFullscreen(bool fullscreen, bool exclusive=true); - void toggleFullscreen(); + // Sets the close flag, check this with shouldClose() + void setCloseFlag(); + // Returns true if the window should remain open + bool isRunning() const; - bool isFullscreen() const; + void setFullscreen(bool fullscreen, bool exclusive = true); + void toggleFullscreen(); - // Relative mouse mode captures the cursor for FPS style use. Returns false if unsupported. - bool setRelativeMouseMode(bool enabled); + bool isFullscreen() const; - // returns true if relative mouse mode is enabled - bool mouseCaptured(); + // Relative mouse mode captures the cursor for FPS style use. Returns false if unsupported. + bool setRelativeMouseMode(bool enabled); - // window events + // returns true if relative mouse mode is enabled + bool mouseCaptured(); - // Returns true if the window was just resized during the previous frame - bool getWindowResized() const; - // Set the window resized flag (to recalculate aspect ratios and such) - inline void setResizedFlag() - { - m_justResized = true; - } + // window events - // keyboard events + // Returns true if the window was just resized during the previous frame + bool getWindowResized() const; + // Set the window resized flag (to recalculate aspect ratios and such) + inline void setResizedFlag() + { + m_justResized = true; + } - // returns true if key is down - bool getKey(inputs::Key key) const; - // returns true if key was just pressed - bool getKeyPress(inputs::Key key) const; - // returns true if key was just released - bool getKeyRelease(inputs::Key key) const; + // keyboard events - // mouse events + // returns true if key is down + bool getKey(inputs::Key key) const; + // returns true if key was just pressed + bool getKeyPress(inputs::Key key) const; + // returns true if key was just released + bool getKeyRelease(inputs::Key key) const; - // returns true if button is down - bool getButton(inputs::MouseButton button) const; - // returns true if button was just pressed - bool getButtonPress(inputs::MouseButton button) const; - // returns true if button was just released - bool getButtonRelease(inputs::MouseButton button) const; + // mouse events - // retrieves x coordinate of the mouse - int getMouseX() const; - // retrieves y coordinate of the mouse - int getMouseY() const; - // retrieves mouse x coordinate normalised for OpenGL - float getMouseNormX() const; - // retrieves mouse y coordinate normalised for OpenGL - float getMouseNormY() const; - // retrieves dx of the mouse since the last frame - int getMouseDX() const; - // retrieves dy of the mouse since the last frame - int getMouseDY() const; - // retrieves amount scrolled vertically - float getMouseScrollX() const; - // retrieves amount scrolled horizontally - float getMouseScrollY() const; + // returns true if button is down + bool getButton(inputs::MouseButton button) const; + // returns true if button was just pressed + bool getButtonPress(inputs::MouseButton button) const; + // returns true if button was just released + bool getButtonRelease(inputs::MouseButton button) const; - // joystick/gamepad events (maybe), other misc events + // retrieves x coordinate of the mouse + int getMouseX() const; + // retrieves y coordinate of the mouse + int getMouseY() const; + // retrieves mouse x coordinate normalised for OpenGL + float getMouseNormX() const; + // retrieves mouse y coordinate normalised for OpenGL + float getMouseNormY() const; + // retrieves dx of the mouse since the last frame + int getMouseDX() const; + // retrieves dy of the mouse since the last frame + int getMouseDY() const; + // retrieves amount scrolled vertically + float getMouseScrollX() const; + // retrieves amount scrolled horizontally + float getMouseScrollY() const; + + // joystick/gamepad events (maybe), other misc events - // returns the performance counter value in nanoseconds; - uint64_t getNanos() const; - // get the time recorded at the end of the last frame - uint64_t getLastFrameStamp() const; + // returns the performance counter value in nanoseconds; + uint64_t getNanos() const; + // get the time recorded at the end of the last frame + uint64_t getLastFrameStamp() const; - // returns the number of frames elapsed since window creation - uint64_t getFrameCount() const; - uint64_t getStartTime() const;; - float dt() const; // returns delta time in seconds - uint64_t getFPS() const; - uint64_t getAvgFPS() const; + // returns the number of frames elapsed since window creation + uint64_t getFrameCount() const; + uint64_t getStartTime() const;; + float dt() const; // returns delta time in seconds + uint64_t getFPS() const; + uint64_t getAvgFPS() const; - void resetAvgFPS(); + void resetAvgFPS(); - bool infoBox(const std::string& title, const std::string& msg); + bool infoBox(const std::string& title, const std::string& msg); - /* STATIC METHODS */ - static void errorBox(const std::string& message); + /* STATIC METHODS */ + static void errorBox(const std::string& message); -public: - SDL_Window* m_handle; + public: + SDL_Window* m_handle; -private: + private: - bool m_shouldClose = false; + bool m_shouldClose = false; - std::string m_title; + std::string m_title; - bool m_fullscreen = false; - bool m_justResized = false; - bool m_keyboardFocus = true; + bool m_fullscreen = false; + bool m_justResized = false; + bool m_keyboardFocus = true; - // size in screen coordinates - glm::ivec2 m_winSize = glm::vec2(640, 480); + // size in screen coordinates + glm::ivec2 m_winSize = glm::vec2(640, 480); - // performance counter frequency - uint64_t m_counterFreq; + // performance counter frequency + uint64_t m_counterFreq; - // number of frames swapped - uint64_t m_frames = 0; - // frame count offset for fpsAvg - uint64_t m_avgFpsStartCount = 0; - // in nanoseconds - uint64_t m_startTime; - // in nanoseconds - uint64_t m_lastFrameStamp; - // in nanoseconds; elapsed time between frames - uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero - // in nanoseconds - uint64_t m_avgFpsStart; + // number of frames swapped + uint64_t m_frames = 0; + // frame count offset for fpsAvg + uint64_t m_avgFpsStartCount = 0; + // in nanoseconds + uint64_t m_startTime; + // in nanoseconds + uint64_t m_lastFrameStamp; + // in nanoseconds; elapsed time between frames + uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero + // in nanoseconds + uint64_t m_avgFpsStart; - // input stuff + // input stuff - enum class ButtonDelta { - SAME = 0, - PRESSED, - RELEASED + enum class ButtonDelta { + SAME = 0, + PRESSED, + RELEASED + }; + + struct { + std::array keys; + std::array deltas; + } m_keyboard{ }; + + struct { + std::array(inputs::MouseButton::M_SIZE)> buttons; + std::array deltas; + Sint32 x; + Sint32 y; + Sint32 dx; + Sint32 dy; + float xscroll; + float yscroll; + bool captured = false; + } m_mouse{ }; + + // private methods + + void onResize(Sint32 width, Sint32 height); + void resetInputDeltas(); + + // event methods (like callbacks) + + void onWindowEvent(SDL_WindowEvent& e); + void onKeyEvent(SDL_KeyboardEvent& e); + void onMouseButtonEvent(SDL_MouseButtonEvent& e); + void onMouseMotionEvent(SDL_MouseMotionEvent& e); + void onMouseWheelEvent(SDL_MouseWheelEvent& e); }; - struct { - std::array keys; - std::array deltas; - } m_keyboard{ }; - - struct { - std::array(inputs::MouseButton::M_SIZE)> buttons; - std::array deltas; - Sint32 x; - Sint32 y; - Sint32 dx; - Sint32 dy; - float xscroll; - float yscroll; - bool captured = false; - } m_mouse{ }; - - // private methods - - void onResize(Sint32 width, Sint32 height); - void resetInputDeltas(); - - // event methods (like callbacks) - - void onWindowEvent(SDL_WindowEvent& e); - void onKeyEvent(SDL_KeyboardEvent& e); - void onMouseButtonEvent(SDL_MouseButtonEvent& e); - void onMouseMotionEvent(SDL_MouseMotionEvent& e); - void onMouseWheelEvent(SDL_MouseWheelEvent& e); -}; +} \ No newline at end of file diff --git a/src/gfx_device_vulkan.cpp b/src/gfx_device_vulkan.cpp index a45a7bb..5f5330a 100644 --- a/src/gfx_device_vulkan.cpp +++ b/src/gfx_device_vulkan.cpp @@ -14,11 +14,12 @@ #include +#include #include #include #include -namespace engine::gfx { +namespace engine { static std::vector getRequiredVulkanExtensions(SDL_Window* window) { diff --git a/src/input.cpp b/src/input.cpp index ace2186..c65598e 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -5,31 +5,33 @@ #include #include -Input::Input(const Window &win) : m_win(win) -{ - m_enabledDevices.fill(true); -} +namespace engine { -Input::~Input() -{ -} + Input::Input(const Window& win) : m_win(win) + { + m_enabledDevices.fill(true); + } -// private methods + Input::~Input() + { + } -float Input::getDeviceAxis(enum InputDevice device, int axis) const -{ - switch (device) { + // private methods + + float Input::getDeviceAxis(enum InputDevice device, int axis) const + { + switch (device) { case InputDevice::MOUSE: switch (static_cast(axis)) { - case inputs::MouseAxis::X: - return static_cast(m_win.getMouseDX()); - case inputs::MouseAxis::Y: - return static_cast(m_win.getMouseDY()); - case inputs::MouseAxis::X_SCR: - return m_win.getMouseScrollX(); - case inputs::MouseAxis::Y_SCR: - return m_win.getMouseScrollY(); - default: break; + case inputs::MouseAxis::X: + return static_cast(m_win.getMouseDX()); + case inputs::MouseAxis::Y: + return static_cast(m_win.getMouseDY()); + case inputs::MouseAxis::X_SCR: + return m_win.getMouseScrollX(); + case inputs::MouseAxis::Y_SCR: + return m_win.getMouseScrollY(); + default: break; } break; case InputDevice::KEYBOARD: @@ -37,13 +39,13 @@ float Input::getDeviceAxis(enum InputDevice device, int axis) const case InputDevice::CONTROLLER: break; default: break; + } + throw std::runtime_error("Error getting device axis"); } - throw std::runtime_error("Error getting device axis"); -} -bool Input::getDeviceButton(enum InputDevice device, int button) const -{ - switch (device) { + bool Input::getDeviceButton(enum InputDevice device, int button) const + { + switch (device) { case InputDevice::MOUSE: return m_win.getButton(static_cast(button)); case InputDevice::KEYBOARD: @@ -51,13 +53,13 @@ bool Input::getDeviceButton(enum InputDevice device, int button) const case InputDevice::CONTROLLER: break; default: break; + } + throw std::runtime_error("Error getting device button"); } - throw std::runtime_error("Error getting device button"); -} -bool Input::getDeviceButtonDown(enum InputDevice device, int button) const -{ - switch (device) { + bool Input::getDeviceButtonDown(enum InputDevice device, int button) const + { + switch (device) { case InputDevice::MOUSE: return m_win.getButtonPress(static_cast(button)); case InputDevice::KEYBOARD: @@ -65,13 +67,13 @@ bool Input::getDeviceButtonDown(enum InputDevice device, int button) const case InputDevice::CONTROLLER: break; default: break; + } + throw std::runtime_error("Error getting device button"); } - throw std::runtime_error("Error getting device button"); -} -bool Input::getDeviceButtonUp(enum InputDevice device, int button) const -{ - switch (device) { + bool Input::getDeviceButtonUp(enum InputDevice device, int button) const + { + switch (device) { case InputDevice::MOUSE: return m_win.getButtonRelease(static_cast(button)); case InputDevice::KEYBOARD: @@ -79,154 +81,157 @@ bool Input::getDeviceButtonUp(enum InputDevice device, int button) const case InputDevice::CONTROLLER: break; default: break; + } + throw std::runtime_error("Error getting device button"); } - throw std::runtime_error("Error getting device button"); -} -float Input::getButtonAxis(enum InputDevice device, int high, int low) const -{ - float value = 0.0f; - if (getDeviceButton(device, high)) value += 1.0f; - if (low != 0) { - if (getDeviceButton(device, low)) value += -1.0f; + float Input::getButtonAxis(enum InputDevice device, int high, int low) const + { + float value = 0.0f; + if (getDeviceButton(device, high)) value += 1.0f; + if (low != 0) { + if (getDeviceButton(device, low)) value += -1.0f; + } + return value; } - return value; -} -// public methods + // public methods -void Input::addInputButton(const std::string& name, InputDevice device, int button) -{ - m_buttonEntries.push_back( { name, device, button } ); -} + void Input::addInputButton(const std::string& name, InputDevice device, int button) + { + m_buttonEntries.push_back({ name, device, button }); + } -void Input::addInputAxis(const std::string& name, InputDevice device, int axis) -{ - m_axisEntries.push_back( { name, device, axis, false, 0, 0 } ); -} + void Input::addInputAxis(const std::string& name, InputDevice device, int axis) + { + m_axisEntries.push_back({ name, device, axis, false, 0, 0 }); + } -void Input::addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low) -{ - m_axisEntries.push_back( { name, device, 0, true, high, low } ); -} + void Input::addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low) + { + m_axisEntries.push_back({ name, device, 0, true, high, low }); + } -// OVERLOADS: + // OVERLOADS: -// Add a mouse input -void Input::addInputButton(const std::string& name, inputs::MouseButton button) -{ - addInputButton(name, InputDevice::MOUSE, static_cast(button)); -} + // Add a mouse input + void Input::addInputButton(const std::string& name, inputs::MouseButton button) + { + addInputButton(name, InputDevice::MOUSE, static_cast(button)); + } -void Input::addInputAxis(const std::string& name, inputs::MouseAxis axis) -{ - addInputAxis(name, InputDevice::MOUSE, static_cast(axis)); -} + void Input::addInputAxis(const std::string& name, inputs::MouseAxis axis) + { + addInputAxis(name, InputDevice::MOUSE, static_cast(axis)); + } -void Input::addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low) -{ - addInputButtonAsAxis(name, InputDevice::MOUSE, static_cast(high), static_cast(low)); -} + void Input::addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low) + { + addInputButtonAsAxis(name, InputDevice::MOUSE, static_cast(high), static_cast(low)); + } -// Add a keyboard input (TODO: add KeyboardButton enum class) -void Input::addInputButton(const std::string& name, inputs::Key button) -{ - addInputButton(name, InputDevice::KEYBOARD, static_cast(button)); -} + // Add a keyboard input (TODO: add KeyboardButton enum class) + void Input::addInputButton(const std::string& name, inputs::Key button) + { + addInputButton(name, InputDevice::KEYBOARD, static_cast(button)); + } -void Input::addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low) -{ - addInputButtonAsAxis(name, InputDevice::KEYBOARD, static_cast(high), static_cast(low)); -} + void Input::addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low) + { + addInputButtonAsAxis(name, InputDevice::KEYBOARD, static_cast(high), static_cast(low)); + } -void Input::delInputButton(int index) -{ - std::vector::iterator it = m_buttonEntries.begin(); - std::advance(it, index); - m_buttonEntries.erase(it); -} + void Input::delInputButton(int index) + { + std::vector::iterator it = m_buttonEntries.begin(); + std::advance(it, index); + m_buttonEntries.erase(it); + } -void Input::delInputAxis(int index) -{ - std::vector::iterator it = m_axisEntries.begin(); - std::advance(it, index); - m_axisEntries.erase(it); -} + void Input::delInputAxis(int index) + { + std::vector::iterator it = m_axisEntries.begin(); + std::advance(it, index); + m_axisEntries.erase(it); + } -void Input::setDeviceActive(enum InputDevice device, bool active) -{ - m_enabledDevices[static_cast(device)] = active; -} + void Input::setDeviceActive(enum InputDevice device, bool active) + { + m_enabledDevices[static_cast(device)] = active; + } -bool Input::getDeviceActive(enum InputDevice device) const -{ - return m_enabledDevices[static_cast(device)]; -} + bool Input::getDeviceActive(enum InputDevice device) const + { + return m_enabledDevices[static_cast(device)]; + } -float Input::getAxis(const std::string& axisName) const -{ - for (const AxisEntry& e : m_axisEntries) { - if (e.name == axisName) { - if (m_enabledDevices[static_cast(e.device)]) { - if (e.isButtonAxis) { - return getButtonAxis(e.device, e.high, e.low); - } else { - return getDeviceAxis(e.device, e.axis); + float Input::getAxis(const std::string& axisName) const + { + for (const AxisEntry& e : m_axisEntries) { + if (e.name == axisName) { + if (m_enabledDevices[static_cast(e.device)]) { + if (e.isButtonAxis) { + return getButtonAxis(e.device, e.high, e.low); + } + else { + return getDeviceAxis(e.device, e.axis); + } } } } + return 0.0f; // instead of throwing an exception, just return nothing + // throw std::runtime_error("Unable to find mapping in input table"); } - return 0.0f; // instead of throwing an exception, just return nothing -// throw std::runtime_error("Unable to find mapping in input table"); -} -bool Input::getButton(const std::string& buttonName) const -{ - bool isDown = false; + bool Input::getButton(const std::string& buttonName) const + { + bool isDown = false; - for (const ButtonEntry& e : m_buttonEntries) { - if (e.name == buttonName) { - if (m_enabledDevices[static_cast(e.device)]) { - if (getDeviceButton(e.device, e.button) == true) { - isDown = true; - break; + for (const ButtonEntry& e : m_buttonEntries) { + if (e.name == buttonName) { + if (m_enabledDevices[static_cast(e.device)]) { + if (getDeviceButton(e.device, e.button) == true) { + isDown = true; + break; + } } } } + return isDown; } - return isDown; -} -bool Input::getButtonPress(const std::string& buttonName) const -{ - bool isPressed = false; + bool Input::getButtonPress(const std::string& buttonName) const + { + bool isPressed = false; - for (const ButtonEntry& e : m_buttonEntries) { - if (e.name == buttonName) { - if (m_enabledDevices[static_cast(e.device)]) { - if (getDeviceButtonDown(e.device, e.button) == true) { - isPressed = true; - break; + for (const ButtonEntry& e : m_buttonEntries) { + if (e.name == buttonName) { + if (m_enabledDevices[static_cast(e.device)]) { + if (getDeviceButtonDown(e.device, e.button) == true) { + isPressed = true; + break; + } } } } + return isPressed; } - return isPressed; -} -bool Input::getButtonRelease(const std::string& buttonName) const -{ - bool isReleased = false; + bool Input::getButtonRelease(const std::string& buttonName) const + { + bool isReleased = false; - for (const ButtonEntry& e : m_buttonEntries) { - if (e.name == buttonName) { - if (m_enabledDevices[static_cast(e.device)]) { - if (getDeviceButtonUp(e.device, e.button) == true) { - isReleased = true; - break; + for (const ButtonEntry& e : m_buttonEntries) { + if (e.name == buttonName) { + if (m_enabledDevices[static_cast(e.device)]) { + if (getDeviceButtonUp(e.device, e.button) == true) { + isReleased = true; + break; + } } } } + return isReleased; } - return isReleased; -} + +} \ No newline at end of file diff --git a/src/window.cpp b/src/window.cpp index cbf92b1..c16d73c 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -7,100 +7,102 @@ const uint64_t BILLION = 1000000000; -Window::Window(const std::string& title) : m_title(title) -{ +namespace engine { - // init SDL - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - const std::string errMsg("Unable to initialise SDL: " + std::string(SDL_GetError())); - if (SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL error", errMsg.c_str(), NULL) != 0) { - std::cerr << errMsg << "\nAre you in a graphical environment?\n"; + Window::Window(const std::string& title) : m_title(title) + { + + // init SDL + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + const std::string errMsg("Unable to initialise SDL: " + std::string(SDL_GetError())); + if (SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL error", errMsg.c_str(), NULL) != 0) { + std::cerr << errMsg << "\nAre you in a graphical environment?\n"; + } + throw std::runtime_error(errMsg); } - throw std::runtime_error(errMsg); - } - m_counterFreq = SDL_GetPerformanceFrequency(); - m_startTime = getNanos(); - m_lastFrameStamp = m_startTime - 1; - m_avgFpsStart = m_startTime; + m_counterFreq = SDL_GetPerformanceFrequency(); + m_startTime = getNanos(); + m_lastFrameStamp = m_startTime - 1; + m_avgFpsStart = m_startTime; - // create the window - m_handle = SDL_CreateWindow( + // create the window + m_handle = SDL_CreateWindow( m_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, static_cast(m_winSize.x), static_cast(m_winSize.y), SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN); - if (m_handle == NULL) { - SDL_Quit(); - throw std::runtime_error("Unable to create window: " + std::string(SDL_GetError())); + if (m_handle == NULL) { + SDL_Quit(); + throw std::runtime_error("Unable to create window: " + std::string(SDL_GetError())); + } + + // get window size + int winWidth, winHeight; + SDL_GetWindowSize(m_handle, &winWidth, &winHeight); + m_winSize.x = winWidth; + m_winSize.y = winHeight; + + const int WINDOWED_MIN_WIDTH = 640; + const int WINDOWED_MIN_HEIGHT = 480; + SDL_SetWindowMinimumSize(m_handle, WINDOWED_MIN_WIDTH, WINDOWED_MIN_HEIGHT); + + /* + m_glContext = SDL_GL_CreateContext(m_handle); + if (m_glContext == NULL) { + SDL_DestroyWindow(m_handle); + SDL_Quit(); + throw std::runtime_error("Unable to create OpenGL context: " + std::string(SDL_GetError())); + } + + if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { + SDL_DestroyWindow(m_handle); + SDL_Quit(); + throw std::runtime_error("Unable to initialise GLAD"); + } + */ + + // onResize(m_winSize.x, m_winSize.y); + } - // get window size - int winWidth, winHeight; - SDL_GetWindowSize(m_handle, &winWidth, &winHeight); - m_winSize.x = winWidth; - m_winSize.y = winHeight; - - const int WINDOWED_MIN_WIDTH = 640; - const int WINDOWED_MIN_HEIGHT = 480; - SDL_SetWindowMinimumSize(m_handle, WINDOWED_MIN_WIDTH, WINDOWED_MIN_HEIGHT); - - /* - m_glContext = SDL_GL_CreateContext(m_handle); - if (m_glContext == NULL) { + Window::~Window() + { SDL_DestroyWindow(m_handle); SDL_Quit(); - throw std::runtime_error("Unable to create OpenGL context: " + std::string(SDL_GetError())); } - if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { - SDL_DestroyWindow(m_handle); - SDL_Quit(); - throw std::runtime_error("Unable to initialise GLAD"); + // private methods + + void Window::onResize(Sint32 width, Sint32 height) + { + // get window size + m_winSize.x = static_cast(width); + m_winSize.y = static_cast(height); + + m_justResized = true; } - */ -// onResize(m_winSize.x, m_winSize.y); + void Window::resetInputDeltas() + { + m_justResized = false; -} + m_keyboard.deltas.fill(ButtonDelta::SAME); -Window::~Window() -{ - SDL_DestroyWindow(m_handle); - SDL_Quit(); -} + m_mouse.deltas.fill(ButtonDelta::SAME); + m_mouse.dx = 0; + m_mouse.dy = 0; + m_mouse.xscroll = 0.0f; + m_mouse.yscroll = 0.0f; + } -// private methods + // TODO event methods (like callbacks) -void Window::onResize(Sint32 width, Sint32 height) -{ - // get window size - m_winSize.x = static_cast(width); - m_winSize.y = static_cast(height); + void Window::onWindowEvent(SDL_WindowEvent& e) + { - m_justResized = true; -} - -void Window::resetInputDeltas() -{ - m_justResized = false; - - m_keyboard.deltas.fill(ButtonDelta::SAME); - - m_mouse.deltas.fill(ButtonDelta::SAME); - m_mouse.dx = 0; - m_mouse.dy = 0; - m_mouse.xscroll = 0.0f; - m_mouse.yscroll = 0.0f; -} - -// TODO event methods (like callbacks) - -void Window::onWindowEvent(SDL_WindowEvent &e) -{ - - switch (e.event) { + switch (e.event) { case SDL_WINDOWEVENT_SIZE_CHANGED: onResize(e.data1, e.data2); break; @@ -110,23 +112,23 @@ void Window::onWindowEvent(SDL_WindowEvent &e) case SDL_WINDOWEVENT_FOCUS_LOST: m_keyboardFocus = false; break; + } } -} -void Window::onKeyEvent(SDL_KeyboardEvent &e) -{ - bool keyWasDown = m_keyboard.keys[e.keysym.scancode]; - bool keyIsDown = (e.state == SDL_PRESSED); - m_keyboard.keys[e.keysym.scancode] = keyIsDown; - if (keyIsDown != keyWasDown) { // (if key was pressed or released) - m_keyboard.deltas[e.keysym.scancode] = keyIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED; + void Window::onKeyEvent(SDL_KeyboardEvent& e) + { + bool keyWasDown = m_keyboard.keys[e.keysym.scancode]; + bool keyIsDown = (e.state == SDL_PRESSED); + m_keyboard.keys[e.keysym.scancode] = keyIsDown; + if (keyIsDown != keyWasDown) { // (if key was pressed or released) + m_keyboard.deltas[e.keysym.scancode] = keyIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED; + } } -} -void Window::onMouseButtonEvent(SDL_MouseButtonEvent &e) -{ - enum inputs::MouseButton button = inputs::MouseButton::M_INVALID; - switch (e.button) { + void Window::onMouseButtonEvent(SDL_MouseButtonEvent& e) + { + enum inputs::MouseButton button = inputs::MouseButton::M_INVALID; + switch (e.button) { case SDL_BUTTON_LEFT: button = inputs::MouseButton::M_LEFT; break; @@ -142,59 +144,60 @@ void Window::onMouseButtonEvent(SDL_MouseButtonEvent &e) case SDL_BUTTON_X2: button = inputs::MouseButton::M_X2; break; - } - int buttonIndex = static_cast(button); - bool buttonWasDown = m_mouse.buttons.at(buttonIndex); - bool buttonIsDown = (e.state == SDL_PRESSED); - m_mouse.buttons.at(buttonIndex) = buttonIsDown; - if (buttonIsDown != buttonWasDown) { // (if button was pressed or released) - // only sets delta if it hasn't already been set this frame (to detect very fast presses) - if (m_mouse.deltas[buttonIndex] == ButtonDelta::SAME) { - m_mouse.deltas[buttonIndex] = buttonIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED; + } + int buttonIndex = static_cast(button); + bool buttonWasDown = m_mouse.buttons.at(buttonIndex); + bool buttonIsDown = (e.state == SDL_PRESSED); + m_mouse.buttons.at(buttonIndex) = buttonIsDown; + if (buttonIsDown != buttonWasDown) { // (if button was pressed or released) + // only sets delta if it hasn't already been set this frame (to detect very fast presses) + if (m_mouse.deltas[buttonIndex] == ButtonDelta::SAME) { + m_mouse.deltas[buttonIndex] = buttonIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED; + } } } -} -void Window::onMouseMotionEvent(SDL_MouseMotionEvent &e) -{ - m_mouse.x = e.x; - m_mouse.y = e.y; - m_mouse.dx = e.xrel; - m_mouse.dy = e.yrel; -} - -void Window::onMouseWheelEvent(SDL_MouseWheelEvent &e) -{ - if (e.direction == SDL_MOUSEWHEEL_NORMAL) { - m_mouse.xscroll = e.preciseX; - m_mouse.yscroll = e.preciseY; - } else { // flipped - m_mouse.xscroll = -e.preciseX; - m_mouse.yscroll = -e.preciseY; + void Window::onMouseMotionEvent(SDL_MouseMotionEvent& e) + { + m_mouse.x = e.x; + m_mouse.y = e.y; + m_mouse.dx = e.xrel; + m_mouse.dy = e.yrel; } -} -// public methods + void Window::onMouseWheelEvent(SDL_MouseWheelEvent& e) + { + if (e.direction == SDL_MOUSEWHEEL_NORMAL) { + m_mouse.xscroll = e.preciseX; + m_mouse.yscroll = e.preciseY; + } + else { // flipped + m_mouse.xscroll = -e.preciseX; + m_mouse.yscroll = -e.preciseY; + } + } -std::string Window::getTitle() const -{ - return m_title; -} + // public methods -void Window::getInputAndEvents() -{ + std::string Window::getTitle() const + { + return m_title; + } - m_frames++; - uint64_t currentFrameStamp = getNanos(); - m_lastFrameTime = currentFrameStamp - m_lastFrameStamp; - m_lastFrameStamp = currentFrameStamp; + void Window::getInputAndEvents() + { - resetInputDeltas(); + m_frames++; + uint64_t currentFrameStamp = getNanos(); + m_lastFrameTime = currentFrameStamp - m_lastFrameStamp; + m_lastFrameStamp = currentFrameStamp; - // loop through all available events - SDL_Event e; - while (SDL_PollEvent(&e)) { - switch (e.type) { + resetInputDeltas(); + + // loop through all available events + SDL_Event e; + while (SDL_PollEvent(&e)) { + switch (e.type) { case SDL_QUIT: setCloseFlag(); @@ -222,233 +225,238 @@ void Window::getInputAndEvents() onMouseWheelEvent(e.wheel); break; + } + } + + } + + void Window::setTitle(std::string title) + { + SDL_SetWindowTitle(m_handle, title.c_str()); + } + + bool Window::getWindowResized() const + { + return m_justResized; + } + + void Window::show() + { + SDL_ShowWindow(m_handle); + } + + void Window::hide() + { + SDL_HideWindow(m_handle); + } + + void Window::focus() + { + SDL_RaiseWindow(m_handle); + m_keyboardFocus = true; + } + + bool Window::hasFocus() const + { + return m_keyboardFocus; + } + + void Window::setCloseFlag() + { + m_shouldClose = true; + } + + bool Window::isRunning() const + { + return !m_shouldClose; + } + + void Window::setFullscreen(bool fullscreen, bool exclusive) + { + if (SDL_SetWindowFullscreen(m_handle, fullscreen ? (exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0) != 0) { + throw std::runtime_error("Unable to set window to fullscreen/windowed"); + } + m_fullscreen = fullscreen; + if (fullscreen) { + int width, height; + SDL_GetWindowSize(m_handle, &width, &height); + onResize(width, height); } } -} - -void Window::setTitle(std::string title) -{ - SDL_SetWindowTitle(m_handle, title.c_str()); -} - -bool Window::getWindowResized() const -{ - return m_justResized; -} - -void Window::show() -{ - SDL_ShowWindow(m_handle); -} - -void Window::hide() -{ - SDL_HideWindow(m_handle); -} - -void Window::focus() -{ - SDL_RaiseWindow(m_handle); - m_keyboardFocus = true; -} - -bool Window::hasFocus() const -{ - return m_keyboardFocus; -} - -void Window::setCloseFlag() -{ - m_shouldClose = true; -} - -bool Window::isRunning() const -{ - return !m_shouldClose; -} - -void Window::setFullscreen(bool fullscreen, bool exclusive) -{ - if (SDL_SetWindowFullscreen(m_handle, fullscreen ? (exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0) != 0) { - throw std::runtime_error("Unable to set window to fullscreen/windowed"); + void Window::toggleFullscreen() + { + setFullscreen(!m_fullscreen); } - m_fullscreen = fullscreen; - if (fullscreen) { - int width, height; - SDL_GetWindowSize(m_handle, &width, &height); - onResize(width, height); + + bool Window::isFullscreen() const + { + return m_fullscreen; } -} -void Window::toggleFullscreen() -{ - setFullscreen(!m_fullscreen); -} - -bool Window::isFullscreen() const -{ - return m_fullscreen; -} - -bool Window::setRelativeMouseMode(bool enabled) -{ - m_mouse.captured = enabled; - int code = SDL_SetRelativeMouseMode(static_cast(enabled)); - if (code != 0) { - throw std::runtime_error("Unable to set relative mouse mode"); - } else { - return true; + bool Window::setRelativeMouseMode(bool enabled) + { + m_mouse.captured = enabled; + int code = SDL_SetRelativeMouseMode(static_cast(enabled)); + if (code != 0) { + throw std::runtime_error("Unable to set relative mouse mode"); + } + else { + return true; + } } -} -bool Window::mouseCaptured() -{ - return m_mouse.captured; -} - -// getting input - -bool Window::getKey(inputs::Key key) const -{ - return m_keyboard.keys[static_cast(key)]; -} - -bool Window::getKeyPress(inputs::Key key) const -{ - return m_keyboard.deltas[static_cast(key)] == ButtonDelta::PRESSED; -} - -bool Window::getKeyRelease(inputs::Key key) const -{ - return m_keyboard.deltas[static_cast(key)] == ButtonDelta::RELEASED; -} - -// TODO mouse input - -bool Window::getButton(inputs::MouseButton button) const -{ - return m_mouse.buttons[static_cast(button)]; -} - -bool Window::getButtonPress(inputs::MouseButton button) const -{ - return m_mouse.deltas[static_cast(button)] == ButtonDelta::PRESSED; -} - -bool Window::getButtonRelease(inputs::MouseButton button) const -{ - return m_mouse.deltas[static_cast(button)] == ButtonDelta::RELEASED; -} - -int Window::getMouseX() const -{ - return static_cast(m_mouse.x); -} - -int Window::getMouseY() const -{ - return static_cast(m_mouse.y); -} - -float Window::getMouseNormX() const -{ - return ((float)m_mouse.x * 2.0f / (float)m_winSize.x) - 1.0f; -} - -float Window::getMouseNormY() const -{ - return ((float)m_mouse.y * -2.0f / (float)m_winSize.y) + 1.0f; -} - -int Window::getMouseDX() const -{ - return static_cast(m_mouse.dx); -} - -int Window::getMouseDY() const -{ - return static_cast(m_mouse.dy); -} - -float Window::getMouseScrollX() const -{ - return m_mouse.xscroll; -} - -float Window::getMouseScrollY() const -{ - return m_mouse.yscroll; -} - -// TODO game pad - -// get timer value -uint64_t Window::getNanos() const -{ - uint64_t count; - - count = SDL_GetPerformanceCounter(); - if (m_counterFreq == BILLION) { - return count; - } else { - return count * (BILLION / m_counterFreq); + bool Window::mouseCaptured() + { + return m_mouse.captured; } -} -uint64_t Window::getLastFrameStamp() const -{ - return m_lastFrameStamp; -} + // getting input -uint64_t Window::getFrameCount() const -{ - return m_frames; -} - -uint64_t Window::getStartTime() const -{ - return m_startTime; -} - -float Window::dt() const -{ - return (float)m_lastFrameTime / (float)BILLION; -} - -uint64_t Window::getFPS() const -{ - if (m_lastFrameTime == 0) return 0; - return BILLION / m_lastFrameTime; -} - -uint64_t Window::getAvgFPS() const -{ - uint64_t delta_t = getNanos() - m_avgFpsStart; - if (delta_t == 0) return 0; - return BILLION * (m_frames - m_avgFpsStartCount) / delta_t; -} - -void Window::resetAvgFPS() -{ - m_avgFpsStart = getNanos(); - m_avgFpsStartCount = getFrameCount(); -} - -bool Window::infoBox(const std::string& title, const std::string& msg) -{ - if (isFullscreen() == false) { - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title.c_str(), msg.c_str(), m_handle); - return true; - } else { - return false; + bool Window::getKey(inputs::Key key) const + { + return m_keyboard.keys[static_cast(key)]; } -} -/* STATIC METHODS */ + bool Window::getKeyPress(inputs::Key key) const + { + return m_keyboard.deltas[static_cast(key)] == ButtonDelta::PRESSED; + } -// Display an error message box -void Window::errorBox(const std::string& message) -{ - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Game Error", message.c_str(), NULL); -} + bool Window::getKeyRelease(inputs::Key key) const + { + return m_keyboard.deltas[static_cast(key)] == ButtonDelta::RELEASED; + } + + // TODO mouse input + + bool Window::getButton(inputs::MouseButton button) const + { + return m_mouse.buttons[static_cast(button)]; + } + + bool Window::getButtonPress(inputs::MouseButton button) const + { + return m_mouse.deltas[static_cast(button)] == ButtonDelta::PRESSED; + } + + bool Window::getButtonRelease(inputs::MouseButton button) const + { + return m_mouse.deltas[static_cast(button)] == ButtonDelta::RELEASED; + } + + int Window::getMouseX() const + { + return static_cast(m_mouse.x); + } + + int Window::getMouseY() const + { + return static_cast(m_mouse.y); + } + + float Window::getMouseNormX() const + { + return ((float)m_mouse.x * 2.0f / (float)m_winSize.x) - 1.0f; + } + + float Window::getMouseNormY() const + { + return ((float)m_mouse.y * -2.0f / (float)m_winSize.y) + 1.0f; + } + + int Window::getMouseDX() const + { + return static_cast(m_mouse.dx); + } + + int Window::getMouseDY() const + { + return static_cast(m_mouse.dy); + } + + float Window::getMouseScrollX() const + { + return m_mouse.xscroll; + } + + float Window::getMouseScrollY() const + { + return m_mouse.yscroll; + } + + // TODO game pad + + // get timer value + uint64_t Window::getNanos() const + { + uint64_t count; + + count = SDL_GetPerformanceCounter(); + if (m_counterFreq == BILLION) { + return count; + } + else { + return count * (BILLION / m_counterFreq); + } + } + + uint64_t Window::getLastFrameStamp() const + { + return m_lastFrameStamp; + } + + uint64_t Window::getFrameCount() const + { + return m_frames; + } + + uint64_t Window::getStartTime() const + { + return m_startTime; + } + + float Window::dt() const + { + return (float)m_lastFrameTime / (float)BILLION; + } + + uint64_t Window::getFPS() const + { + if (m_lastFrameTime == 0) return 0; + return BILLION / m_lastFrameTime; + } + + uint64_t Window::getAvgFPS() const + { + uint64_t delta_t = getNanos() - m_avgFpsStart; + if (delta_t == 0) return 0; + return BILLION * (m_frames - m_avgFpsStartCount) / delta_t; + } + + void Window::resetAvgFPS() + { + m_avgFpsStart = getNanos(); + m_avgFpsStartCount = getFrameCount(); + } + + bool Window::infoBox(const std::string& title, const std::string& msg) + { + if (isFullscreen() == false) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title.c_str(), msg.c_str(), m_handle); + return true; + } + else { + return false; + } + } + + /* STATIC METHODS */ + + // Display an error message box + void Window::errorBox(const std::string& message) + { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Game Error", message.c_str(), NULL); + } + +} \ No newline at end of file