Input
This commit is contained in:
@@ -31,6 +31,7 @@ add_subdirectory(assert)
|
|||||||
add_subdirectory(console)
|
add_subdirectory(console)
|
||||||
add_subdirectory(display)
|
add_subdirectory(display)
|
||||||
add_subdirectory(engine)
|
add_subdirectory(engine)
|
||||||
|
add_subdirectory(input)
|
||||||
add_subdirectory(time)
|
add_subdirectory(time)
|
||||||
|
|
||||||
# Platform-specific settings
|
# Platform-specific settings
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
assertTrueImpl(
|
assertTrueImpl(
|
||||||
file,
|
file,
|
||||||
line,
|
line,
|
||||||
pointer != NULL,
|
pointer != NULL && pointer != nullptr,
|
||||||
message
|
message
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -13,16 +13,23 @@ Console::Console(void) :
|
|||||||
variables(),
|
variables(),
|
||||||
buffer()
|
buffer()
|
||||||
{
|
{
|
||||||
|
this->registerCommand("echo", [](auto console, auto args) {
|
||||||
|
if(args.size() == 0) {
|
||||||
|
console.print("Usage: echo <message>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.print("%s", args[0].c_str());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::registerCommand(
|
void Console::registerCommand(
|
||||||
const std::string &cmd,
|
const std::string &cmd,
|
||||||
const std::function<void(std::vector<std::string>&)> &callback
|
const std::function<void(Console&, const std::vector<std::string>&)> &cb
|
||||||
) {
|
) {
|
||||||
assertTrue(cmd.length() > 0, "cmd length must be > 0");
|
assertTrue(cmd.length() > 0, "cmd length must be > 0");
|
||||||
assertTrue(callback != nullptr, "callback must not be null");
|
assertTrue(cb != nullptr, "callback must not be null");
|
||||||
|
|
||||||
this->commands[cmd] = callback;
|
this->commands[cmd] = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -121,7 +128,7 @@ void Console::update() {
|
|||||||
printf("Console: Variable '%s' ", cmdName.c_str());
|
printf("Console: Variable '%s' ", cmdName.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
itCmd->second(args);
|
itCmd->second(*this, args);
|
||||||
}
|
}
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
}
|
}
|
||||||
@@ -141,6 +148,20 @@ void Console::exec(const std::string &str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Console::print(const char_t *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
vprintf(fmt, args);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::print(std::string str) {
|
||||||
|
this->print("%s", str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
Console::~Console(void) {
|
Console::~Console(void) {
|
||||||
|
|
||||||
}
|
}
|
@@ -10,7 +10,8 @@ namespace Dawn {
|
|||||||
struct Console {
|
struct Console {
|
||||||
private:
|
private:
|
||||||
std::map<
|
std::map<
|
||||||
std::string, std::function<void(std::vector<std::string>&)>
|
std::string,
|
||||||
|
std::function<void(Console&, const std::vector<std::string>&)>
|
||||||
> commands;
|
> commands;
|
||||||
|
|
||||||
std::map<std::string, std::pair<
|
std::map<std::string, std::pair<
|
||||||
@@ -31,11 +32,11 @@ namespace Dawn {
|
|||||||
* Registers a command with the console.
|
* Registers a command with the console.
|
||||||
*
|
*
|
||||||
* @param cmd The command string.
|
* @param cmd The command string.
|
||||||
* @param callback The callback function for the command.
|
* @param cb The callback function for the command.
|
||||||
*/
|
*/
|
||||||
void registerCommand(
|
void registerCommand(
|
||||||
const std::string &cmd,
|
const std::string &cmd,
|
||||||
const std::function<void(std::vector<std::string>&)> &callback
|
const std::function<void(Console&, const std::vector<std::string>&)> &cb
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,6 +65,21 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
void exec(const std::string &str);
|
void exec(const std::string &str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a formatted string to the console output.
|
||||||
|
*
|
||||||
|
* @param fmt The format string.
|
||||||
|
* @param ... The format arguments.
|
||||||
|
*/
|
||||||
|
void print(const char_t *fmt, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a string to the console output.
|
||||||
|
*
|
||||||
|
* @param str The string to print.
|
||||||
|
*/
|
||||||
|
void print(std::string str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructs the console.
|
* Destructs the console.
|
||||||
*/
|
*/
|
||||||
|
@@ -8,11 +8,12 @@
|
|||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
Display::Display(void) :
|
Display::Display(Engine &engine) :
|
||||||
#if DAWN_SDL2
|
#if DAWN_SDL2
|
||||||
glContext(nullptr),
|
glContext(nullptr),
|
||||||
window(nullptr)
|
window(nullptr),
|
||||||
#endif
|
#endif
|
||||||
|
engine(engine)
|
||||||
{
|
{
|
||||||
#if DAWN_SDL2
|
#if DAWN_SDL2
|
||||||
uint32_t flags = SDL_INIT_VIDEO;
|
uint32_t flags = SDL_INIT_VIDEO;
|
||||||
@@ -72,14 +73,14 @@ void Display::update(void) {
|
|||||||
while(SDL_PollEvent(&event)) {
|
while(SDL_PollEvent(&event)) {
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case SDL_QUIT: {
|
case SDL_QUIT: {
|
||||||
Engine::getInstance()->console.exec("exit");
|
engine.console.exec("exit");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_WINDOWEVENT: {
|
case SDL_WINDOWEVENT: {
|
||||||
switch(event.window.event) {
|
switch(event.window.event) {
|
||||||
case SDL_WINDOWEVENT_CLOSE: {
|
case SDL_WINDOWEVENT_CLOSE: {
|
||||||
Engine::getInstance()->console.exec("exit");
|
engine.console.exec("exit");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,8 +7,11 @@
|
|||||||
#include "dawn.hpp"
|
#include "dawn.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
|
struct Engine;
|
||||||
|
|
||||||
struct Display {
|
struct Display {
|
||||||
private:
|
private:
|
||||||
|
Engine &engine;
|
||||||
#if DAWN_SDL2
|
#if DAWN_SDL2
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_GLContext glContext;
|
SDL_GLContext glContext;
|
||||||
@@ -20,8 +23,10 @@ namespace Dawn {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Display constructor
|
* Display constructor
|
||||||
|
*
|
||||||
|
* @param engine The engine instance.
|
||||||
*/
|
*/
|
||||||
Display(void);
|
Display(Engine &engine);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the display (swap buffers, etc.)
|
* Update the display (swap buffers, etc.)
|
||||||
|
@@ -7,21 +7,13 @@
|
|||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
std::shared_ptr<Engine> Engine::instance = nullptr;
|
|
||||||
|
|
||||||
std::shared_ptr<Engine> Engine::getInstance() {
|
|
||||||
if(!Engine::instance) {
|
|
||||||
Engine::instance = std::make_shared<Engine>();
|
|
||||||
}
|
|
||||||
return Engine::instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Engine::Engine() :
|
Engine::Engine() :
|
||||||
time(),
|
time(),
|
||||||
console(),
|
console(),
|
||||||
display()
|
display(*this),
|
||||||
|
input(*this)
|
||||||
{
|
{
|
||||||
console.registerCommand("exit", [this](std::vector<std::string> &args) {
|
console.registerCommand("exit", [this](auto console, auto args) {
|
||||||
this->exitRequested = true;
|
this->exitRequested = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -32,6 +24,7 @@ bool_t Engine::isExitRequested() const {
|
|||||||
|
|
||||||
void Engine::update(void) {
|
void Engine::update(void) {
|
||||||
time.update();
|
time.update();
|
||||||
|
input.update();
|
||||||
console.update();
|
console.update();
|
||||||
display.update();
|
display.update();
|
||||||
}
|
}
|
||||||
|
@@ -7,11 +7,12 @@
|
|||||||
#include "time/Time.hpp"
|
#include "time/Time.hpp"
|
||||||
#include "console/Console.hpp"
|
#include "console/Console.hpp"
|
||||||
#include "display/Display.hpp"
|
#include "display/Display.hpp"
|
||||||
|
#include "input/Input.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
struct Engine {
|
struct Engine {
|
||||||
private:
|
private:
|
||||||
static std::shared_ptr<Engine> instance;
|
static Engine* instance;
|
||||||
|
|
||||||
bool_t exitRequested = false;
|
bool_t exitRequested = false;
|
||||||
|
|
||||||
@@ -19,13 +20,7 @@ namespace Dawn {
|
|||||||
Time time;
|
Time time;
|
||||||
Console console;
|
Console console;
|
||||||
Display display;
|
Display display;
|
||||||
|
Input input;
|
||||||
/**
|
|
||||||
* Get the singleton instance of the engine.
|
|
||||||
*
|
|
||||||
* @return A shared pointer to the engine instance.
|
|
||||||
*/
|
|
||||||
static std::shared_ptr<Engine> getInstance();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for the Dawn engine.
|
* Constructor for the Dawn engine.
|
||||||
|
@@ -8,4 +8,5 @@ target_sources(${DAWN_TARGET_NAME}
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
Input.cpp
|
Input.cpp
|
||||||
InputButton.cpp
|
InputButton.cpp
|
||||||
|
InputBind.cpp
|
||||||
)
|
)
|
@@ -4,57 +4,239 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#include "Input.hpp"
|
#include "Input.hpp"
|
||||||
|
#include "assert/Assert.hpp"
|
||||||
|
#include "engine/Engine.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
Input::Input(void) :
|
Input::Input(Engine &engine) :
|
||||||
|
engine(engine),
|
||||||
states({}),
|
states({}),
|
||||||
buttons({})
|
buttons({})
|
||||||
{
|
{
|
||||||
|
engine.console.registerCommand("bind", [this](auto console, auto args) {
|
||||||
|
if(args.size() == 0) {
|
||||||
|
this->engine.console.print("Usage: bind <input> [command]");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t Input::getCurrent(const InputBind &bind) const {
|
// Find input by name.
|
||||||
auto it = states.find(bind);
|
auto itButton = this->buttons.begin();
|
||||||
if(it != states.end()) {
|
while(itButton != this->buttons.end()) {
|
||||||
return it->second.current;
|
if(itButton->getName() == args[0]) break;
|
||||||
|
++itButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(itButton == this->buttons.end()) {
|
||||||
|
this->engine.console.print("No such input: %s", args[0].c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is there a second arg?
|
||||||
|
if(args.size() == 1) {
|
||||||
|
auto bind = itButton->getBind();
|
||||||
|
if(bind) {
|
||||||
|
console.print(bind->getName());
|
||||||
|
} else {
|
||||||
|
console.print(itButton->getCommand());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is there a bind for the arg?
|
||||||
|
auto itBind = InputBind::ALL_BINDS.begin();
|
||||||
|
while(itBind != InputBind::ALL_BINDS.end()) {
|
||||||
|
if(strcasecmp((*itBind)->getName().c_str(),args[1].c_str()) == 0) break;
|
||||||
|
++itBind;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a bind?
|
||||||
|
if(itBind != InputBind::ALL_BINDS.end()) {
|
||||||
|
itButton->setBind(const_cast<InputBind*>(*itBind));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a command then.
|
||||||
|
itButton->setCommand(args[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
#if DAWN_SDL2
|
||||||
|
buttons.push_back(InputButton("esc", InputButtonType::KEY, { .scancode = SDL_SCANCODE_ESCAPE }));
|
||||||
|
buttons.push_back(InputButton("1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_1 }));
|
||||||
|
buttons.push_back(InputButton("2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_2 }));
|
||||||
|
buttons.push_back(InputButton("3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_3 }));
|
||||||
|
buttons.push_back(InputButton("4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_4 }));
|
||||||
|
buttons.push_back(InputButton("5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_5 }));
|
||||||
|
buttons.push_back(InputButton("6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_6 }));
|
||||||
|
buttons.push_back(InputButton("7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_7 }));
|
||||||
|
buttons.push_back(InputButton("8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_8 }));
|
||||||
|
buttons.push_back(InputButton("9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_9 }));
|
||||||
|
buttons.push_back(InputButton("0", InputButtonType::KEY, { .scancode = SDL_SCANCODE_0 }));
|
||||||
|
buttons.push_back(InputButton("-", InputButtonType::KEY, { .scancode = SDL_SCANCODE_MINUS }));
|
||||||
|
buttons.push_back(InputButton("backspace", InputButtonType::KEY, { .scancode = SDL_SCANCODE_BACKSPACE }));
|
||||||
|
buttons.push_back(InputButton("tab", InputButtonType::KEY, { .scancode = SDL_SCANCODE_TAB }));
|
||||||
|
buttons.push_back(InputButton("q", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Q }));
|
||||||
|
buttons.push_back(InputButton("w", InputButtonType::KEY, { .scancode = SDL_SCANCODE_W }));
|
||||||
|
buttons.push_back(InputButton("e", InputButtonType::KEY, { .scancode = SDL_SCANCODE_E }));
|
||||||
|
buttons.push_back(InputButton("r", InputButtonType::KEY, { .scancode = SDL_SCANCODE_R }));
|
||||||
|
buttons.push_back(InputButton("t", InputButtonType::KEY, { .scancode = SDL_SCANCODE_T }));
|
||||||
|
buttons.push_back(InputButton("y", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Y }));
|
||||||
|
buttons.push_back(InputButton("u", InputButtonType::KEY, { .scancode = SDL_SCANCODE_U }));
|
||||||
|
buttons.push_back(InputButton("i", InputButtonType::KEY, { .scancode = SDL_SCANCODE_I }));
|
||||||
|
buttons.push_back(InputButton("o", InputButtonType::KEY, { .scancode = SDL_SCANCODE_O }));
|
||||||
|
buttons.push_back(InputButton("p", InputButtonType::KEY, { .scancode = SDL_SCANCODE_P }));
|
||||||
|
buttons.push_back(InputButton("[", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LEFTBRACKET }));
|
||||||
|
buttons.push_back(InputButton("]", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RIGHTBRACKET }));
|
||||||
|
buttons.push_back(InputButton("enter", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RETURN }));
|
||||||
|
buttons.push_back(InputButton("a", InputButtonType::KEY, { .scancode = SDL_SCANCODE_A }));
|
||||||
|
buttons.push_back(InputButton("s", InputButtonType::KEY, { .scancode = SDL_SCANCODE_S }));
|
||||||
|
buttons.push_back(InputButton("d", InputButtonType::KEY, { .scancode = SDL_SCANCODE_D }));
|
||||||
|
buttons.push_back(InputButton("f", InputButtonType:: KEY, { .scancode = SDL_SCANCODE_F }));
|
||||||
|
buttons.push_back(InputButton("g", InputButtonType::KEY, { .scancode = SDL_SCANCODE_G }));
|
||||||
|
buttons.push_back(InputButton("h", InputButtonType::KEY, { .scancode = SDL_SCANCODE_H }));
|
||||||
|
buttons.push_back(InputButton("j", InputButtonType::KEY, { .scancode = SDL_SCANCODE_J }));
|
||||||
|
buttons.push_back(InputButton("k", InputButtonType::KEY, { .scancode = SDL_SCANCODE_K }));
|
||||||
|
buttons.push_back(InputButton("l", InputButtonType::KEY, { .scancode = SDL_SCANCODE_L }));
|
||||||
|
buttons.push_back(InputButton(";", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SEMICOLON }));
|
||||||
|
buttons.push_back(InputButton("'", InputButtonType::KEY, { .scancode = SDL_SCANCODE_APOSTROPHE }));
|
||||||
|
buttons.push_back(InputButton("`", InputButtonType::KEY, { .scancode = SDL_SCANCODE_GRAVE }));
|
||||||
|
buttons.push_back(InputButton("\\", InputButtonType::KEY, { .scancode = SDL_SCANCODE_BACKSLASH }));
|
||||||
|
buttons.push_back(InputButton("z", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Z }));
|
||||||
|
buttons.push_back(InputButton("x", InputButtonType::KEY, { .scancode = SDL_SCANCODE_X }));
|
||||||
|
buttons.push_back(InputButton("c", InputButtonType::KEY, { .scancode = SDL_SCANCODE_C }));
|
||||||
|
buttons.push_back(InputButton("v", InputButtonType::KEY, { .scancode = SDL_SCANCODE_V }));
|
||||||
|
buttons.push_back(InputButton("b", InputButtonType::KEY, { .scancode = SDL_SCANCODE_B }));
|
||||||
|
buttons.push_back(InputButton("n", InputButtonType::KEY, { .scancode = SDL_SCANCODE_N }));
|
||||||
|
buttons.push_back(InputButton("m", InputButtonType::KEY, { .scancode = SDL_SCANCODE_M }));
|
||||||
|
buttons.push_back(InputButton(",", InputButtonType::KEY, { .scancode = SDL_SCANCODE_COMMA }));
|
||||||
|
buttons.push_back(InputButton(".", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PERIOD }));
|
||||||
|
buttons.push_back(InputButton("/", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SLASH }));
|
||||||
|
buttons.push_back(InputButton("space", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SPACE }));
|
||||||
|
buttons.push_back(InputButton("capslock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_CAPSLOCK }));
|
||||||
|
buttons.push_back(InputButton("f1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F1 }));
|
||||||
|
buttons.push_back(InputButton("f2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F2 }));
|
||||||
|
buttons.push_back(InputButton("f3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F3 }));
|
||||||
|
buttons.push_back(InputButton("f4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F4 }));
|
||||||
|
buttons.push_back(InputButton("f5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F5 }));
|
||||||
|
buttons.push_back(InputButton("f6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F6 }));
|
||||||
|
buttons.push_back(InputButton("f7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F7 }));
|
||||||
|
buttons.push_back(InputButton("f8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F8 }));
|
||||||
|
buttons.push_back(InputButton("f9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F9 }));
|
||||||
|
buttons.push_back(InputButton("f10", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F10 }));
|
||||||
|
buttons.push_back(InputButton("f11", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F11 }));
|
||||||
|
buttons.push_back(InputButton("f12", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F12 }));
|
||||||
|
buttons.push_back(InputButton("printscreen", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PRINTSCREEN }));
|
||||||
|
buttons.push_back(InputButton("scrolllock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SCROLLLOCK }));
|
||||||
|
buttons.push_back(InputButton("pause", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAUSE }));
|
||||||
|
buttons.push_back(InputButton("insert", InputButtonType::KEY, { .scancode = SDL_SCANCODE_INSERT }));
|
||||||
|
buttons.push_back(InputButton("home", InputButtonType::KEY, { .scancode = SDL_SCANCODE_HOME }));
|
||||||
|
buttons.push_back(InputButton("end", InputButtonType::KEY, { .scancode = SDL_SCANCODE_END }));
|
||||||
|
buttons.push_back(InputButton("pageup", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAGEUP }));
|
||||||
|
buttons.push_back(InputButton("pagedown", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAGEDOWN }));
|
||||||
|
buttons.push_back(InputButton("delete", InputButtonType::KEY, { .scancode = SDL_SCANCODE_DELETE }));
|
||||||
|
buttons.push_back(InputButton("right", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RIGHT }));
|
||||||
|
buttons.push_back(InputButton("left", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LEFT }));
|
||||||
|
buttons.push_back(InputButton("down", InputButtonType::KEY, { .scancode = SDL_SCANCODE_DOWN }));
|
||||||
|
buttons.push_back(InputButton("up", InputButtonType::KEY, { .scancode = SDL_SCANCODE_UP }));
|
||||||
|
buttons.push_back(InputButton("numlock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_NUMLOCKCLEAR }));
|
||||||
|
buttons.push_back(InputButton("kp_divide", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_DIVIDE }));
|
||||||
|
buttons.push_back(InputButton("kp_multiply", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_MULTIPLY }));
|
||||||
|
buttons.push_back(InputButton("kp_minus", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_MINUS }));
|
||||||
|
buttons.push_back(InputButton("kp_plus", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_PLUS }));
|
||||||
|
buttons.push_back(InputButton("kp_enter", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_ENTER }));
|
||||||
|
buttons.push_back(InputButton("kp_1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_1 }));
|
||||||
|
buttons.push_back(InputButton("kp_2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_2 }));
|
||||||
|
buttons.push_back(InputButton("kp_3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_3 }));
|
||||||
|
buttons.push_back(InputButton("kp_4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_4 }));
|
||||||
|
buttons.push_back(InputButton("kp_5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_5 }));
|
||||||
|
buttons.push_back(InputButton("kp_6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_6 }));
|
||||||
|
buttons.push_back(InputButton("kp_7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_7 }));
|
||||||
|
buttons.push_back(InputButton("kp_8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_8 }));
|
||||||
|
buttons.push_back(InputButton("kp_9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_9 }));
|
||||||
|
buttons.push_back(InputButton("kp_0", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_0 }));
|
||||||
|
buttons.push_back(InputButton("kp_period", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_PERIOD }));
|
||||||
|
buttons.push_back(InputButton("ctrl", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LCTRL }));
|
||||||
|
buttons.push_back(InputButton("shift", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LSHIFT }));
|
||||||
|
buttons.push_back(InputButton("alt", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LALT }));
|
||||||
|
buttons.push_back(InputButton("rctrl", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RCTRL }));
|
||||||
|
buttons.push_back(InputButton("rshift", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RSHIFT }));
|
||||||
|
buttons.push_back(InputButton("ralt", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RALT }));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float_t Input::getCurrent(const InputBind *bind) const {
|
||||||
|
assertNotNull(bind, "Input bind cannot be NULL");
|
||||||
|
|
||||||
|
auto it = states.find(bind);
|
||||||
|
if(it != states.end()) return it->second.current;
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t Input::getPrevious(const InputBind &bind) const {
|
float_t Input::getPrevious(const InputBind* bind) const {
|
||||||
|
assertNotNull(bind, "Input bind cannot be NULL");
|
||||||
|
|
||||||
auto it = states.find(bind);
|
auto it = states.find(bind);
|
||||||
if(it != states.end()) {
|
if(it != states.end()) return it->second.previous;
|
||||||
return it->second.previous;
|
|
||||||
}
|
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t Input::getWhen(const InputBind &bind) const {
|
float_t Input::getWhen(const InputBind *bind) const {
|
||||||
auto it = states.find(bind);
|
auto it = states.find(bind);
|
||||||
if(it != states.end()) {
|
if(it != states.end()) return it->second.when;
|
||||||
return it->second.when;
|
|
||||||
}
|
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t Input::isDown(const InputBind &bind) const {
|
bool_t Input::isDown(const InputBind* bind) const {
|
||||||
|
assertNotNull(bind, "Input bind cannot be NULL");
|
||||||
return this->getCurrent(bind) != 0.0f;
|
return this->getCurrent(bind) != 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t Input::isUp(const InputBind &bind) const {
|
bool_t Input::isUp(const InputBind* bind) const {
|
||||||
|
assertNotNull(bind, "Input bind cannot be NULL");
|
||||||
return this->getCurrent(bind) == 0.0f;
|
return this->getCurrent(bind) == 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t Input::wasPressed(const InputBind &bind) const {
|
bool_t Input::wasPressed(const InputBind* bind) const {
|
||||||
|
assertNotNull(bind, "Input bind cannot be NULL");
|
||||||
return this->getPrevious(bind) == 0.0f && this->getCurrent(bind) != 0.0f;
|
return this->getPrevious(bind) == 0.0f && this->getCurrent(bind) != 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t Input::wasReleased(const InputBind &bind) const {
|
bool_t Input::wasReleased(const InputBind* bind) const {
|
||||||
|
assertNotNull(bind, "Input bind cannot be NULL");
|
||||||
return this->getPrevious(bind) != 0.0f && this->getCurrent(bind) == 0.0f;
|
return this->getPrevious(bind) != 0.0f && this->getCurrent(bind) == 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::update(void) {
|
void Input::update(void) {
|
||||||
|
// Reset all input bind states
|
||||||
|
for(auto &state : this->states) {
|
||||||
|
state.second.previous = state.second.current;
|
||||||
|
state.second.current = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update button states.
|
||||||
|
auto itButton = this->buttons.begin();
|
||||||
|
while(itButton != this->buttons.end()) {
|
||||||
|
itButton->update();
|
||||||
|
|
||||||
|
if(itButton->getCurrent() != 0.0f) {
|
||||||
|
// Exec command if actuated this tick.
|
||||||
|
auto cmd = itButton->getCommand();
|
||||||
|
if(itButton->getPrevious() == 0.0f && cmd.length() > 0) {
|
||||||
|
engine.console.exec(cmd);
|
||||||
|
} else {
|
||||||
|
// If bound to an input, update the bind state.
|
||||||
|
auto bind = itButton->getBind();
|
||||||
|
if(bind != nullptr) {
|
||||||
|
states[bind].when = engine.time.time;
|
||||||
|
states[bind].current = fmaxf(
|
||||||
|
states[bind].current, itButton->getCurrent()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++itButton;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Input::~Input(void) {
|
Input::~Input(void) {
|
||||||
|
@@ -7,31 +7,27 @@
|
|||||||
#include "InputButton.hpp"
|
#include "InputButton.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
enum class InputBind {
|
|
||||||
UP = "UP",
|
|
||||||
DOWN = "DOWN",
|
|
||||||
LEFT = "LEFT",
|
|
||||||
RIGHT = "RIGHT",
|
|
||||||
ACCEPT = "ACCEPT",
|
|
||||||
CANCEL = "CANCEL"
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InputBindState {
|
struct InputBindState {
|
||||||
float_t current;
|
float_t current;
|
||||||
float_t previous;
|
float_t previous;
|
||||||
float_t when;
|
float_t when;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Engine;
|
||||||
|
|
||||||
struct Input {
|
struct Input {
|
||||||
private:
|
private:
|
||||||
std::map<InputBind, InputBindState> states;
|
std::map<const InputBind*, InputBindState> states;
|
||||||
std::vector<InputButton> buttons;
|
std::vector<InputButton> buttons;
|
||||||
|
Engine &engine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Initializes the input manager.
|
* Initializes the input manager.
|
||||||
|
*
|
||||||
|
* @param engine The engine instance.
|
||||||
*/
|
*/
|
||||||
Input(void);
|
Input(Engine &engine);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current state of the input bind.
|
* Returns the current state of the input bind.
|
||||||
@@ -39,7 +35,7 @@ namespace Dawn {
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return The current state of the input bind.
|
* @return The current state of the input bind.
|
||||||
*/
|
*/
|
||||||
float_t getCurrent(const InputBind &bind) const;
|
float_t getCurrent(const InputBind* bind) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the previous state of the input bind.
|
* Returns the previous state of the input bind.
|
||||||
@@ -47,7 +43,7 @@ namespace Dawn {
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return The previous state of the input bind.
|
* @return The previous state of the input bind.
|
||||||
*/
|
*/
|
||||||
float_t getPrevious(const InputBind &bind) const;
|
float_t getPrevious(const InputBind* bind) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the time when the input last changed states.
|
* Returns the time when the input last changed states.
|
||||||
@@ -55,7 +51,7 @@ namespace Dawn {
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return The time when the input last changed states.
|
* @return The time when the input last changed states.
|
||||||
*/
|
*/
|
||||||
float_t getWhen(const InputBind &bind) const;
|
float_t getWhen(const InputBind* bind) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the input bind is currently down.
|
* Returns true if the input bind is currently down.
|
||||||
@@ -63,7 +59,7 @@ namespace Dawn {
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return True if the input bind is currently down.
|
* @return True if the input bind is currently down.
|
||||||
*/
|
*/
|
||||||
bool_t isDown(const InputBind &bind) const;
|
bool_t isDown(const InputBind* bind) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the input bind is currently up.
|
* Returns true if the input bind is currently up.
|
||||||
@@ -71,7 +67,7 @@ namespace Dawn {
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return True if the input bind is currently up.
|
* @return True if the input bind is currently up.
|
||||||
*/
|
*/
|
||||||
bool_t isUp(const InputBind &bind) const;
|
bool_t isUp(const InputBind* bind) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the input bind was pressed this frame.
|
* Returns true if the input bind was pressed this frame.
|
||||||
@@ -79,7 +75,7 @@ namespace Dawn {
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return True if the input bind was pressed this frame.
|
* @return True if the input bind was pressed this frame.
|
||||||
*/
|
*/
|
||||||
bool_t wasPressed(const InputBind &bind) const;
|
bool_t wasPressed(const InputBind* bind) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the input bind was released this frame.
|
* Returns true if the input bind was released this frame.
|
||||||
@@ -87,7 +83,7 @@ namespace Dawn {
|
|||||||
* @param bind The input bind to check.
|
* @param bind The input bind to check.
|
||||||
* @return True if the input bind was released this frame.
|
* @return True if the input bind was released this frame.
|
||||||
*/
|
*/
|
||||||
bool_t wasReleased(const InputBind &bind) const;
|
bool_t wasReleased(const InputBind* bind) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the input manager.
|
* Updates the input manager.
|
||||||
|
26
src/input/InputBind.cpp
Normal file
26
src/input/InputBind.cpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (c) 2025 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#include "InputBind.hpp"
|
||||||
|
|
||||||
|
using namespace Dawn;
|
||||||
|
|
||||||
|
std::vector<const InputBind*> InputBind::ALL_BINDS;
|
||||||
|
|
||||||
|
const InputBind InputBind::UP("UP");
|
||||||
|
const InputBind InputBind::DOWN("DOWN");
|
||||||
|
const InputBind InputBind::LEFT("LEFT");
|
||||||
|
const InputBind InputBind::RIGHT("RIGHT");
|
||||||
|
const InputBind InputBind::ACCEPT("ACCEPT");
|
||||||
|
const InputBind InputBind::CANCEL("CANCEL");
|
||||||
|
|
||||||
|
|
||||||
|
InputBind::InputBind(const std::string &name) : name(name) {
|
||||||
|
ALL_BINDS.push_back(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InputBind::getName() const {
|
||||||
|
return this->name;
|
||||||
|
}
|
35
src/input/InputBind.hpp
Normal file
35
src/input/InputBind.hpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (c) 2025 Dominic Masters
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "dawn.hpp"
|
||||||
|
|
||||||
|
namespace Dawn {
|
||||||
|
struct InputBind {
|
||||||
|
public:
|
||||||
|
const std::string name;
|
||||||
|
|
||||||
|
static std::vector<const InputBind*> ALL_BINDS;
|
||||||
|
static const InputBind UP;
|
||||||
|
static const InputBind DOWN;
|
||||||
|
static const InputBind LEFT;
|
||||||
|
static const InputBind RIGHT;
|
||||||
|
static const InputBind ACCEPT;
|
||||||
|
static const InputBind CANCEL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the input bind.
|
||||||
|
*
|
||||||
|
* @return The name of the input bind.
|
||||||
|
*/
|
||||||
|
std::string getName() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Private only constructor for an InputBind.
|
||||||
|
*/
|
||||||
|
InputBind(const std::string &name);
|
||||||
|
};
|
||||||
|
}
|
@@ -4,17 +4,87 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#include "InputButton.hpp"
|
#include "InputButton.hpp"
|
||||||
|
#include "engine/Engine.hpp"
|
||||||
|
#include "assert/Assert.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
InputButton::InputButton(
|
InputButton::InputButton(
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
const InputButtonType buttonType
|
const InputButtonType buttonType,
|
||||||
|
const InputButtonData data
|
||||||
) :
|
) :
|
||||||
name(name),
|
name(name),
|
||||||
buttonType(buttonType),
|
buttonType(buttonType),
|
||||||
data(data),
|
data(data),
|
||||||
command("")
|
command(""),
|
||||||
|
bind(nullptr),
|
||||||
|
current(0.0f),
|
||||||
|
previous(0.0f)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputButton::update() {
|
||||||
|
previous = current;
|
||||||
|
|
||||||
|
switch(this->buttonType) {
|
||||||
|
case InputButtonType::KEY: {
|
||||||
|
#if DAWN_SDL2
|
||||||
|
const uint8_t *state = SDL_GetKeyboardState(NULL);
|
||||||
|
current = state[this->data.scancode] ? 1.0f : 0.0f;
|
||||||
|
#else
|
||||||
|
#error "No input platform defined"
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case InputButtonType::BUTTON: {
|
||||||
|
current = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case InputButtonType::AXIS: {
|
||||||
|
current = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
assertUnreachable("Unknown input button type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float_t InputButton::getCurrent(void) const {
|
||||||
|
return this->current;
|
||||||
|
}
|
||||||
|
|
||||||
|
float_t InputButton::getPrevious(void) const {
|
||||||
|
return this->previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InputButton::getName(void) const {
|
||||||
|
return this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputButtonType InputButton::getType(void) const {
|
||||||
|
return this->buttonType;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InputButton::getCommand(void) const {
|
||||||
|
return this->command;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBind * InputButton::getBind(void) const {
|
||||||
|
return this->bind;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputButton::setBind(const InputBind *bind) {
|
||||||
|
this->bind = const_cast<InputBind*>(bind);
|
||||||
|
this->command.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputButton::setCommand(const std::string &command) {
|
||||||
|
this->command = command;
|
||||||
|
this->bind = nullptr;
|
||||||
|
}
|
@@ -4,15 +4,19 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.hpp"
|
#include "InputBind.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
enum class InputButtonType {
|
enum class InputButtonType {
|
||||||
BUTTON,
|
BUTTON,
|
||||||
AXIS
|
AXIS,
|
||||||
|
KEY
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputButtonData {
|
union InputButtonData {
|
||||||
|
#if DAWN_SDL2
|
||||||
|
SDL_Scancode scancode;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputButton {
|
struct InputButton {
|
||||||
@@ -20,7 +24,12 @@ namespace Dawn {
|
|||||||
const std::string name;
|
const std::string name;
|
||||||
const InputButtonType buttonType;
|
const InputButtonType buttonType;
|
||||||
const InputButtonData data;
|
const InputButtonData data;
|
||||||
|
|
||||||
std::string command;
|
std::string command;
|
||||||
|
InputBind *bind;
|
||||||
|
|
||||||
|
float_t previous;
|
||||||
|
float_t current;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +47,25 @@ namespace Dawn {
|
|||||||
const InputButtonData data
|
const InputButtonData data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the state of the input button.
|
||||||
|
*/
|
||||||
|
void update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current state of the input button.
|
||||||
|
*
|
||||||
|
* @return The current state of the input button.
|
||||||
|
*/
|
||||||
|
float_t getCurrent() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the previous state of the input button.
|
||||||
|
*
|
||||||
|
* @return The previous state of the input button.
|
||||||
|
*/
|
||||||
|
float_t getPrevious() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the human name of the input button.
|
* Returns the human name of the input button.
|
||||||
*
|
*
|
||||||
@@ -58,5 +86,26 @@ namespace Dawn {
|
|||||||
* @return The command that is executed when the input button is pressed.
|
* @return The command that is executed when the input button is pressed.
|
||||||
*/
|
*/
|
||||||
std::string getCommand(void) const;
|
std::string getCommand(void) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the input bind associated with this button, or NULL if none.
|
||||||
|
*
|
||||||
|
* @return The input bind associated with this button, or NULL if none.
|
||||||
|
*/
|
||||||
|
InputBind * getBind(void) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the input bind for a button.
|
||||||
|
*
|
||||||
|
* @param bind The input bind to associate with this button.
|
||||||
|
*/
|
||||||
|
void setBind(const InputBind *bind);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the command to be executed when the button is pressed.
|
||||||
|
*
|
||||||
|
* @param command The command to execute when the button is pressed.
|
||||||
|
*/
|
||||||
|
void setCommand(const std::string &command);
|
||||||
};
|
};
|
||||||
}
|
}
|
@@ -9,11 +9,15 @@
|
|||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
auto engine = Engine::getInstance();
|
std::shared_ptr<Engine> engine = std::make_shared<Engine>();
|
||||||
|
|
||||||
|
engine->console.exec("bind w up");
|
||||||
|
|
||||||
while(!engine->isExitRequested()) {
|
while(!engine->isExitRequested()) {
|
||||||
engine->update();
|
engine->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
engine = nullptr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Reference in New Issue
Block a user