restructured project to match a more standard cmake setup

This commit is contained in:
Noel Berry
2020-12-31 13:43:23 -08:00
parent c841bd82a1
commit 241d863ac4
97 changed files with 233 additions and 264 deletions

403
src/input/input.cpp Normal file
View File

@ -0,0 +1,403 @@
#include <blah/input/input.h>
#include <blah/core/app.h>
#include <blah/core/time.h>
#include <blah/core/log.h>
#include <blah/math/point.h>
#include "../internal/input_backend.h"
#include <string.h>
using namespace Blah;
namespace
{
InputState g_last_state;
InputState g_curr_state;
InputState g_next_state;
InputState g_empty_state;
ControllerState g_empty_controller;
}
void InputBackend::init()
{
g_empty_controller.name = "Disconnected";
for (int i = 0; i < Blah::Input::max_controllers; i++)
g_empty_state.controllers[i].name = g_empty_controller.name;
g_last_state = g_empty_state;
g_curr_state = g_empty_state;
g_next_state = g_empty_state;
}
void InputBackend::frame()
{
// cycle states
g_last_state = g_curr_state;
g_curr_state = g_next_state;
// copy state, clear pressed / released values
{
for (int i = 0; i < Blah::Input::max_keyboard_keys; i++)
{
g_next_state.keyboard.pressed[i] = false;
g_next_state.keyboard.released[i] = false;
}
for (int i = 0; i < Blah::Input::max_mouse_buttons; i++)
{
g_next_state.mouse.pressed[i] = false;
g_next_state.mouse.released[i] = false;
}
g_next_state.mouse.wheel = Point::zero;
for (int i = 0; i < Blah::Input::max_text_input; i++)
g_next_state.keyboard.text[i] = 0;
for (int i = 0; i < Blah::Input::max_controllers; i++)
{
ControllerState* controller = &(g_next_state.controllers[i]);
if (!controller->is_connected)
controller->name = nullptr;
for (int j = 0; j < Blah::Input::max_controller_buttons; j++)
{
controller->pressed[j] = false;
controller->released[j] = false;
}
}
}
}
void InputBackend::on_mouse_move(float x, float y)
{
g_next_state.mouse.position.x = x;
g_next_state.mouse.position.y = y;
Point size = Point(App::width(), App::height());
Point draw = Point(App::draw_width(), App::draw_height());
g_next_state.mouse.draw_position.x = (x / (float)size.x) * draw.x;
g_next_state.mouse.draw_position.y = (y / (float)size.y) * draw.y;
}
void InputBackend::on_mouse_screen_move(float x, float y)
{
g_next_state.mouse.screen_position.x = x;
g_next_state.mouse.screen_position.y = y;
}
void InputBackend::on_mouse_down(MouseButton button)
{
int i = (int)button;
if (i >= 0 && i < Blah::Input::max_mouse_buttons)
{
g_next_state.mouse.down[i] = true;
g_next_state.mouse.pressed[i] = true;
g_next_state.mouse.timestamp[i] = Time::milliseconds;
}
}
void InputBackend::on_mouse_up(MouseButton button)
{
int i = (int)button;
if (i >= 0 && i < Blah::Input::max_mouse_buttons)
{
g_next_state.mouse.down[i] = false;
g_next_state.mouse.released[i] = true;
}
}
void InputBackend::on_key_down(Key key)
{
int i = (int)key;
if (i >= 0 && i < Blah::Input::max_keyboard_keys)
{
g_next_state.keyboard.down[i] = true;
g_next_state.keyboard.pressed[i] = true;
g_next_state.keyboard.timestamp[i] = Time::milliseconds;
}
}
void InputBackend::on_mouse_wheel(Point wheel)
{
g_next_state.mouse.wheel = wheel;
}
void InputBackend::on_key_up(Key key)
{
int i = (int)key;
if (i >= 0 && i < Blah::Input::max_keyboard_keys)
{
g_next_state.keyboard.down[i] = false;
g_next_state.keyboard.released[i] = true;
}
}
void InputBackend::on_text_utf8(const char* text)
{
strncat(g_next_state.keyboard.text, text, Blah::Input::max_text_input);
}
void InputBackend::on_controller_connect(int index, const char* name, int is_gamepad, int button_count, int axis_count, uint16_t vendor, uint16_t product, uint16_t version)
{
if (index < Blah::Input::max_controllers)
{
ControllerState* controller = &(g_next_state.controllers[index]);
*controller = g_empty_controller;
controller->name = name;
controller->is_connected = 1;
controller->is_gamepad = is_gamepad;
controller->button_count = button_count;
controller->axis_count = axis_count;
controller->vendor = vendor;
controller->product = product;
controller->version = version;
}
}
void InputBackend::on_controller_disconnect(int index)
{
if (index < Blah::Input::max_controllers)
g_next_state.controllers[index] = g_empty_controller;
}
void InputBackend::on_button_down(int index, int button)
{
if (index < Blah::Input::max_controllers &&
button < Blah::Input::max_controller_buttons &&
g_next_state.controllers[index].is_connected &&
button < g_next_state.controllers[index].button_count)
{
g_next_state.controllers[index].down[button] = 1;
g_next_state.controllers[index].pressed[button] = 1;
g_next_state.controllers[index].button_timestamp[button] = Time::milliseconds;
}
}
void InputBackend::on_button_up(int index, int button)
{
if (index < Blah::Input::max_controllers &&
button < Blah::Input::max_controller_buttons &&
g_next_state.controllers[index].is_connected &&
button < g_next_state.controllers[index].button_count)
{
g_next_state.controllers[index].down[button] = 0;
g_next_state.controllers[index].released[button] = 1;
}
}
void InputBackend::on_axis_move(int index, int axis, float value)
{
if (index < Blah::Input::max_controllers &&
axis < Blah::Input::max_controller_axis &&
g_next_state.controllers[index].is_connected &&
axis < g_next_state.controllers[index].axis_count)
{
g_next_state.controllers[index].axis[axis] = value;
g_next_state.controllers[index].axis_timestamp[axis] = Time::milliseconds;
}
}
const InputState* Input::state()
{
return &g_curr_state;
}
const InputState* Input::last_state()
{
return &g_last_state;
}
Vec2 Input::mouse()
{
return g_curr_state.mouse.position;
}
Vec2 Input::mouse_draw()
{
return Vec2(g_curr_state.mouse.draw_position);
}
Vec2 Input::mouse_screen()
{
return Vec2(g_curr_state.mouse.screen_position);
}
bool Input::pressed(MouseButton button)
{
int i = (int)button;
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.pressed[i];
}
bool Input::down(MouseButton button)
{
int i = (int)button;
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.down[i];
}
bool Input::released(MouseButton button)
{
int i = (int)button;
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.released[i];
}
Point Input::mouse_wheel()
{
return g_curr_state.mouse.wheel;
}
bool Input::pressed(Key key)
{
int i = (int)key;
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.pressed[i];
}
bool Input::down(Key key)
{
int i = (int)key;
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.down[i];
}
bool Input::released(Key key)
{
int i = (int)key;
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.released[i];
}
bool Input::ctrl()
{
return down(Key::LeftControl) || down(Key::RightControl);
}
bool Input::shift()
{
return down(Key::LeftShift) || down(Key::RightShift);
}
bool Input::alt()
{
return down(Key::LeftAlt) || down(Key::RightAlt);
}
const char* Input::text()
{
return g_curr_state.keyboard.text;
}
const ControllerState* Input::controller(int controllerIndex)
{
if (controllerIndex >= Blah::Input::max_controllers)
{
Log::warn("Trying to access a out-of-range controller at %i", controllerIndex);
return &g_empty_controller;
}
else if (!g_curr_state.controllers[controllerIndex].is_connected)
{
return &g_empty_controller;
}
else
{
return &g_curr_state.controllers[controllerIndex];
}
}
bool Input::pressed(int controllerIndex, Button button)
{
int i = (int)button;
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
return g_curr_state.controllers[controllerIndex].pressed[i];
return false;
}
bool Input::down(int controllerIndex, Button button)
{
int i = (int)button;
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
return g_curr_state.controllers[controllerIndex].down[i];
return false;
}
bool Input::released(int controllerIndex, Button button)
{
int i = (int)button;
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
return g_curr_state.controllers[controllerIndex].released[i];
return false;
}
float Input::axis_check(int controllerIndex, Axis axis)
{
int i = (int)axis;
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_axis)
return g_curr_state.controllers[controllerIndex].axis[i];
return 0;
}
int Input::axis_check(int fallback, Key negative, Key positive)
{
if (Input::pressed(positive))
return 1;
else if (Input::pressed(negative))
return -1;
else
{
bool pos = Input::down(positive);
bool neg = Input::down(negative);
if (pos && neg)
return fallback;
else if (pos)
return 1;
else if (neg)
return -1;
else
return 0;
}
}
int Input::axis_check(int fallback, int controllerIndex, Button negative, Button positive)
{
if (Input::pressed(controllerIndex, positive))
return 1;
else if (Input::pressed(controllerIndex, negative))
return -1;
else
{
bool pos = Input::down(controllerIndex, positive);
bool neg = Input::down(controllerIndex, negative);
if (pos && neg)
return fallback;
else if (pos)
return 1;
else if (neg)
return -1;
else
return 0;
}
}
const char* Input::name_of(Key key)
{
switch (key)
{
#define DEFINE_KEY(name, value) case Key::name: return #name;
BLAH_KEY_DEFINITIONS
#undef DEFINE_KEY
}
return "Unknown";
}
const char* Input::name_of(Button button)
{
switch (button)
{
#define DEFINE_BTN(name, value) case Button::name: return #name;
BLAH_BUTTON_DEFINITIONS
#undef DEFINE_BTN
}
return "Unknown";
}

166
src/input/virtual_axis.cpp Normal file
View File

@ -0,0 +1,166 @@
#include <blah/input/virtual_axis.h>
#include <blah/core/time.h>
#include <blah/core/log.h>
using namespace Blah;
VirtualAxis& VirtualAxis::add_keys(Key negative, Key positive)
{
if (m_axes_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualAxis Keys out of bounds!");
else
{
m_keys[m_keys_len].init(negative, positive);
m_keys_len++;
}
return *this;
}
VirtualAxis& VirtualAxis::add_buttons(int gamepad_id, Button negative, Button positive)
{
if (m_axes_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualAxis Buttons out of bounds!");
else
{
m_buttons[m_buttons_len].init(gamepad_id, negative, positive);
m_buttons_len++;
}
return *this;
}
VirtualAxis& VirtualAxis::add_axis(int gamepad_id, Axis axis, float deadzone)
{
if (m_axes_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualAxis Axes out of bounds!");
else
{
m_axes[m_axes_len].init(gamepad_id, axis, deadzone);
m_axes_len++;
}
return *this;
}
VirtualAxis& VirtualAxis::repeat(float m_repeat_delay, float m_repeat_interval)
{
this->m_repeat_delay = m_repeat_delay;
this->m_repeat_interval = m_repeat_interval;
return *this;
}
VirtualAxis& VirtualAxis::press_buffer(float duration)
{
this->m_press_buffer = duration;
return *this;
}
VirtualAxis& VirtualAxis::release_buffer(float duration)
{
this->m_release_buffer = duration;
return *this;
}
void VirtualAxis::update()
{
m_last_value = m_value;
m_value = 0;
for (int i = 0; i < m_keys_len; i++)
{
m_keys[i].update();
if (m_value == 0)
m_value = (float)m_keys[i].value;
}
for (int i = 0; i < m_buttons_len; i++)
{
m_buttons[i].update();
if (m_value == 0)
m_value = (float)m_buttons[i].value;
}
for (int i = 0; i < m_axes_len; i++)
{
m_axes[i].update();
if (m_value == 0)
m_value = m_axes[i].value;
}
//Valuei
m_last_value_i = m_value_i;
if (m_value > 0)
m_value_i = 1;
else if (m_value < 0)
m_value_i = -1;
else
m_value_i = 0;
//pressed?
m_pressed = false;
if (m_value_i != 0 && m_last_value_i != m_value_i)
{
m_pressed = true;
m_last_press_time = m_repeat_press_time = Time::elapsed;
}
else if (m_value_i == m_last_value_i && m_value_i != 0)
{
if (Time::elapsed - m_last_press_time <= m_press_buffer)
m_pressed = true;
else if (m_repeat_interval > 0 && Time::elapsed >= m_repeat_press_time + m_repeat_delay)
{
int prev = (int)((Time::previous_elapsed - m_repeat_press_time - m_repeat_delay) / m_repeat_interval);
int cur = (int)((Time::elapsed - m_repeat_press_time - m_repeat_delay) / m_repeat_interval);
m_pressed = prev < cur;
}
}
//released?
if (m_last_value_i != 0 && m_value_i != m_last_value_i)
{
m_released = true;
m_last_release_time = Time::elapsed;
}
else if (Time::elapsed - m_last_release_time <= m_release_buffer)
m_released = true;
else
m_released = false;
}
void VirtualAxis::KeysNode::init(Key negative, Key positive)
{
this->negative = negative;
this->positive = positive;
}
void VirtualAxis::KeysNode::update()
{
value = Input::axis_check(value, negative, positive);
}
void VirtualAxis::ButtonsNode::init(int gamepad_id, Button negative, Button positive)
{
this->gamepad_id = gamepad_id;
this->negative = negative;
this->positive = positive;
}
void VirtualAxis::ButtonsNode::update()
{
value = Input::axis_check(value, gamepad_id, negative, positive);
}
void VirtualAxis::AxisNode::init(int gamepad_id, Axis axis, float deadzone)
{
this->gamepad_id = gamepad_id;
this->axis = axis;
this->deadzone = deadzone;
}
void VirtualAxis::AxisNode::update()
{
value = Input::axis_check(gamepad_id, axis);
if (value < deadzone && value > -deadzone)
value = 0;
}

View File

@ -0,0 +1,174 @@
#include <blah/input/virtual_button.h>
#include <blah/core/time.h>
#include <blah/core/log.h>
using namespace Blah;
VirtualButton& VirtualButton::add_key(Key key)
{
if (m_keys_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualButton Keys out of bounds!");
else
{
m_keys[m_keys_len].init(key);
m_keys_len++;
}
return *this;
}
VirtualButton& VirtualButton::add_button(int gamepad_id, Button button)
{
if (m_buttons_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualButton Buttons out of bounds!");
else
{
m_buttons[m_buttons_len].init(gamepad_id, button);
m_buttons_len++;
}
return *this;
}
VirtualButton& VirtualButton::add_axis(int gamepad_id, Axis axis, float threshold, bool greater_than)
{
if (m_axes_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualButton Axes out of bounds!");
else
{
m_axes[m_axes_len].init(gamepad_id, axis, threshold, greater_than);
m_axes_len++;
}
return *this;
}
VirtualButton& VirtualButton::repeat(float m_repeat_delay, float m_repeat_interval)
{
this->m_repeat_delay = m_repeat_delay;
this->m_repeat_interval = m_repeat_interval;
return *this;
}
VirtualButton& VirtualButton::press_buffer(float duration)
{
this->m_press_buffer = duration;
return *this;
}
VirtualButton& VirtualButton::release_buffer(float duration)
{
this->m_release_buffer = duration;
return *this;
}
void VirtualButton::update()
{
m_down = false;
m_pressed = false;
m_released = false;
//Keys
for (int i = 0; i < m_keys_len; i++)
{
m_keys[i].update();
m_down = m_down || m_keys[i].down;
m_pressed = m_pressed || m_keys[i].pressed;
m_released = m_released || m_keys[i].released;
}
//Buttons
for (int i = 0; i < m_buttons_len; i++)
{
m_buttons[i].update();
m_down = m_down || m_buttons[i].down;
m_pressed = m_pressed || m_buttons[i].pressed;
m_released = m_released || m_buttons[i].released;
}
//Axes
for (int i = 0; i < m_axes_len; i++)
{
m_axes[i].update();
m_down = m_down || m_axes[i].down;
m_pressed = m_pressed || m_axes[i].pressed;
m_released = m_released || m_axes[i].released;
}
//pressed?
if (m_pressed)
{
m_repeat_press_time = m_last_press_time = Time::elapsed;
}
else if (Time::elapsed - m_last_press_time <= m_press_buffer)
{
m_pressed = true;
}
else if (m_down && m_repeat_interval > 0 && Time::elapsed >= m_repeat_press_time + m_repeat_delay)
{
int prev = (int)((Time::previous_elapsed - m_repeat_press_time - m_repeat_delay) / m_repeat_interval);
int cur = (int)((Time::elapsed - m_repeat_press_time - m_repeat_delay) / m_repeat_interval);
m_pressed = prev < cur;
}
//released?
if (m_released)
m_last_release_time = Time::elapsed;
else
m_released = Time::elapsed - m_last_release_time <= m_release_buffer;
}
void VirtualButton::KeyNode::init(Key key)
{
this->key = key;
}
void VirtualButton::KeyNode::update()
{
down = Input::down(key);
pressed = Input::pressed(key);
released = Input::released(key);
}
void VirtualButton::ButtonNode::init(int gamepad_id, Button button)
{
this->gamepad_id = gamepad_id;
this->button = button;
}
void VirtualButton::ButtonNode::update()
{
down = Input::down(gamepad_id, button);
pressed = Input::pressed(gamepad_id, button);
released = Input::released(gamepad_id, button);
}
void VirtualButton::AxisNode::init(int gamepad_id, Axis axis, float threshold, bool greater_than)
{
this->gamepad_id = gamepad_id;
this->axis = axis;
this->threshold = threshold;
this->greater_than = greater_than;
}
void VirtualButton::AxisNode::update()
{
float curr = Input::state()->controllers[gamepad_id].axis[(int)axis];
float prev = Input::last_state()->controllers[gamepad_id].axis[(int)axis];
if (greater_than)
{
down = curr >= threshold;
pressed = down && prev < threshold;
released = !down && prev >= threshold;
}
else
{
down = curr <= threshold;
pressed = down && prev > threshold;
released = !down && prev <= threshold;
}
}

191
src/input/virtual_stick.cpp Normal file
View File

@ -0,0 +1,191 @@
#include <blah/input/virtual_stick.h>
#include <blah/core/time.h>
#include <blah/core/log.h>
using namespace Blah;
VirtualStick::VirtualStick()
{
this->m_i_deadzone = 0;
}
VirtualStick::VirtualStick(float iDeadzone)
{
this->m_i_deadzone = iDeadzone;
}
VirtualStick& VirtualStick::add_keys(Key left, Key right, Key up, Key down)
{
if (m_keys_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualStick Keys out of bounds!");
else
{
m_keys[m_keys_len].init(left, right, up, down);
m_keys_len++;
}
return *this;
}
VirtualStick& VirtualStick::add_buttons(int gamepad_id, Button left, Button right, Button up, Button down)
{
if (m_buttons_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualStick Buttons out of bounds!");
else
{
m_buttons[m_buttons_len].init(gamepad_id, left, right, up, down);
m_buttons_len++;
}
return *this;
}
VirtualStick& VirtualStick::add_axes(int gamepad_id, Axis horizontal, Axis vertical, float deadzone)
{
if (m_axes_len >= Input::max_virtual_nodes)
BLAH_ERROR("VirtualStick Axes out of bounds!");
else
{
m_axes[m_axes_len].init(gamepad_id, horizontal, vertical, deadzone);
m_axes_len++;
}
return *this;
}
VirtualStick& VirtualStick::repeat(float repeat_delay, float repeat_interval)
{
this->m_repeat_delay = repeat_delay;
this->m_repeat_interval = repeat_interval;
return *this;
}
VirtualStick& VirtualStick::press_buffer(float duration)
{
m_press_buffer = duration;
return *this;
}
VirtualStick& VirtualStick::release_buffer(float duration)
{
m_release_buffer = duration;
return *this;
}
void VirtualStick::update()
{
m_last_value = m_value;
m_value = Vec2::zero;
for (int i = 0; i < m_keys_len; i++)
{
m_keys[i].update();
if (m_value == Vec2::zero)
m_value = m_keys[i].value;
}
for (int i = 0; i < m_buttons_len; i++)
{
m_buttons[i].update();
if (m_value == Vec2::zero)
m_value = m_buttons[i].value;
}
for (int i = 0; i < m_axes_len; i++)
{
m_axes[i].update();
if (m_value == Vec2::zero)
m_value = m_axes[i].value;
}
//Valuei
m_last_value_i = m_value_i;
if (m_value.x > m_i_deadzone)
m_value_i.x = 1;
else if (m_value.x < -m_i_deadzone)
m_value_i.x = -1;
else
m_value_i.x = 0;
if (m_value.y > m_i_deadzone)
m_value_i.y = 1;
else if (m_value.y < -m_i_deadzone)
m_value_i.y = -1;
else
m_value_i.y = 0;
//pressed?
m_pressed = false;
if (m_value_i != Point::zero && m_last_value_i != m_value_i)
{
m_pressed = true;
m_last_press_time = m_repeat_press_time = Time::elapsed;
}
else if (m_value_i == m_last_value_i && m_value_i != Point::zero)
{
if (Time::elapsed - m_last_press_time <= m_press_buffer)
m_pressed = true;
else if (m_repeat_interval > 0 && Time::elapsed >= m_repeat_press_time + m_repeat_delay)
{
int prev = (int)((Time::previous_elapsed - m_repeat_press_time - m_repeat_delay) / m_repeat_interval);
int cur = (int)((Time::elapsed - m_repeat_press_time - m_repeat_delay) / m_repeat_interval);
m_pressed = prev < cur;
}
}
//released?
if (m_last_value_i != Point::zero && m_value_i != m_last_value_i)
{
m_released = true;
m_last_release_time = Time::elapsed;
}
else if (Time::elapsed - m_last_release_time <= m_release_buffer)
m_released = true;
else
m_released = false;
}
void VirtualStick::KeysNode::init(Key left, Key right, Key up, Key down)
{
this->left = left;
this->right = right;
this->up = up;
this->down = down;
}
void VirtualStick::KeysNode::update()
{
value.x = Input::axis_check(value.x, left, right);
value.y = Input::axis_check(value.y, up, down);
}
void VirtualStick::ButtonsNode::init(int gamepad_id, Button left, Button right, Button up, Button down)
{
this->gamepad_id = gamepad_id;
this->left = left;
this->right = right;
this->up = up;
this->down = down;
}
void VirtualStick::ButtonsNode::update()
{
value.x = Input::axis_check(value.x, gamepad_id, left, right);
value.y = Input::axis_check(value.y, gamepad_id, up, down);
}
void VirtualStick::AxesNode::init(int gamepad_id, Axis horizontal, Axis vertical, float deadzone)
{
this->gamepad_id = gamepad_id;
this->horizontal = horizontal;
this->vertical = vertical;
this->deadzone = deadzone;
}
void VirtualStick::AxesNode::update()
{
value.x = Input::axis_check(gamepad_id, horizontal);
value.y = Input::axis_check(gamepad_id, vertical);
if (value.length() < deadzone)
value = Vec2::zero;
}