simplifying input backend & input state update

This commit is contained in:
Noel Berry 2021-05-19 11:21:08 -07:00
parent b7e318e420
commit d7cef352a5
12 changed files with 293 additions and 331 deletions

View File

@ -53,7 +53,7 @@ namespace Blah
AppEventFn on_render;
// Callback when the user has requested the application close.
// For example, pressing the Close button
// For example, pressing the Close button, ALT+F4, etc
// By default this calls `App::exit()`
AppEventFn on_exit_request;

View File

@ -228,119 +228,6 @@ namespace Blah
constexpr int max_keyboard_keys = 512;
}
struct ControllerState
{
// The name of the gamepad, or NULL if not connected
const char* name;
// Whether this gamepad is connected
bool is_connected;
// Whether this gamepad is a standard Game Controller
bool is_gamepad;
// The total button count for this controller
int button_count;
// The total axis count for this controller
int axis_count;
// An array holding the pressed state of each button
bool pressed[Input::max_controller_buttons];
// An array holding the down state of each button
bool down[Input::max_controller_buttons];
// An array holding the released state of each button
bool released[Input::max_controller_buttons];
// An array holding the value state of each axis
float axis[Input::max_controller_axis];
// Timestamp, in milliseconds, since each button was last pressed
u64 button_timestamp[Input::max_controller_buttons];
// Timestamp, in milliseconds, since each axis last had a value set
u64 axis_timestamp[Input::max_controller_axis];
// The USB Vendor ID
u16 vendor;
// The USB Product ID
u16 product;
// the Product Version
u16 version;
};
struct KeyboardState
{
// whether a key was pressed this frame
bool pressed[Input::max_keyboard_keys];
// whether a key is currently held
bool down[Input::max_keyboard_keys];
// whether a key was released this frame
bool released[Input::max_keyboard_keys];
// the timestamp for the key being pressed
u64 timestamp[Input::max_keyboard_keys];
// current text input this frame
String text;
// Checks if the Left or Right Ctrl Key is down
bool ctrl();
// Checks if the Left or Right Shift Key is down
bool shift();
// Checks if the Left or Right Alt Key is down
bool alt();
};
struct MouseState
{
// whether a button was pressed this frame
bool pressed[Input::max_mouse_buttons];
// whether a button was held this frame
bool down[Input::max_mouse_buttons];
// whether a button was released this frame
bool released[Input::max_mouse_buttons];
// the timestamp for the button being pressed
u64 timestamp[Input::max_mouse_buttons];
// mouse position in screen coordinates
Vec2 screen_position;
// mouse position in pixel coordinates
Vec2 draw_position;
// mouse position on the window
Vec2 position;
// mouse wheel value this frame
Point wheel;
};
// An Input State, which stores the state for gamepads, keyboard, and mouse
struct InputState
{
// All the Gamepads. Note that not all gamepads are necessarily connected,
// and each one must be checked before use.
ControllerState controllers[Input::max_controllers];
// The current Keyboard state
KeyboardState keyboard;
// The current Mouse state
MouseState mouse;
};
// Keyboard Keys
struct Keys
{
@ -394,6 +281,152 @@ namespace Blah
};
using MouseButton = MouseButtons::Enumeration;
// Controller State
struct ControllerState
{
// The name of the gamepad, or NULL if not connected
String name;
// Whether this gamepad is connected
bool is_connected;
// Whether this gamepad is a standard Game Controller
bool is_gamepad;
// The total button count for this controller
int button_count;
// The total axis count for this controller
int axis_count;
// An array holding the pressed state of each button
bool pressed[Input::max_controller_buttons];
// An array holding the down state of each button
bool down[Input::max_controller_buttons];
// An array holding the released state of each button
bool released[Input::max_controller_buttons];
// An array holding the value state of each axis
float axis[Input::max_controller_axis];
// Timestamp, in milliseconds, since each button was last pressed
u64 button_timestamp[Input::max_controller_buttons];
// Timestamp, in milliseconds, since each axis last had a value set
u64 axis_timestamp[Input::max_controller_axis];
// The USB Vendor ID
u16 vendor;
// The USB Product ID
u16 product;
// the Product Version
u16 version;
// marks the controller as connected
void on_connect(const String& name, bool is_gamepad, int button_count, int axis_count, u16 vendor, u16 product, u16 version);
// marks the controller as disconnected
void on_disconnect();
// invokes a button press
void on_press(Button button);
// invokes a button release
void on_release(Button button);
// invokes an axis movement
void on_axis(Axis axis, float value);
};
// Keyboard State
struct KeyboardState
{
// whether a key was pressed this frame
bool pressed[Input::max_keyboard_keys];
// whether a key is currently held
bool down[Input::max_keyboard_keys];
// whether a key was released this frame
bool released[Input::max_keyboard_keys];
// the timestamp for the key being pressed
u64 timestamp[Input::max_keyboard_keys];
// current text input this frame
String text;
// Checks if the Left or Right Ctrl Key is down
bool ctrl();
// Checks if the Left or Right Shift Key is down
bool shift();
// Checks if the Left or Right Alt Key is down
bool alt();
// invokes a key press
void on_press(Key key);
// invokes a key release
void on_release(Key key);
};
// Mouse State
struct MouseState
{
// whether a button was pressed this frame
bool pressed[Input::max_mouse_buttons];
// whether a button was held this frame
bool down[Input::max_mouse_buttons];
// whether a button was released this frame
bool released[Input::max_mouse_buttons];
// the timestamp for the button being pressed
u64 timestamp[Input::max_mouse_buttons];
// mouse position in screen coordinates
Vec2 screen_position;
// mouse position in pixel coordinates
Vec2 draw_position;
// mouse position on the window
Vec2 position;
// mouse wheel value this frame
Point wheel;
// invokes a key press
void on_press(MouseButton button);
// invokes a mouse movement
void on_move(const Vec2& position, const Vec2& screen_position);
// invokes a key release
void on_release(MouseButton button);
};
// An Input State, which stores the state for gamepads, keyboard, and mouse
struct InputState
{
// All the Gamepads. Note that not all gamepads are necessarily connected,
// and each one must be checked before use.
ControllerState controllers[Input::max_controllers];
// The current Keyboard state
KeyboardState keyboard;
// The current Mouse state
MouseState mouse;
};
class ButtonBinding;
using ButtonBindingRef = Ref<ButtonBinding>;

View File

@ -40,9 +40,6 @@ namespace
void app_iterate()
{
// poll system events
PlatformBackend::frame();
// update at a fixed timerate
// TODO: allow a non-fixed step update?
{
@ -91,8 +88,10 @@ namespace
Time::previous_seconds = Time::seconds;
Time::seconds += Time::delta;
InputBackend::frame();
GraphicsBackend::frame();
InputBackend::update_state();
PlatformBackend::update(Input::state);
InputBackend::update_bindings();
GraphicsBackend::update();
if (app_config.on_update != nullptr)
app_config.on_update();

View File

@ -11,7 +11,6 @@ using namespace Blah;
namespace
{
InputState g_next_state;
InputState g_empty_state;
ControllerState g_empty_controller;
Vector<WeakRef<ButtonBinding>> g_buttons;
@ -25,57 +24,54 @@ InputState Blah::Input::last_state;
void InputBackend::init()
{
g_empty_controller.name = "Disconnected";
for (int i = 0; i < Blah::Input::max_controllers; i++)
for (int i = 0; i < Input::max_controllers; i++)
g_empty_state.controllers[i].name = g_empty_controller.name;
Input::last_state = g_empty_state;
Input::state = g_empty_state;
g_next_state = g_empty_state;
g_buttons.dispose();
g_axes.dispose();
g_sticks.dispose();
}
void InputBackend::frame()
void InputBackend::update_state()
{
// cycle states
Input::last_state = Input::state;
Input::state = g_next_state;
// copy state, clear pressed / released values
// update other state for next frame
for (int i = 0; i < Input::max_keyboard_keys; i++)
{
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;
g_next_state.keyboard.text.clear();
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;
}
}
Input::state.keyboard.pressed[i] = false;
Input::state.keyboard.released[i] = false;
}
// update bindings
for (int i = 0; i < Input::max_mouse_buttons; i++)
{
Input::state.mouse.pressed[i] = false;
Input::state.mouse.released[i] = false;
}
Input::state.mouse.wheel = Point::zero;
Input::state.keyboard.text.clear();
for (int i = 0; i < Input::max_controllers; i++)
{
ControllerState& controller = Input::state.controllers[i];
if (!controller.is_connected)
controller.name.clear();
for (int j = 0; j < Input::max_controller_buttons; j++)
{
controller.pressed[j] = false;
controller.released[j] = false;
}
}
}
void InputBackend::update_bindings()
{
for (int i = 0; i < g_buttons.size(); i++)
{
if (g_buttons[i].use_count() <= 0)
@ -116,133 +112,99 @@ void InputBackend::frame()
}
}
void InputBackend::on_mouse_move(float x, float y)
void MouseState::on_move(const Vec2& pos, const Vec2& screen_pos)
{
g_next_state.mouse.position.x = x;
g_next_state.mouse.position.y = y;
position = pos;
screen_position = screen_pos;
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;
draw_position.x = (position.x / (float)size.x) * draw.x;
draw_position.y = (position.y / (float)size.y) * draw.y;
}
void InputBackend::on_mouse_screen_move(float x, float y)
void MouseState::on_press(MouseButton button)
{
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)
if (button >= 0 && button < 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::ticks;
down[button] = true;
pressed[button] = true;
timestamp[button] = Time::ticks;
}
}
void InputBackend::on_mouse_up(MouseButton button)
void MouseState::on_release(MouseButton button)
{
int i = (int)button;
if (i >= 0 && i < Blah::Input::max_mouse_buttons)
if (button >= 0 && button < Input::max_mouse_buttons)
{
g_next_state.mouse.down[i] = false;
g_next_state.mouse.released[i] = true;
down[button] = false;
released[button] = true;
}
}
void InputBackend::on_key_down(Key key)
void KeyboardState::on_press(Key key)
{
int i = (int)key;
if (i >= 0 && i < Blah::Input::max_keyboard_keys)
if (key >= 0 && key < 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::ticks;
down[key] = true;
pressed[key] = true;
timestamp[key] = Time::ticks;
}
}
void InputBackend::on_mouse_wheel(Point wheel)
void KeyboardState::on_release(Key key)
{
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)
if (key >= 0 && key < Input::max_keyboard_keys)
{
g_next_state.keyboard.down[i] = false;
g_next_state.keyboard.released[i] = true;
down[key] = false;
released[key] = true;
}
}
void InputBackend::on_text_utf8(const char* text)
void ControllerState::on_connect(const String& name, bool is_gamepad, int button_count, int axis_count, u16 vendor, u16 product, u16 version)
{
g_next_state.keyboard.text += text;
*this = g_empty_controller;
this->name = name;
this->is_connected = true;
this->is_gamepad = is_gamepad;
this->button_count = button_count;
this->axis_count = axis_count;
this->vendor = vendor;
this->product = product;
this->version = version;
}
void InputBackend::on_controller_connect(int index, const char* name, int is_gamepad, int button_count, int axis_count, u16 vendor, u16 product, u16 version)
void ControllerState::on_disconnect()
{
if (index < Blah::Input::max_controllers)
*this = g_empty_controller;
}
void ControllerState::on_press(Button button)
{
if (button >= 0 && button < Input::max_controller_buttons && button < button_count)
{
ControllerState* controller = &(g_next_state.controllers[index]);
*controller = g_empty_controller;
controller->name = name;
controller->is_connected = true;
controller->is_gamepad = is_gamepad;
controller->button_count = button_count;
controller->axis_count = axis_count;
controller->vendor = vendor;
controller->product = product;
controller->version = version;
down[button] = true;
pressed[button] = true;
button_timestamp[button] = Time::ticks;
}
}
void InputBackend::on_controller_disconnect(int index)
void ControllerState::on_release(Button button)
{
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)
if (button >= 0 && button < Input::max_controller_buttons && button < button_count)
{
g_next_state.controllers[index].down[button] = true;
g_next_state.controllers[index].pressed[button] = true;
g_next_state.controllers[index].button_timestamp[button] = Time::ticks;
down[button] = false;
released[button] = true;
}
}
void InputBackend::on_button_up(int index, int button)
void ControllerState::on_axis(Axis index, float value)
{
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)
if (index >= 0 && index < Input::max_controller_axis && index < axis_count)
{
g_next_state.controllers[index].down[button] = false;
g_next_state.controllers[index].released[button] = true;
}
}
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::ticks;
axis[index] = value;
axis_timestamp[index] = Time::ticks;
}
}

View File

@ -27,7 +27,7 @@ namespace Blah
Renderer renderer();
// Called once per frame
void frame();
void update();
// Called before rendering begins
void before_render();

View File

@ -792,7 +792,7 @@ namespace Blah
return state.features;
}
void GraphicsBackend::frame()
void GraphicsBackend::update()
{
}

View File

@ -177,7 +177,7 @@ namespace Blah
return features;
}
void GraphicsBackend::frame() {}
void GraphicsBackend::update() {}
void GraphicsBackend::before_render() {}
void GraphicsBackend::after_render() {}

View File

@ -1159,7 +1159,7 @@ namespace Blah
return gl.features;
}
void GraphicsBackend::frame() {}
void GraphicsBackend::update() {}
void GraphicsBackend::before_render() {}
void GraphicsBackend::after_render() {}

View File

@ -5,50 +5,13 @@ namespace Blah
{
namespace InputBackend
{
// This is called internally by the app, and initializes the input state
// Initializes the Input State
void init();
// This is called internally by the app, and updates the input state
void frame();
// Steps the input state
void update_state();
// Call this when the Mouse moves relative to the window
void on_mouse_move(float x, float y);
// Call this when the Mouse moves relative to the screen
void on_mouse_screen_move(float x, float y);
// Call this when a Mouse Button is pressed
void on_mouse_down(MouseButton button);
// Call this when a Mouse Button is released
void on_mouse_up(MouseButton button);
// Call this when the Mouse Wheel moves
void on_mouse_wheel(Point wheel);
// Call this when a keyboard key is pressed
void on_key_down(Key key);
// Call this when a keyboard key is released
void on_key_up(Key key);
// Call this on Text Input
void on_text_utf8(const char* text);
// Call this when a Controller is connected. Note that the Name parameter must be kept valid
// until on_controller_disconnect is called with the same index.
void on_controller_connect(int index, const char* name, int isGamepad, int buttonCount, int axisCount, u16 vendor, u16 product, u16 version);
// Call this when a controller is disconnected
void on_controller_disconnect(int index);
// Call this when a controller button is pressed
void on_button_down(int index, int button);
// Call this when a controller button is released
void on_button_up(int index, int button);
/// Call this when a controller axis is moved
void on_axis_move(int index, int axis, float value);
// Updates bindings
void update_bindings();
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <blah/common.h>
#include <blah/filesystem.h>
#include <blah/input.h>
#include <blah/containers/vector.h>
namespace Blah
@ -25,7 +26,7 @@ namespace Blah
u64 ticks();
// Called every frame
void frame();
void update(InputState& state);
// Sleeps the current thread
void sleep(int milliseconds);

View File

@ -164,11 +164,6 @@ namespace Blah
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
#endif
}
// enable DirectX
else if (App::renderer() == Renderer::D3D11)
{
}
// create the window
@ -246,16 +241,18 @@ namespace Blah
// Macro defined by X11 conflicts with MouseButton enum
#undef None
void PlatformBackend::frame()
void PlatformBackend::update(InputState& state)
{
// update the mouse every frame
{
int winX, winY, x, y;
SDL_GetWindowPosition(window, &winX, &winY);
int win_x, win_y, x, y;
SDL_GetWindowPosition(window, &win_x, &win_y);
SDL_GetGlobalMouseState(&x, &y);
InputBackend::on_mouse_move((float)(x - winX), (float)(y - winY));
InputBackend::on_mouse_screen_move((float)x, (float)y);
state.mouse.on_move(
Vec2((float)(x - win_x), (float)(y - win_y)),
Vec2((float)x, (float)y));
}
// poll normal events
@ -278,7 +275,8 @@ namespace Blah
btn = MouseButton::Right;
else if (event.button.button == SDL_BUTTON_MIDDLE)
btn = MouseButton::Middle;
InputBackend::on_mouse_down(btn);
state.mouse.on_press(btn);
}
else if (event.type == SDL_MOUSEBUTTONUP)
{
@ -289,26 +287,27 @@ namespace Blah
btn = MouseButton::Right;
else if (event.button.button == SDL_BUTTON_MIDDLE)
btn = MouseButton::Middle;
InputBackend::on_mouse_up(btn);
state.mouse.on_release(btn);
}
else if (event.type == SDL_MOUSEWHEEL)
{
InputBackend::on_mouse_wheel(Point(event.wheel.x, event.wheel.y));
state.mouse.wheel = Point(event.wheel.x, event.wheel.y);
}
// Keyboard
else if (event.type == SDL_KEYDOWN)
{
if (event.key.repeat == 0)
InputBackend::on_key_down((Key)event.key.keysym.scancode);
state.keyboard.on_press((Key)event.key.keysym.scancode);
}
else if (event.type == SDL_KEYUP)
{
if (event.key.repeat == 0)
InputBackend::on_key_up((Key)event.key.keysym.scancode);
state.keyboard.on_release((Key)event.key.keysym.scancode);
}
else if (event.type == SDL_TEXTINPUT)
{
InputBackend::on_text_utf8(event.text.text);
state.keyboard.text += event.text.text;
}
// Joystick Controller
else if (event.type == SDL_JOYDEVICEADDED)
@ -325,7 +324,7 @@ namespace Blah
auto product = SDL_JoystickGetProduct(ptr);
auto version = SDL_JoystickGetProductVersion(ptr);
InputBackend::on_controller_connect(index, name, 0, button_count, axis_count, vendor, product, version);
state.controllers[index].on_connect(name, 0, button_count, axis_count, vendor, product, version);
}
}
else if (event.type == SDL_JOYDEVICEREMOVED)
@ -335,7 +334,7 @@ namespace Blah
{
if (SDL_IsGameController(index) == SDL_FALSE)
{
InputBackend::on_controller_disconnect(index);
state.controllers[index].on_disconnect();
SDL_JoystickClose(joysticks[index]);
}
}
@ -346,7 +345,7 @@ namespace Blah
if (index >= 0)
{
if (SDL_IsGameController(index) == SDL_FALSE)
InputBackend::on_button_down(index, event.jbutton.button);
state.controllers[index].on_press((Button)event.jbutton.button);
}
}
else if (event.type == SDL_JOYBUTTONUP)
@ -355,7 +354,7 @@ namespace Blah
if (index >= 0)
{
if (SDL_IsGameController(index) == SDL_FALSE)
InputBackend::on_button_up(index, event.jbutton.button);
state.controllers[index].on_release((Button)event.jbutton.button);
}
}
else if (event.type == SDL_JOYAXISMOTION)
@ -370,7 +369,7 @@ namespace Blah
value = event.jaxis.value / 32767.0f;
else
value = event.jaxis.value / 32768.0f;
InputBackend::on_axis_move(index, event.jaxis.axis, value);
state.controllers[index].on_axis((Axis)event.jaxis.axis, value);
}
}
}
@ -386,7 +385,7 @@ namespace Blah
auto product = SDL_GameControllerGetProduct(ptr);
auto version = SDL_GameControllerGetProductVersion(ptr);
InputBackend::on_controller_connect(index, name, 1, 15, 6, vendor, product, version);
state.controllers[index].on_connect(name, 1, 15, 6, vendor, product, version);
}
}
else if (event.type == SDL_CONTROLLERDEVICEREMOVED)
@ -394,7 +393,7 @@ namespace Blah
auto index = find_gamepad_index(event.cdevice.which);
if (index >= 0)
{
InputBackend::on_controller_disconnect(index);
state.controllers[index].on_disconnect();
SDL_GameControllerClose(gamepads[index]);
}
}
@ -403,11 +402,11 @@ namespace Blah
auto index = find_gamepad_index(event.cdevice.which);
if (index >= 0)
{
int button = (int)Button::None;
Button button = Button::None;
if (event.cbutton.button >= 0 && event.cbutton.button < 15)
button = event.cbutton.button; // NOTE: These map directly to Engine Buttons enum!
button = (Button)event.cbutton.button; // NOTE: These map directly to Engine Buttons enum!
InputBackend::on_button_down(index, button);
state.controllers[index].on_press(button);
}
}
else if (event.type == SDL_CONTROLLERBUTTONUP)
@ -415,11 +414,11 @@ namespace Blah
auto index = find_gamepad_index(event.cdevice.which);
if (index >= 0)
{
int button = (int)Button::None;
Button button = Button::None;
if (event.cbutton.button >= 0 && event.cbutton.button < 15)
button = event.cbutton.button; // NOTE: These map directly to Engine Buttons enum!
button = (Button)event.cbutton.button; // NOTE: These map directly to Engine Buttons enum!
InputBackend::on_button_up(index, button);
state.controllers[index].on_release(button);
}
}
else if (event.type == SDL_CONTROLLERAXISMOTION)
@ -427,9 +426,9 @@ namespace Blah
auto index = find_gamepad_index(event.cdevice.which);
if (index >= 0)
{
int axis = (int)Axis::None;
Axis axis = Axis::None;
if (event.caxis.axis >= 0 && event.caxis.axis < 6)
axis = event.caxis.axis; // NOTE: These map directly to Engine Axis enum!
axis = (Axis)event.caxis.axis; // NOTE: These map directly to Engine Axis enum!
float value;
if (event.caxis.value >= 0)
@ -437,7 +436,7 @@ namespace Blah
else
value = event.caxis.value / 32768.0f;
InputBackend::on_axis_move(index, axis, value);
state.controllers[index].on_axis(axis, value);
}
}
}

View File

@ -50,6 +50,9 @@ namespace Blah
RECT g_windowed_position;
bool g_fullscreen = false;
// current input state
InputState* g_input_state = nullptr;
// Converts Windows scancode to Blah key
Key scancode_to_key(WPARAM wParam, LPARAM lParam);
@ -329,35 +332,35 @@ namespace Blah
// Mouse Input
case WM_LBUTTONDOWN:
InputBackend::on_mouse_down(MouseButton::Left);
g_input_state->mouse.on_press(MouseButton::Left);
return 0;
case WM_LBUTTONUP:
InputBackend::on_mouse_up(MouseButton::Left);
g_input_state->mouse.on_release(MouseButton::Left);
return 0;
case WM_RBUTTONDOWN:
InputBackend::on_mouse_down(MouseButton::Right);
g_input_state->mouse.on_press(MouseButton::Right);
return 0;
case WM_RBUTTONUP:
InputBackend::on_mouse_up(MouseButton::Right);
g_input_state->mouse.on_release(MouseButton::Right);
return 0;
case WM_MBUTTONDOWN:
InputBackend::on_mouse_down(MouseButton::Middle);
g_input_state->mouse.on_press(MouseButton::Middle);
return 0;
case WM_MBUTTONUP:
InputBackend::on_mouse_up(MouseButton::Middle);
g_input_state->mouse.on_release(MouseButton::Middle);
return 0;
case WM_MOUSEMOVE:
InputBackend::on_mouse_move((float)((u16)lParam), (float)(lParam >> 16));
g_input_state->mouse.on_move(Vec2((float)((u16)lParam), (float)(lParam >> 16)), Vec2::zero);
return 0;
case WM_MOUSEWHEEL:
InputBackend::on_mouse_wheel(Point(0, GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA));
g_input_state->mouse.wheel = Point(0, GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA);
return 0;
// Text Input
@ -369,7 +372,7 @@ namespace Blah
String result;
result.append((u32)wParam);
if (result.length() > 0)
InputBackend::on_text_utf8(result.cstr());
g_input_state->keyboard.text += result.cstr();
return 0;
}
@ -382,7 +385,7 @@ namespace Blah
{
auto key = scancode_to_key(wParam, lParam);
if (key != Key::Unknown)
InputBackend::on_key_down(key);
g_input_state->keyboard.on_press(key);
}
return 0;
}
@ -392,7 +395,7 @@ namespace Blah
{
auto key = scancode_to_key(wParam, lParam);
if (key != Key::Unknown)
InputBackend::on_key_up(key);
g_input_state->keyboard.on_release(key);
return 0;
}
}
@ -400,8 +403,10 @@ namespace Blah
return DefWindowProc(hwnd, msg, wParam, lParam);
}
void PlatformBackend::frame()
void PlatformBackend::update(InputState& state)
{
g_input_state = &state;
// Catch & Dispatch Window Messages
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
@ -850,4 +855,4 @@ namespace Blah
}
}
#endif // BLAH_PLATFORM_WINDOWS
#endif // BLAH_PLATFORM_WIN32