Convert back to a static library

This commit is contained in:
Bailey Harrison 2022-10-02 16:34:51 +01:00
parent 50ca206428
commit d7a79abb1c
10 changed files with 751 additions and 720 deletions

View File

@ -6,7 +6,7 @@ project(engine LANGUAGES CXX
VERSION "0.1.0" VERSION "0.1.0"
) )
add_library(${PROJECT_NAME} SHARED add_library(${PROJECT_NAME} STATIC
"src/engine.cpp" "src/engine.cpp"
"src/window.cpp" "src/window.cpp"
@ -74,6 +74,8 @@ add_library(${PROJECT_NAME} SHARED
target_compile_definitions(${PROJECT_NAME} PRIVATE DEFINITIONS "ENGINE_EXPORTS") 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 20)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) 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) target_include_directories(${PROJECT_NAME} PUBLIC dependencies/glm)
# spdlog # spdlog
set(SPDLOG_BUILD_SHARED ON CACHE INTERNAL "" FORCE) set(SPDLOG_BUILD_SHARED OFF CACHE INTERNAL "" FORCE)
set(BUILD_SHARED_LIBS ON) set(BUILD_SHARED_LIBS OFF)
add_subdirectory(dependencies/spdlog) add_subdirectory(dependencies/spdlog)
target_link_libraries(${PROJECT_NAME} PUBLIC spdlog) target_link_libraries(${PROJECT_NAME} PUBLIC spdlog)
target_include_directories(${PROJECT_NAME} PUBLIC dependencies/spdlog/include) target_include_directories(${PROJECT_NAME} PUBLIC dependencies/spdlog/include)

View File

@ -2,9 +2,12 @@
#include "engine_api.h" #include "engine_api.h"
namespace engine {
class Window;
class Input;
}
class Object; class Object;
class Window;
class Input;
class ResourceManager; class ResourceManager;
class ENGINE_API Component { class ENGINE_API Component {
@ -30,8 +33,8 @@ public:
Object& parent; Object& parent;
protected: protected:
Window& win; engine::Window& win;
Input& inp; engine::Input& inp;
ResourceManager& res; ResourceManager& res;
private: private:

View File

@ -11,3 +11,5 @@
# define ENGINE_API # define ENGINE_API
# endif # endif
#endif #endif
#define ENGINE_API

View File

@ -8,7 +8,7 @@
struct SDL_Window; struct SDL_Window;
namespace engine::gfx { namespace engine {
class ENGINE_API GFXDevice { class ENGINE_API GFXDevice {

View File

@ -9,81 +9,85 @@
#include <array> #include <array>
#include <string> #include <string>
class Window; namespace engine {
enum class InputDevice : int { class Window;
MOUSE,
KEYBOARD,
CONTROLLER,
SIZE
};
// This class should be used to get platform/input-device independent input enum class InputDevice : int {
class ENGINE_API Input { MOUSE,
KEYBOARD,
public: CONTROLLER,
SIZE
// 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 { // This class should be used to get platform/input-device independent input
std::string name; class ENGINE_API Input {
enum InputDevice device;
int axis; public:
bool isButtonAxis;
int high; // requires a window reference to get input from
int low; 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<struct ButtonEntry> m_buttonEntries;
std::vector<struct AxisEntry> m_axisEntries;
std::array<bool, static_cast<int>(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<struct ButtonEntry> m_buttonEntries;
std::vector<struct AxisEntry> m_axisEntries;
std::array<bool, static_cast<int>(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);
};

View File

@ -12,8 +12,10 @@
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
class Window; namespace engine {
class Input; class Window;
class Input;
}
class ResourceManager; class ResourceManager;
class SceneRoot; class SceneRoot;
@ -28,8 +30,8 @@ namespace components {
} }
struct GameIO { struct GameIO {
Window * const win; engine::Window * const win;
Input * const input; engine::Input * const input;
ResourceManager * const resMan; ResourceManager * const resMan;
}; };
@ -43,8 +45,8 @@ public:
Object& operator=(const Object&) = delete; Object& operator=(const Object&) = delete;
~Object(); ~Object();
Window& win; engine::Window& win;
Input& inp; engine::Input& inp;
ResourceManager& res; ResourceManager& res;
SceneRoot& root; SceneRoot& root;

View File

@ -17,183 +17,187 @@
ENGINE_API extern const uint64_t BILLION; ENGINE_API extern const uint64_t BILLION;
class ENGINE_API Window { namespace engine {
public: class ENGINE_API Window {
Window(const std::string& title);
Window(const Window&) = delete;
Window& operator=(const Window&) = delete;
~Window();
// Return the title name public:
std::string getTitle() const; 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. // Return the title name
// Run this on every frame. std::string getTitle() const;
void getInputAndEvents();
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 setTitle(std::string title);
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;
// Sets the close flag, check this with shouldClose() // Hides the window (it will appear closed to the user).
void setCloseFlag(); void hide();
// Returns true if the window should remain open // Shows the window again.
bool isRunning() const; 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); // Sets the close flag, check this with shouldClose()
void toggleFullscreen(); 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 isFullscreen() const;
bool setRelativeMouseMode(bool enabled);
// returns true if relative mouse mode is enabled // Relative mouse mode captures the cursor for FPS style use. Returns false if unsupported.
bool mouseCaptured(); 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 // window events
bool getWindowResized() const;
// Set the window resized flag (to recalculate aspect ratios and such)
inline void setResizedFlag()
{
m_justResized = true;
}
// 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 // keyboard events
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;
// 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 // mouse events
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;
// retrieves x coordinate of the mouse // returns true if button is down
int getMouseX() const; bool getButton(inputs::MouseButton button) const;
// retrieves y coordinate of the mouse // returns true if button was just pressed
int getMouseY() const; bool getButtonPress(inputs::MouseButton button) const;
// retrieves mouse x coordinate normalised for OpenGL // returns true if button was just released
float getMouseNormX() const; bool getButtonRelease(inputs::MouseButton button) 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 // 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; // returns the performance counter value in nanoseconds;
uint64_t getNanos() const; uint64_t getNanos() const;
// get the time recorded at the end of the last frame // get the time recorded at the end of the last frame
uint64_t getLastFrameStamp() const; uint64_t getLastFrameStamp() const;
// returns the number of frames elapsed since window creation // returns the number of frames elapsed since window creation
uint64_t getFrameCount() const; uint64_t getFrameCount() const;
uint64_t getStartTime() const;; uint64_t getStartTime() const;;
float dt() const; // returns delta time in seconds float dt() const; // returns delta time in seconds
uint64_t getFPS() const; uint64_t getFPS() const;
uint64_t getAvgFPS() 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 METHODS */
static void errorBox(const std::string& message); static void errorBox(const std::string& message);
public: public:
SDL_Window* m_handle; 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_fullscreen = false;
bool m_justResized = false; bool m_justResized = false;
bool m_keyboardFocus = true; bool m_keyboardFocus = true;
// size in screen coordinates // size in screen coordinates
glm::ivec2 m_winSize = glm::vec2(640, 480); glm::ivec2 m_winSize = glm::vec2(640, 480);
// performance counter frequency // performance counter frequency
uint64_t m_counterFreq; uint64_t m_counterFreq;
// number of frames swapped // number of frames swapped
uint64_t m_frames = 0; uint64_t m_frames = 0;
// frame count offset for fpsAvg // frame count offset for fpsAvg
uint64_t m_avgFpsStartCount = 0; uint64_t m_avgFpsStartCount = 0;
// in nanoseconds // in nanoseconds
uint64_t m_startTime; uint64_t m_startTime;
// in nanoseconds // in nanoseconds
uint64_t m_lastFrameStamp; uint64_t m_lastFrameStamp;
// in nanoseconds; elapsed time between frames // in nanoseconds; elapsed time between frames
uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero
// in nanoseconds // in nanoseconds
uint64_t m_avgFpsStart; uint64_t m_avgFpsStart;
// input stuff // input stuff
enum class ButtonDelta { enum class ButtonDelta {
SAME = 0, SAME = 0,
PRESSED, PRESSED,
RELEASED RELEASED
};
struct {
std::array<bool, SDL_NUM_SCANCODES> keys;
std::array<enum ButtonDelta, SDL_NUM_SCANCODES> deltas;
} m_keyboard{ };
struct {
std::array<bool, static_cast<int>(inputs::MouseButton::M_SIZE)> buttons;
std::array<enum ButtonDelta, 8> 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<bool, SDL_NUM_SCANCODES> keys;
std::array<enum ButtonDelta, SDL_NUM_SCANCODES> deltas;
} m_keyboard{ };
struct {
std::array<bool, static_cast<int>(inputs::MouseButton::M_SIZE)> buttons;
std::array<enum ButtonDelta, 8> 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);
};

View File

@ -14,11 +14,12 @@
#include <assert.h> #include <assert.h>
#include <array>
#include <iostream> #include <iostream>
#include <optional> #include <optional>
#include <unordered_set> #include <unordered_set>
namespace engine::gfx { namespace engine {
static std::vector<const char*> getRequiredVulkanExtensions(SDL_Window* window) static std::vector<const char*> getRequiredVulkanExtensions(SDL_Window* window)
{ {

View File

@ -5,31 +5,33 @@
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
Input::Input(const Window &win) : m_win(win) namespace engine {
{
m_enabledDevices.fill(true);
}
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 // private methods
{
switch (device) { float Input::getDeviceAxis(enum InputDevice device, int axis) const
{
switch (device) {
case InputDevice::MOUSE: case InputDevice::MOUSE:
switch (static_cast<inputs::MouseAxis>(axis)) { switch (static_cast<inputs::MouseAxis>(axis)) {
case inputs::MouseAxis::X: case inputs::MouseAxis::X:
return static_cast<float>(m_win.getMouseDX()); return static_cast<float>(m_win.getMouseDX());
case inputs::MouseAxis::Y: case inputs::MouseAxis::Y:
return static_cast<float>(m_win.getMouseDY()); return static_cast<float>(m_win.getMouseDY());
case inputs::MouseAxis::X_SCR: case inputs::MouseAxis::X_SCR:
return m_win.getMouseScrollX(); return m_win.getMouseScrollX();
case inputs::MouseAxis::Y_SCR: case inputs::MouseAxis::Y_SCR:
return m_win.getMouseScrollY(); return m_win.getMouseScrollY();
default: break; default: break;
} }
break; break;
case InputDevice::KEYBOARD: case InputDevice::KEYBOARD:
@ -37,13 +39,13 @@ float Input::getDeviceAxis(enum InputDevice device, int axis) const
case InputDevice::CONTROLLER: case InputDevice::CONTROLLER:
break; break;
default: 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 bool Input::getDeviceButton(enum InputDevice device, int button) const
{ {
switch (device) { switch (device) {
case InputDevice::MOUSE: case InputDevice::MOUSE:
return m_win.getButton(static_cast<inputs::MouseButton>(button)); return m_win.getButton(static_cast<inputs::MouseButton>(button));
case InputDevice::KEYBOARD: case InputDevice::KEYBOARD:
@ -51,13 +53,13 @@ bool Input::getDeviceButton(enum InputDevice device, int button) const
case InputDevice::CONTROLLER: case InputDevice::CONTROLLER:
break; break;
default: 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 bool Input::getDeviceButtonDown(enum InputDevice device, int button) const
{ {
switch (device) { switch (device) {
case InputDevice::MOUSE: case InputDevice::MOUSE:
return m_win.getButtonPress(static_cast<enum inputs::MouseButton>(button)); return m_win.getButtonPress(static_cast<enum inputs::MouseButton>(button));
case InputDevice::KEYBOARD: case InputDevice::KEYBOARD:
@ -65,13 +67,13 @@ bool Input::getDeviceButtonDown(enum InputDevice device, int button) const
case InputDevice::CONTROLLER: case InputDevice::CONTROLLER:
break; break;
default: 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 bool Input::getDeviceButtonUp(enum InputDevice device, int button) const
{ {
switch (device) { switch (device) {
case InputDevice::MOUSE: case InputDevice::MOUSE:
return m_win.getButtonRelease(static_cast<enum inputs::MouseButton>(button)); return m_win.getButtonRelease(static_cast<enum inputs::MouseButton>(button));
case InputDevice::KEYBOARD: case InputDevice::KEYBOARD:
@ -79,154 +81,157 @@ bool Input::getDeviceButtonUp(enum InputDevice device, int button) const
case InputDevice::CONTROLLER: case InputDevice::CONTROLLER:
break; break;
default: 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 Input::getButtonAxis(enum InputDevice device, int high, int low) const
{ {
float value = 0.0f; float value = 0.0f;
if (getDeviceButton(device, high)) value += 1.0f; if (getDeviceButton(device, high)) value += 1.0f;
if (low != 0) { if (low != 0) {
if (getDeviceButton(device, low)) value += -1.0f; 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) void Input::addInputButton(const std::string& name, InputDevice device, int button)
{ {
m_buttonEntries.push_back( { name, device, button } ); m_buttonEntries.push_back({ name, device, button });
} }
void Input::addInputAxis(const std::string& name, InputDevice device, int axis) void Input::addInputAxis(const std::string& name, InputDevice device, int axis)
{ {
m_axisEntries.push_back( { name, device, axis, false, 0, 0 } ); m_axisEntries.push_back({ name, device, axis, false, 0, 0 });
} }
void Input::addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low) void Input::addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low)
{ {
m_axisEntries.push_back( { name, device, 0, true, high, low } ); m_axisEntries.push_back({ name, device, 0, true, high, low });
} }
// OVERLOADS: // OVERLOADS:
// Add a mouse input // Add a mouse input
void Input::addInputButton(const std::string& name, inputs::MouseButton button) void Input::addInputButton(const std::string& name, inputs::MouseButton button)
{ {
addInputButton(name, InputDevice::MOUSE, static_cast<int>(button)); addInputButton(name, InputDevice::MOUSE, static_cast<int>(button));
} }
void Input::addInputAxis(const std::string& name, inputs::MouseAxis axis) void Input::addInputAxis(const std::string& name, inputs::MouseAxis axis)
{ {
addInputAxis(name, InputDevice::MOUSE, static_cast<int>(axis)); addInputAxis(name, InputDevice::MOUSE, static_cast<int>(axis));
} }
void Input::addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low) void Input::addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low)
{ {
addInputButtonAsAxis(name, InputDevice::MOUSE, static_cast<int>(high), static_cast<int>(low)); addInputButtonAsAxis(name, InputDevice::MOUSE, static_cast<int>(high), static_cast<int>(low));
} }
// Add a keyboard input (TODO: add KeyboardButton enum class) // Add a keyboard input (TODO: add KeyboardButton enum class)
void Input::addInputButton(const std::string& name, inputs::Key button) void Input::addInputButton(const std::string& name, inputs::Key button)
{ {
addInputButton(name, InputDevice::KEYBOARD, static_cast<int>(button)); addInputButton(name, InputDevice::KEYBOARD, static_cast<int>(button));
} }
void Input::addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low) void Input::addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low)
{ {
addInputButtonAsAxis(name, InputDevice::KEYBOARD, static_cast<int>(high), static_cast<int>(low)); addInputButtonAsAxis(name, InputDevice::KEYBOARD, static_cast<int>(high), static_cast<int>(low));
} }
void Input::delInputButton(int index) void Input::delInputButton(int index)
{ {
std::vector<struct ButtonEntry>::iterator it = m_buttonEntries.begin(); std::vector<struct ButtonEntry>::iterator it = m_buttonEntries.begin();
std::advance(it, index); std::advance(it, index);
m_buttonEntries.erase(it); m_buttonEntries.erase(it);
} }
void Input::delInputAxis(int index) void Input::delInputAxis(int index)
{ {
std::vector<struct AxisEntry>::iterator it = m_axisEntries.begin(); std::vector<struct AxisEntry>::iterator it = m_axisEntries.begin();
std::advance(it, index); std::advance(it, index);
m_axisEntries.erase(it); m_axisEntries.erase(it);
} }
void Input::setDeviceActive(enum InputDevice device, bool active) void Input::setDeviceActive(enum InputDevice device, bool active)
{ {
m_enabledDevices[static_cast<int>(device)] = active; m_enabledDevices[static_cast<int>(device)] = active;
} }
bool Input::getDeviceActive(enum InputDevice device) const bool Input::getDeviceActive(enum InputDevice device) const
{ {
return m_enabledDevices[static_cast<int>(device)]; return m_enabledDevices[static_cast<int>(device)];
} }
float Input::getAxis(const std::string& axisName) const float Input::getAxis(const std::string& axisName) const
{ {
for (const AxisEntry& e : m_axisEntries) { for (const AxisEntry& e : m_axisEntries) {
if (e.name == axisName) { if (e.name == axisName) {
if (m_enabledDevices[static_cast<int>(e.device)]) { if (m_enabledDevices[static_cast<int>(e.device)]) {
if (e.isButtonAxis) { if (e.isButtonAxis) {
return getButtonAxis(e.device, e.high, e.low); return getButtonAxis(e.device, e.high, e.low);
} else { }
return getDeviceAxis(e.device, e.axis); 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 Input::getButton(const std::string& buttonName) const
{ {
bool isDown = false; bool isDown = false;
for (const ButtonEntry& e : m_buttonEntries) { for (const ButtonEntry& e : m_buttonEntries) {
if (e.name == buttonName) { if (e.name == buttonName) {
if (m_enabledDevices[static_cast<int>(e.device)]) { if (m_enabledDevices[static_cast<int>(e.device)]) {
if (getDeviceButton(e.device, e.button) == true) { if (getDeviceButton(e.device, e.button) == true) {
isDown = true; isDown = true;
break; break;
}
} }
} }
} }
return isDown;
} }
return isDown;
}
bool Input::getButtonPress(const std::string& buttonName) const bool Input::getButtonPress(const std::string& buttonName) const
{ {
bool isPressed = false; bool isPressed = false;
for (const ButtonEntry& e : m_buttonEntries) { for (const ButtonEntry& e : m_buttonEntries) {
if (e.name == buttonName) { if (e.name == buttonName) {
if (m_enabledDevices[static_cast<int>(e.device)]) { if (m_enabledDevices[static_cast<int>(e.device)]) {
if (getDeviceButtonDown(e.device, e.button) == true) { if (getDeviceButtonDown(e.device, e.button) == true) {
isPressed = true; isPressed = true;
break; break;
}
} }
} }
} }
return isPressed;
} }
return isPressed;
}
bool Input::getButtonRelease(const std::string& buttonName) const bool Input::getButtonRelease(const std::string& buttonName) const
{ {
bool isReleased = false; bool isReleased = false;
for (const ButtonEntry& e : m_buttonEntries) { for (const ButtonEntry& e : m_buttonEntries) {
if (e.name == buttonName) { if (e.name == buttonName) {
if (m_enabledDevices[static_cast<int>(e.device)]) { if (m_enabledDevices[static_cast<int>(e.device)]) {
if (getDeviceButtonUp(e.device, e.button) == true) { if (getDeviceButtonUp(e.device, e.button) == true) {
isReleased = true; isReleased = true;
break; break;
}
} }
} }
} }
return isReleased;
} }
return isReleased;
} }

View File

@ -7,100 +7,102 @@
const uint64_t BILLION = 1000000000; const uint64_t BILLION = 1000000000;
Window::Window(const std::string& title) : m_title(title) namespace engine {
{
// init SDL Window::Window(const std::string& title) : m_title(title)
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) { // init SDL
std::cerr << errMsg << "\nAre you in a graphical environment?\n"; 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_counterFreq = SDL_GetPerformanceFrequency();
m_startTime = getNanos(); m_startTime = getNanos();
m_lastFrameStamp = m_startTime - 1; m_lastFrameStamp = m_startTime - 1;
m_avgFpsStart = m_startTime; m_avgFpsStart = m_startTime;
// create the window // create the window
m_handle = SDL_CreateWindow( m_handle = SDL_CreateWindow(
m_title.c_str(), m_title.c_str(),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
static_cast<int>(m_winSize.x), static_cast<int>(m_winSize.x),
static_cast<int>(m_winSize.y), static_cast<int>(m_winSize.y),
SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN); SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN);
if (m_handle == NULL) { if (m_handle == NULL) {
SDL_Quit(); SDL_Quit();
throw std::runtime_error("Unable to create window: " + std::string(SDL_GetError())); 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 Window::~Window()
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_DestroyWindow(m_handle);
SDL_Quit(); SDL_Quit();
throw std::runtime_error("Unable to create OpenGL context: " + std::string(SDL_GetError()));
} }
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { // private methods
SDL_DestroyWindow(m_handle);
SDL_Quit(); void Window::onResize(Sint32 width, Sint32 height)
throw std::runtime_error("Unable to initialise GLAD"); {
// get window size
m_winSize.x = static_cast<int>(width);
m_winSize.y = static_cast<int>(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() m_mouse.deltas.fill(ButtonDelta::SAME);
{ m_mouse.dx = 0;
SDL_DestroyWindow(m_handle); m_mouse.dy = 0;
SDL_Quit(); m_mouse.xscroll = 0.0f;
} m_mouse.yscroll = 0.0f;
}
// private methods // TODO event methods (like callbacks)
void Window::onResize(Sint32 width, Sint32 height) void Window::onWindowEvent(SDL_WindowEvent& e)
{ {
// get window size
m_winSize.x = static_cast<int>(width);
m_winSize.y = static_cast<int>(height);
m_justResized = true; switch (e.event) {
}
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) {
case SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WINDOWEVENT_SIZE_CHANGED:
onResize(e.data1, e.data2); onResize(e.data1, e.data2);
break; break;
@ -110,23 +112,23 @@ void Window::onWindowEvent(SDL_WindowEvent &e)
case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_WINDOWEVENT_FOCUS_LOST:
m_keyboardFocus = false; m_keyboardFocus = false;
break; break;
}
} }
}
void Window::onKeyEvent(SDL_KeyboardEvent &e) void Window::onKeyEvent(SDL_KeyboardEvent& e)
{ {
bool keyWasDown = m_keyboard.keys[e.keysym.scancode]; bool keyWasDown = m_keyboard.keys[e.keysym.scancode];
bool keyIsDown = (e.state == SDL_PRESSED); bool keyIsDown = (e.state == SDL_PRESSED);
m_keyboard.keys[e.keysym.scancode] = keyIsDown; m_keyboard.keys[e.keysym.scancode] = keyIsDown;
if (keyIsDown != keyWasDown) { // (if key was pressed or released) if (keyIsDown != keyWasDown) { // (if key was pressed or released)
m_keyboard.deltas[e.keysym.scancode] = keyIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED; m_keyboard.deltas[e.keysym.scancode] = keyIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED;
}
} }
}
void Window::onMouseButtonEvent(SDL_MouseButtonEvent &e) void Window::onMouseButtonEvent(SDL_MouseButtonEvent& e)
{ {
enum inputs::MouseButton button = inputs::MouseButton::M_INVALID; enum inputs::MouseButton button = inputs::MouseButton::M_INVALID;
switch (e.button) { switch (e.button) {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
button = inputs::MouseButton::M_LEFT; button = inputs::MouseButton::M_LEFT;
break; break;
@ -142,59 +144,60 @@ void Window::onMouseButtonEvent(SDL_MouseButtonEvent &e)
case SDL_BUTTON_X2: case SDL_BUTTON_X2:
button = inputs::MouseButton::M_X2; button = inputs::MouseButton::M_X2;
break; break;
} }
int buttonIndex = static_cast<int>(button); int buttonIndex = static_cast<int>(button);
bool buttonWasDown = m_mouse.buttons.at(buttonIndex); bool buttonWasDown = m_mouse.buttons.at(buttonIndex);
bool buttonIsDown = (e.state == SDL_PRESSED); bool buttonIsDown = (e.state == SDL_PRESSED);
m_mouse.buttons.at(buttonIndex) = buttonIsDown; m_mouse.buttons.at(buttonIndex) = buttonIsDown;
if (buttonIsDown != buttonWasDown) { // (if button was pressed or released) 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) // only sets delta if it hasn't already been set this frame (to detect very fast presses)
if (m_mouse.deltas[buttonIndex] == ButtonDelta::SAME) { if (m_mouse.deltas[buttonIndex] == ButtonDelta::SAME) {
m_mouse.deltas[buttonIndex] = buttonIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED; m_mouse.deltas[buttonIndex] = buttonIsDown ? ButtonDelta::PRESSED : ButtonDelta::RELEASED;
}
} }
} }
}
void Window::onMouseMotionEvent(SDL_MouseMotionEvent &e) void Window::onMouseMotionEvent(SDL_MouseMotionEvent& e)
{ {
m_mouse.x = e.x; m_mouse.x = e.x;
m_mouse.y = e.y; m_mouse.y = e.y;
m_mouse.dx = e.xrel; m_mouse.dx = e.xrel;
m_mouse.dy = e.yrel; 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;
} }
}
// 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 // public methods
{
return m_title;
}
void Window::getInputAndEvents() std::string Window::getTitle() const
{ {
return m_title;
}
m_frames++; void Window::getInputAndEvents()
uint64_t currentFrameStamp = getNanos(); {
m_lastFrameTime = currentFrameStamp - m_lastFrameStamp;
m_lastFrameStamp = currentFrameStamp;
resetInputDeltas(); m_frames++;
uint64_t currentFrameStamp = getNanos();
m_lastFrameTime = currentFrameStamp - m_lastFrameStamp;
m_lastFrameStamp = currentFrameStamp;
// loop through all available events resetInputDeltas();
SDL_Event e;
while (SDL_PollEvent(&e)) { // loop through all available events
switch (e.type) { SDL_Event e;
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT: case SDL_QUIT:
setCloseFlag(); setCloseFlag();
@ -222,233 +225,238 @@ void Window::getInputAndEvents()
onMouseWheelEvent(e.wheel); onMouseWheelEvent(e.wheel);
break; 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::toggleFullscreen()
{
void Window::setTitle(std::string title) setFullscreen(!m_fullscreen);
{
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) { bool Window::isFullscreen() const
int width, height; {
SDL_GetWindowSize(m_handle, &width, &height); return m_fullscreen;
onResize(width, height);
} }
}
void Window::toggleFullscreen() bool Window::setRelativeMouseMode(bool enabled)
{ {
setFullscreen(!m_fullscreen); m_mouse.captured = enabled;
} int code = SDL_SetRelativeMouseMode(static_cast<SDL_bool>(enabled));
if (code != 0) {
bool Window::isFullscreen() const throw std::runtime_error("Unable to set relative mouse mode");
{ }
return m_fullscreen; else {
} return true;
}
bool Window::setRelativeMouseMode(bool enabled)
{
m_mouse.captured = enabled;
int code = SDL_SetRelativeMouseMode(static_cast<SDL_bool>(enabled));
if (code != 0) {
throw std::runtime_error("Unable to set relative mouse mode");
} else {
return true;
} }
}
bool Window::mouseCaptured() bool Window::mouseCaptured()
{ {
return m_mouse.captured; return m_mouse.captured;
}
// getting input
bool Window::getKey(inputs::Key key) const
{
return m_keyboard.keys[static_cast<int>(key)];
}
bool Window::getKeyPress(inputs::Key key) const
{
return m_keyboard.deltas[static_cast<int>(key)] == ButtonDelta::PRESSED;
}
bool Window::getKeyRelease(inputs::Key key) const
{
return m_keyboard.deltas[static_cast<int>(key)] == ButtonDelta::RELEASED;
}
// TODO mouse input
bool Window::getButton(inputs::MouseButton button) const
{
return m_mouse.buttons[static_cast<int>(button)];
}
bool Window::getButtonPress(inputs::MouseButton button) const
{
return m_mouse.deltas[static_cast<int>(button)] == ButtonDelta::PRESSED;
}
bool Window::getButtonRelease(inputs::MouseButton button) const
{
return m_mouse.deltas[static_cast<int>(button)] == ButtonDelta::RELEASED;
}
int Window::getMouseX() const
{
return static_cast<int>(m_mouse.x);
}
int Window::getMouseY() const
{
return static_cast<int>(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<int>(m_mouse.dx);
}
int Window::getMouseDY() const
{
return static_cast<int>(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 // getting input
{
return m_lastFrameStamp;
}
uint64_t Window::getFrameCount() const bool Window::getKey(inputs::Key key) const
{ {
return m_frames; return m_keyboard.keys[static_cast<int>(key)];
}
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 */ bool Window::getKeyPress(inputs::Key key) const
{
return m_keyboard.deltas[static_cast<int>(key)] == ButtonDelta::PRESSED;
}
// Display an error message box bool Window::getKeyRelease(inputs::Key key) const
void Window::errorBox(const std::string& message) {
{ return m_keyboard.deltas[static_cast<int>(key)] == ButtonDelta::RELEASED;
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Game Error", message.c_str(), NULL); }
}
// TODO mouse input
bool Window::getButton(inputs::MouseButton button) const
{
return m_mouse.buttons[static_cast<int>(button)];
}
bool Window::getButtonPress(inputs::MouseButton button) const
{
return m_mouse.deltas[static_cast<int>(button)] == ButtonDelta::PRESSED;
}
bool Window::getButtonRelease(inputs::MouseButton button) const
{
return m_mouse.deltas[static_cast<int>(button)] == ButtonDelta::RELEASED;
}
int Window::getMouseX() const
{
return static_cast<int>(m_mouse.x);
}
int Window::getMouseY() const
{
return static_cast<int>(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<int>(m_mouse.dx);
}
int Window::getMouseDY() const
{
return static_cast<int>(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);
}
}