Browse Source

input: start splitting keyboard, mouse etc. objects

legacy
Sam Hocevar 5 years ago
parent
commit
c9f75a6c3f
6 changed files with 196 additions and 219 deletions
  1. +3
    -3
      doc/tutorial/07_input.cpp
  2. +6
    -7
      src/ui/d3d9-input.cpp
  3. +23
    -17
      src/ui/input.cpp
  4. +160
    -189
      src/ui/input.h
  5. +1
    -2
      src/ui/sdl-input.cpp
  6. +3
    -1
      src/ui/sdl-input.h

+ 3
- 3
doc/tutorial/07_input.cpp View File

@@ -76,7 +76,7 @@ public:
m_autorot = !m_autorot;

/* Handle joystick */
auto joystick = InputDevice::Get(g_name_joystick(1).c_str());
auto joystick = input::joystick(0);
if ((bool)joystick)
{
if (lol::abs(joystick->axis(input::axis::LeftY)) > 0.2f)
@@ -91,8 +91,8 @@ public:
if (mouse->button(input::button::BTN_Left))
{
mouse->capture(true);
m_pitch_angle -= mouse->axis(input::axis::MoveX) * seconds * 0.1f;
m_yaw_angle += mouse->axis(input::axis::MoveY) * seconds * 0.1f;
m_pitch_angle += mouse->axis(input::axis::MoveY) * seconds * 0.1f;
m_yaw_angle += mouse->axis(input::axis::MoveX) * seconds * 0.1f;
}
else
{


+ 6
- 7
src/ui/d3d9-input.cpp View File

@@ -18,6 +18,8 @@
# include <xinput.h>
#endif

#include <memory>

#include <lol/engine-internal.h>

#include "ui/d3d9-input.h"
@@ -36,7 +38,7 @@ class D3d9InputData

private:
#if defined LOL_USE_XINPUT
array<int, InputDevice*> m_joysticks;
array<int, std::shared_ptr<input::device::joystick>> m_joysticks;
#endif // LOL_USE_XINPUT
};

@@ -53,8 +55,8 @@ D3d9Input::D3d9Input()
XINPUT_STATE state;
if (XInputGetState(i, &state) != ERROR_SUCCESS)
continue;
// TODO: we can put more friendly name here, such as LeftAxisX, ButtonX...
InputDevice* stick = new InputDevice(g_name_joystick(i + 1));
auto stick = input::joystick(i);

stick->internal_add_axis(input::axis::LeftX, "LeftX");
stick->internal_add_axis(input::axis::LeftY, "LeftY");
@@ -76,12 +78,9 @@ D3d9Input::D3d9Input()
D3d9Input::~D3d9Input()
{
#if defined LOL_USE_XINPUT
/* Unregister all the joysticks we added */
/* Unregister all the joysticks we added (FIXME: this code seems unnecessary) */
while (m_data->m_joysticks.count())
{
delete m_data->m_joysticks[0].m2;
m_data->m_joysticks.remove(0);
}
#endif
delete m_data;
}


+ 23
- 17
src/ui/input.cpp View File

@@ -22,14 +22,6 @@
namespace lol
{

const std::string g_name_mouse("mouse");
const std::string g_name_keyboard("keyboard");

std::string g_name_joystick(const uint64_t num)
{
return format("joystick%d", (int)num);
}

std::shared_ptr<input> input::get()
{
static auto instance = new input();
@@ -40,13 +32,13 @@ std::shared_ptr<input> input::get()
input::input()
{
// Create default keyboard device
m_keyboard = std::make_shared<InputDevice>(g_name_keyboard.c_str());
m_keyboard = std::make_shared<input::device::keyboard>("default keyboard");
/* Register all scancodes known to SDL (from the USB standard) */
#define _SC(id, str, name) m_keyboard->internal_add_key(input::key::SC_##name, #name);
#include "ui/keys.inc"

// Create default mouse device
m_mouse = std::make_shared<InputDevice>(g_name_mouse.c_str());
m_mouse = std::make_shared<input::device::mouse>("default mouse");
#define _BTN(id, name) m_mouse->internal_add_button(input::button::BTN_##name, #name);
#include "ui/buttons.inc" // FIXME: this will also add joystick buttons!
m_mouse->internal_add_axis(input::axis::X, "X");
@@ -58,6 +50,8 @@ input::input()
m_mouse->internal_add_axis(input::axis::ScreenMoveX, "ScreenMoveX");
m_mouse->internal_add_axis(input::axis::ScreenMoveY, "ScreenMoveY");
m_mouse->internal_add_axis(input::axis::Wheel, "Wheel");

// FIXME: there are no default joysticks and they will all have zero axes by default
}

// Lookup tables for scancode and key name lookups
@@ -97,26 +91,38 @@ input::key input::name_to_key(std::string const &name)
return it == g_name_to_key.end() ? key::SC_Unknown : it->second;
}

array<InputDevice*> InputDevice::devices;
std::shared_ptr<input::device::joystick> input::joystick(int n)
{
auto &joysticks = get()->m_joysticks;

if (joysticks.find(n) == joysticks.end())
joysticks[n] = std::make_shared<input::device::joystick>(format("joystick %d", n));

return joysticks[n];
}

//
// input::device
//

std::string InputDevice::text()
std::string input::device::text()
{
std::string ret = m_text;
m_text = "";
return ret;
}

bool InputDevice::capture_text()
bool input::device::capture_text()
{
return m_input_active;
}

void InputDevice::capture_text(bool status)
void input::device::capture_text(bool status)
{
m_input_active = status;
}

void InputDevice::internal_add_key(input::key key, const char* name)
void input::device::internal_add_key(input::key key, const char* name)
{
while ((int)key >= (int)m_key_names.size())
{
@@ -127,7 +133,7 @@ void InputDevice::internal_add_key(input::key key, const char* name)
m_key_names[(int)key] = name;
}

void InputDevice::internal_add_button(input::button button, const char* name)
void input::device::internal_add_button(input::button button, const char* name)
{
while ((int)button >= (int)m_button_names.size())
{
@@ -138,7 +144,7 @@ void InputDevice::internal_add_button(input::button button, const char* name)
m_button_names[(int)button] = name;
}

void InputDevice::internal_add_axis(input::axis axis, const char* name)
void input::device::internal_add_axis(input::axis axis, const char* name)
{
while ((int)axis >= (int)m_axis_names.size())
{


+ 160
- 189
src/ui/input.h View File

@@ -21,22 +21,9 @@
namespace lol
{

extern const std::string g_name_mouse;
extern const std::string g_name_keyboard;
extern std::string g_name_joystick(const uint64_t num);

class input
{
public:
static std::shared_ptr<input> get();

// Default devices

static std::shared_ptr<class InputDevice> keyboard() { return get()->m_keyboard; }
static std::shared_ptr<class InputDevice> mouse() { return get()->m_mouse; }

// Keyboard API

enum class key : uint16_t
{
#define _SC(id, str, name) SC_##name = id,
@@ -70,226 +57,210 @@ public:
RightShoulder,
};

static std::vector<key> const &all_keys();
static std::string const &key_to_name(key k);
static key name_to_key(std::string const &name);

// Joystick API

private:
input();

std::shared_ptr<class InputDevice> m_keyboard;
std::shared_ptr<class InputDevice> m_mouse;
};

class InputDevice
{
public:
InputDevice(std::string const &name)
: m_name(name),
m_input_active(false)
class device
{
devices.push_unique(this);
}
public:
device(std::string const &name) : m_name(name) {}

~InputDevice()
{
for (int i = 0; i < devices.count(); ++i)
class mouse;
class keyboard;
class joystick;

/** Gets the name of this input device */
const std::string& GetName() const
{
if (devices[i] == this)
{
devices.remove(i);
return;
}
return m_name;
}
}

/** Gets the name of this input device */
const std::string& GetName() const
{
return m_name;
}
//
// Bindings section
//

/** Gets the index of the corresponding key, needed to call GetKey */
int GetKeyIndex(std::string const &name) const
{
return GetItemIndex(name, m_key_names);
}
void bind(input::key key, uint16_t event);
void unbind(input::key key, uint16_t event);

/** Gets the index of the corresponding axis, needed to call GetAxis */
int GetAxisIndex(std::string const &name) const
{
return GetItemIndex(name, m_axis_names);
}
void bind(input::button button, uint16_t event);
void unbind(input::button button, uint16_t event);

//
// Bindings section
//
void bind(input::axis axis, uint16_t event);
void unbind(input::axis axis, uint16_t event);

void bind(input::key key, uint16_t event);
void unbind(input::key key, uint16_t event);
//
// Key, button etc. state
//

void bind(input::button button, uint16_t event);
void unbind(input::button button, uint16_t event);
// Get the current state of the given key
bool key(input::key key) const
{
return (size_t)key >= m_keys.size() ? false : m_keys[(int)key];
}

void bind(input::axis axis, uint16_t event);
void unbind(input::axis axis, uint16_t event);
bool key_released(input::key key) const
{
return m_released_keys.find(key) != m_released_keys.end();
}

//
// Key, button etc. state
//
bool key_pressed(input::key key) const
{
return m_pressed_keys.find(key) != m_pressed_keys.end();
}

// Get the current state of the given key
bool key(input::key key) const { return m_keys[(int)key]; }
// Get the current state of the given button
bool button(input::button button) const
{
return (size_t)button >= m_buttons.size() ? false : m_buttons[(int)button];
}

bool key_released(input::key key) const
{
return m_released_keys.find(key) != m_released_keys.end();
}
bool button_released(input::button button) const
{
return m_released_buttons.find(button) != m_released_buttons.end();
}

bool key_pressed(input::key key) const
{
return m_pressed_keys.find(key) != m_pressed_keys.end();
}
bool button_pressed(input::button button) const
{
return m_pressed_buttons.find(button) != m_pressed_buttons.end();
}

// Get the current state of the given button
bool button(input::button button) const { return m_buttons[(int)button]; }
// Get the current state of the given axis
float axis(input::axis axis) const
{
return (size_t)axis >= m_axes.size() ? 0.0f : m_axes[(int)axis];
}

bool button_released(input::button button) const
{
return m_released_buttons.find(button) != m_released_buttons.end();
}
bool axis_changed(input::axis axis) const
{
return m_changed_axes.find(axis) != m_changed_axes.end();
}

bool button_pressed(input::button button) const
{
return m_pressed_buttons.find(button) != m_pressed_buttons.end();
}
// TODO: axis sensitivity was removed

// Get the current state of the given axis
float axis(input::axis axis) const { return m_axes[(int)axis]; }
//
// Keyboard-specific section
//

bool axis_changed(input::axis axis) const
{
return m_changed_axes.find(axis) != m_changed_axes.end();
}
/** Get the names of all available keys on this device */
std::vector<std::string> const& key_names() const { return m_key_names; }

// TODO: axis sensitivity was removed
/** Get the current state of all keys */
std::vector<bool> const &keys() const { return m_keys; }

//
// Keyboard-specific section
//
/** Gets the latest contents of text input. */
std::string text();

/** Get the names of all available keys on this device */
std::vector<std::string> const& key_names() const { return m_key_names; }
bool capture_text();
void capture_text(bool status);

/** Get the current state of all keys */
std::vector<bool> const &keys() const { return m_keys; }
//
// Mouse-specific section
//

/** Gets the latest contents of text input. */
std::string text();
// Gets and sets whether the mouse cursor should be captured.
void capture(bool value) { m_capture = value; }
bool capture() const { return m_capture; }

bool capture_text();
void capture_text(bool status);
public:
/** Internal functions that allow to construct an input device
* dynamically, when the keys, axis and cursors are not known at
* compile time. */
void internal_add_key(input::key, char const *name);
void internal_add_button(input::button, char const *name);
void internal_add_axis(input::axis, char const *name);

//
// Mouse-specific section
//
/* Internal functions for the platform-specific drivers. */
void internal_begin_frame()
{
m_pressed_keys.clear();
m_released_keys.clear();
m_pressed_buttons.clear();
m_released_buttons.clear();
m_changed_axes.clear();
}

// Gets and sets whether the mouse cursor should be captured.
void capture(bool value) { m_capture = value; }
bool capture() const { return m_capture; }
void internal_set_key(input::key key, bool state)
{
if (m_keys[(int)key] != state)
(state ? m_pressed_keys : m_released_keys).insert(key);
m_keys[(int)key] = state;
}

/** Gets an input device by its name */
static InputDevice* Get(std::string const &name)
{
for (int i = 0; i < devices.count(); ++i)
void internal_set_button(input::button button, bool state)
{
if (devices[i]->m_name == name)
return devices[i];
if (m_buttons[(int)button] != state)
(state ? m_pressed_buttons : m_released_buttons).insert(button);
m_buttons[(int)button] = state;
}
return nullptr;
}

public:
/** Internal functions that allow to construct an InputDevice
* dynamically, when the keys, axis and cursors are not known at
* compile time. */
void internal_add_key(input::key, char const *name);
void internal_add_button(input::button, char const *name);
void internal_add_axis(input::axis, char const *name);

/* Internal functions for the platform-specific drivers. */
void internal_begin_frame()
{
m_pressed_keys.clear();
m_released_keys.clear();
m_pressed_buttons.clear();
m_released_buttons.clear();
m_changed_axes.clear();
}

void internal_set_key(input::key key, bool state)
{
if (m_keys[(int)key] != state)
(state ? m_pressed_keys : m_released_keys).insert(key);
m_keys[(int)key] = state;
}
void internal_set_axis(input::axis axis, float value)
{
if (m_axes[(int)axis] != value)
m_changed_axes.insert(axis);
m_axes[(int)axis] = value;
}

void internal_set_button(input::button button, bool state)
{
if (m_buttons[(int)button] != state)
(state ? m_pressed_buttons : m_released_buttons).insert(button);
m_buttons[(int)button] = state;
}
void internal_add_text(std::string const &text)
{
m_text += text;
}

void internal_set_axis(input::axis axis, float value)
{
if (m_axes[(int)axis] != value)
m_changed_axes.insert(axis);
m_axes[(int)axis] = value;
}
protected:
std::string m_name;

void internal_add_text(std::string const &text)
{
m_text += text;
}
std::vector<std::string> m_key_names;
std::vector<std::string> m_button_names;
std::vector<std::string> m_axis_names;

protected:
// TODO: hide all of this in a InputDeviceData?
/** Key and button states (pressed/released) */
std::vector<bool> m_keys;
std::unordered_set<input::key> m_pressed_keys, m_released_keys;
std::vector<bool> m_buttons;
std::unordered_set<input::button> m_pressed_buttons, m_released_buttons;
std::vector<float> m_axes;
std::unordered_set<input::axis> m_changed_axes;

std::string m_name;
// Text input state
std::string m_text;
bool m_input_active = false;

std::vector<std::string> m_key_names;
std::vector<std::string> m_button_names;
std::vector<std::string> m_axis_names;
// Capture (for mouse devices)
bool m_capture = false;
};

/** Key and button states (pressed/released) */
std::vector<bool> m_keys;
std::unordered_set<input::key> m_pressed_keys, m_released_keys;
std::vector<bool> m_buttons;
std::unordered_set<input::button> m_pressed_buttons, m_released_buttons;
std::vector<float> m_axes;
std::unordered_set<input::axis> m_changed_axes;
// Default devices

// Text input state
std::string m_text;
bool m_input_active;
static std::shared_ptr<class device::keyboard> keyboard() { return get()->m_keyboard; }
static std::shared_ptr<class device::mouse> mouse() { return get()->m_mouse; }
static std::shared_ptr<class device::joystick> joystick(int n);

// Capture (for mouse devices)
bool m_capture = false;
static std::vector<key> const &all_keys();
static std::string const &key_to_name(key k);
static key name_to_key(std::string const &name);

private:
static array<InputDevice*> devices;
input();

template <typename... T>
int GetItemIndex(std::string const &name, std::vector<std::string, T...> const& a) const
{
for (size_t i = 0; i < a.size(); ++i)
if (a[i] == name)
return (int)i;
return -1;
}
static std::shared_ptr<input> get();

std::shared_ptr<device::keyboard> m_keyboard;
std::shared_ptr<device::mouse> m_mouse;
std::map<int, std::shared_ptr<device::joystick>> m_joysticks;
};

class input::device::mouse : public input::device
{
public:
mouse(std::string const &name) : input::device(name) {}
};

class input::device::keyboard : public input::device
{
public:
keyboard(std::string const &name) : input::device(name) {}
};

class input::device::joystick : public input::device
{
public:
joystick(std::string const &name) : input::device(name) {}
};

} /* namespace lol */


+ 1
- 2
src/ui/sdl-input.cpp View File

@@ -83,7 +83,7 @@ SdlInput::SdlInput(int app_w, int app_h, int screen_w, int screen_h)
continue;
}

InputDevice* stick = new InputDevice(g_name_joystick(i + 1));
auto stick = input::joystick(i);
for (int j = 0; j < SDL_JoystickNumAxes(sdlstick); ++j)
stick->internal_add_axis((input::axis)(j + 1), format("Axis%d", j + 1).c_str());
for (int j = 0; j < SDL_JoystickNumButtons(sdlstick); ++j)
@@ -103,7 +103,6 @@ SdlInput::~SdlInput()
while (m_joysticks.count())
{
SDL_JoystickClose(m_joysticks[0].m1);
delete m_joysticks[0].m2;
m_joysticks.remove(0);
}
#endif


+ 3
- 1
src/ui/sdl-input.h View File

@@ -27,6 +27,8 @@
# endif
#endif

#include <memory>

namespace lol
{

@@ -46,7 +48,7 @@ protected:
private:
void tick(float seconds);

array<SDL_Joystick *, class InputDevice *> m_joysticks;
array<SDL_Joystick *, std::shared_ptr<class input::device::joystick>> m_joysticks;

vec2 m_app;
vec2 m_screen;


Loading…
Cancel
Save