mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-12-01 03:47:07 -05:00
SDL2: Added gamepad support.
This commit is contained in:
parent
504af5216b
commit
73a227cefd
10 changed files with 372 additions and 49 deletions
|
@ -1111,7 +1111,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
|
||||||
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
|
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
|
||||||
|
|
||||||
// Update camera.
|
// Update camera.
|
||||||
cameraUpdate(deltaTime, mouseState.m_mx, mouseState.m_my, !!mouseState.m_buttons[entry::MouseButton::Right]);
|
cameraUpdate(deltaTime, mouseState);
|
||||||
cameraGetViewMtx(viewState.m_view);
|
cameraGetViewMtx(viewState.m_view);
|
||||||
|
|
||||||
static float lightTimeAccumulator = 0.0f;
|
static float lightTimeAccumulator = 0.0f;
|
||||||
|
|
|
@ -2197,7 +2197,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
|
||||||
s_uniforms.m_time = time;
|
s_uniforms.m_time = time;
|
||||||
|
|
||||||
// Update camera.
|
// Update camera.
|
||||||
cameraUpdate(deltaTime, mouseState.m_mx, mouseState.m_my, !!mouseState.m_buttons[entry::MouseButton::Right]);
|
cameraUpdate(deltaTime, mouseState);
|
||||||
|
|
||||||
// Set view and projection matrix for view 0.
|
// Set view and projection matrix for view 0.
|
||||||
const bgfx::HMD* hmd = bgfx::getHMD();
|
const bgfx::HMD* hmd = bgfx::getHMD();
|
||||||
|
|
|
@ -2239,7 +2239,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
|
||||||
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
|
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
|
||||||
|
|
||||||
// Update camera.
|
// Update camera.
|
||||||
cameraUpdate(deltaTime, mouseState.m_mx, mouseState.m_my, !!mouseState.m_buttons[entry::MouseButton::Right]);
|
cameraUpdate(deltaTime, mouseState);
|
||||||
|
|
||||||
// Update view mtx.
|
// Update view mtx.
|
||||||
cameraGetViewMtx(viewState.m_view);
|
cameraGetViewMtx(viewState.m_view);
|
||||||
|
|
|
@ -439,7 +439,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
|
||||||
imguiEndFrame();
|
imguiEndFrame();
|
||||||
|
|
||||||
// Update camera.
|
// Update camera.
|
||||||
cameraUpdate(deltaTime, mouseState.m_mx, mouseState.m_my, !!mouseState.m_buttons[entry::MouseButton::Right]);
|
cameraUpdate(deltaTime, mouseState);
|
||||||
cameraGetViewMtx(view);
|
cameraGetViewMtx(view);
|
||||||
|
|
||||||
// Setup views
|
// Setup views
|
||||||
|
|
|
@ -17,7 +17,6 @@ extern "C" int _main_(int _argc, char** _argv);
|
||||||
|
|
||||||
namespace entry
|
namespace entry
|
||||||
{
|
{
|
||||||
const uint16_t WindowHandle::invalidHandle = UINT16_MAX;
|
|
||||||
static uint32_t s_debug = BGFX_DEBUG_NONE;
|
static uint32_t s_debug = BGFX_DEBUG_NONE;
|
||||||
static uint32_t s_reset = BGFX_RESET_NONE;
|
static uint32_t s_reset = BGFX_RESET_NONE;
|
||||||
static bool s_exit = false;
|
static bool s_exit = false;
|
||||||
|
@ -112,16 +111,17 @@ namespace entry
|
||||||
|
|
||||||
static const InputBinding s_bindings[] =
|
static const InputBinding s_bindings[] =
|
||||||
{
|
{
|
||||||
{ entry::Key::KeyQ, entry::Modifier::LeftCtrl, 1, cmd, "exit" },
|
{ entry::Key::KeyQ, entry::Modifier::LeftCtrl, 1, cmd, "exit" },
|
||||||
{ entry::Key::F1, entry::Modifier::None, 1, cmd, "graphics stats" },
|
{ entry::Key::F1, entry::Modifier::None, 1, cmd, "graphics stats" },
|
||||||
{ entry::Key::F1, entry::Modifier::LeftShift, 1, cmd, "graphics stats 0\ngraphics text 0" },
|
{ entry::Key::GamepadStart, entry::Modifier::None, 1, cmd, "graphics stats" },
|
||||||
{ entry::Key::F3, entry::Modifier::None, 1, cmd, "graphics wireframe" },
|
{ entry::Key::F1, entry::Modifier::LeftShift, 1, cmd, "graphics stats 0\ngraphics text 0" },
|
||||||
{ entry::Key::F4, entry::Modifier::None, 1, cmd, "graphics hmd" },
|
{ entry::Key::F3, entry::Modifier::None, 1, cmd, "graphics wireframe" },
|
||||||
{ entry::Key::F4, entry::Modifier::LeftShift, 1, cmd, "graphics hmdrecenter" },
|
{ entry::Key::F4, entry::Modifier::None, 1, cmd, "graphics hmd" },
|
||||||
{ entry::Key::F4, entry::Modifier::LeftCtrl, 1, cmd, "graphics hmddbg" },
|
{ entry::Key::F4, entry::Modifier::LeftShift, 1, cmd, "graphics hmdrecenter" },
|
||||||
{ entry::Key::F7, entry::Modifier::None, 1, cmd, "graphics vsync" },
|
{ entry::Key::F4, entry::Modifier::LeftCtrl, 1, cmd, "graphics hmddbg" },
|
||||||
{ entry::Key::F8, entry::Modifier::None, 1, cmd, "graphics msaa" },
|
{ entry::Key::F7, entry::Modifier::None, 1, cmd, "graphics vsync" },
|
||||||
{ entry::Key::Print, entry::Modifier::None, 1, cmd, "graphics screenshot" },
|
{ entry::Key::F8, entry::Modifier::None, 1, cmd, "graphics msaa" },
|
||||||
|
{ entry::Key::Print, entry::Modifier::None, 1, cmd, "graphics screenshot" },
|
||||||
|
|
||||||
INPUT_BINDING_END
|
INPUT_BINDING_END
|
||||||
};
|
};
|
||||||
|
@ -157,6 +157,16 @@ namespace entry
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* s_gamepadAxisName[GamepadAxis::Count] =
|
||||||
|
{
|
||||||
|
"LeftX",
|
||||||
|
"LeftY",
|
||||||
|
"LeftZ",
|
||||||
|
"RightX",
|
||||||
|
"RightY",
|
||||||
|
"RightZ",
|
||||||
|
};
|
||||||
|
|
||||||
bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse)
|
bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse)
|
||||||
{
|
{
|
||||||
s_debug = _debug;
|
s_debug = _debug;
|
||||||
|
@ -176,6 +186,20 @@ namespace entry
|
||||||
{
|
{
|
||||||
switch (ev->m_type)
|
switch (ev->m_type)
|
||||||
{
|
{
|
||||||
|
case Event::Axis:
|
||||||
|
{
|
||||||
|
const AxisEvent* axis = static_cast<const AxisEvent*>(ev);
|
||||||
|
inputSetGamepadAxis(axis->m_gamepad, axis->m_axis, axis->m_value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::Char:
|
||||||
|
{
|
||||||
|
const CharEvent* chev = static_cast<const CharEvent*>(ev);
|
||||||
|
inputChar(chev->m_len, chev->m_char);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Event::Exit:
|
case Event::Exit:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -219,13 +243,6 @@ namespace entry
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Event::Char:
|
|
||||||
{
|
|
||||||
const CharEvent* chev = static_cast<const CharEvent*>(ev);
|
|
||||||
inputChar(chev->m_len, chev->m_char);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Event::Size:
|
case Event::Size:
|
||||||
{
|
{
|
||||||
const SizeEvent* size = static_cast<const SizeEvent*>(ev);
|
const SizeEvent* size = static_cast<const SizeEvent*>(ev);
|
||||||
|
@ -302,6 +319,21 @@ namespace entry
|
||||||
|
|
||||||
switch (ev->m_type)
|
switch (ev->m_type)
|
||||||
{
|
{
|
||||||
|
case Event::Axis:
|
||||||
|
{
|
||||||
|
const AxisEvent* axis = static_cast<const AxisEvent*>(ev);
|
||||||
|
inputSetGamepadAxis(axis->m_gamepad, axis->m_axis, axis->m_value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Event::Char:
|
||||||
|
{
|
||||||
|
const CharEvent* chev = static_cast<const CharEvent*>(ev);
|
||||||
|
win.m_handle = chev->m_handle;
|
||||||
|
inputChar(chev->m_len, chev->m_char);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Event::Exit:
|
case Event::Exit:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -344,14 +376,6 @@ namespace entry
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Event::Char:
|
|
||||||
{
|
|
||||||
const CharEvent* chev = static_cast<const CharEvent*>(ev);
|
|
||||||
win.m_handle = chev->m_handle;
|
|
||||||
inputChar(chev->m_len, chev->m_char);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Event::Size:
|
case Event::Size:
|
||||||
{
|
{
|
||||||
const SizeEvent* size = static_cast<const SizeEvent*>(ev);
|
const SizeEvent* size = static_cast<const SizeEvent*>(ev);
|
||||||
|
|
|
@ -20,8 +20,11 @@ extern "C" int _main_(int _argc, char** _argv);
|
||||||
|
|
||||||
namespace entry
|
namespace entry
|
||||||
{
|
{
|
||||||
struct WindowHandle { uint16_t idx; static const uint16_t invalidHandle; };
|
struct WindowHandle { uint16_t idx; };
|
||||||
inline bool isValid(WindowHandle _handle) { return WindowHandle::invalidHandle != _handle.idx; }
|
inline bool isValid(WindowHandle _handle) { return UINT16_MAX != _handle.idx; }
|
||||||
|
|
||||||
|
struct GamepadHandle { uint16_t idx; };
|
||||||
|
inline bool isValid(GamepadHandle _handle) { return UINT16_MAX != _handle.idx; }
|
||||||
|
|
||||||
struct MouseButton
|
struct MouseButton
|
||||||
{
|
{
|
||||||
|
@ -36,6 +39,21 @@ namespace entry
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GamepadAxis
|
||||||
|
{
|
||||||
|
enum Enum
|
||||||
|
{
|
||||||
|
LeftX,
|
||||||
|
LeftY,
|
||||||
|
LeftZ,
|
||||||
|
RightX,
|
||||||
|
RightY,
|
||||||
|
RightZ,
|
||||||
|
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct Modifier
|
struct Modifier
|
||||||
{
|
{
|
||||||
enum Enum
|
enum Enum
|
||||||
|
@ -132,7 +150,22 @@ namespace entry
|
||||||
KeyY,
|
KeyY,
|
||||||
KeyZ,
|
KeyZ,
|
||||||
|
|
||||||
Count,
|
GamepadA,
|
||||||
|
GamepadB,
|
||||||
|
GamepadX,
|
||||||
|
GamepadY,
|
||||||
|
GamepadThumbL,
|
||||||
|
GamepadThumbR,
|
||||||
|
GamepadShoulderL,
|
||||||
|
GamepadShoulderR,
|
||||||
|
GamepadUp,
|
||||||
|
GamepadDown,
|
||||||
|
GamepadLeft,
|
||||||
|
GamepadRight,
|
||||||
|
GamepadBack,
|
||||||
|
GamepadStart,
|
||||||
|
|
||||||
|
Count
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,6 +188,16 @@ namespace entry
|
||||||
uint8_t m_buttons[entry::MouseButton::Count];
|
uint8_t m_buttons[entry::MouseButton::Count];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GamepadState
|
||||||
|
{
|
||||||
|
GamepadState()
|
||||||
|
{
|
||||||
|
memset(m_axis, 0, sizeof(m_axis) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t m_axis[entry::GamepadAxis::Count];
|
||||||
|
};
|
||||||
|
|
||||||
bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse = NULL);
|
bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse = NULL);
|
||||||
|
|
||||||
bx::FileReaderI* getFileReader();
|
bx::FileReaderI* getFileReader();
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
# define ENTRY_CONFIG_MAX_WINDOWS 8
|
# define ENTRY_CONFIG_MAX_WINDOWS 8
|
||||||
#endif // ENTRY_CONFIG_MAX_WINDOWS
|
#endif // ENTRY_CONFIG_MAX_WINDOWS
|
||||||
|
|
||||||
|
#ifndef ENTRY_CONFIG_MAX_GAMEPADS
|
||||||
|
# define ENTRY_CONFIG_MAX_GAMEPADS 4
|
||||||
|
#endif // ENTRY_CONFIG_MAX_GAMEPADS
|
||||||
|
|
||||||
#if !defined(ENTRY_DEFAULT_WIDTH) && !defined(ENTRY_DEFAULT_HEIGHT)
|
#if !defined(ENTRY_DEFAULT_WIDTH) && !defined(ENTRY_DEFAULT_HEIGHT)
|
||||||
# define ENTRY_DEFAULT_WIDTH 1280
|
# define ENTRY_DEFAULT_WIDTH 1280
|
||||||
# define ENTRY_DEFAULT_HEIGHT 720
|
# define ENTRY_DEFAULT_HEIGHT 720
|
||||||
|
@ -44,9 +48,10 @@ namespace entry
|
||||||
{
|
{
|
||||||
enum Enum
|
enum Enum
|
||||||
{
|
{
|
||||||
|
Axis,
|
||||||
|
Char,
|
||||||
Exit,
|
Exit,
|
||||||
Key,
|
Key,
|
||||||
Char,
|
|
||||||
Mouse,
|
Mouse,
|
||||||
Size,
|
Size,
|
||||||
Window,
|
Window,
|
||||||
|
@ -68,13 +73,13 @@ namespace entry
|
||||||
WindowHandle m_handle;
|
WindowHandle m_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KeyEvent : public Event
|
struct AxisEvent : public Event
|
||||||
{
|
{
|
||||||
ENTRY_IMPLEMENT_EVENT(KeyEvent, Event::Key);
|
ENTRY_IMPLEMENT_EVENT(AxisEvent, Event::Axis);
|
||||||
|
|
||||||
Key::Enum m_key;
|
GamepadAxis::Enum m_axis;
|
||||||
uint8_t m_modifiers;
|
int32_t m_value;
|
||||||
bool m_down;
|
GamepadHandle m_gamepad;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CharEvent : public Event
|
struct CharEvent : public Event
|
||||||
|
@ -97,6 +102,15 @@ namespace entry
|
||||||
bool m_move;
|
bool m_move;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct KeyEvent : public Event
|
||||||
|
{
|
||||||
|
ENTRY_IMPLEMENT_EVENT(KeyEvent, Event::Key);
|
||||||
|
|
||||||
|
Key::Enum m_key;
|
||||||
|
uint8_t m_modifiers;
|
||||||
|
bool m_down;
|
||||||
|
};
|
||||||
|
|
||||||
struct SizeEvent : public Event
|
struct SizeEvent : public Event
|
||||||
{
|
{
|
||||||
ENTRY_IMPLEMENT_EVENT(SizeEvent, Event::Size);
|
ENTRY_IMPLEMENT_EVENT(SizeEvent, Event::Size);
|
||||||
|
@ -119,6 +133,23 @@ namespace entry
|
||||||
class EventQueue
|
class EventQueue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void postAxisEvent(WindowHandle _handle, GamepadHandle _gamepad, GamepadAxis::Enum _axis, int32_t _value)
|
||||||
|
{
|
||||||
|
AxisEvent* ev = new AxisEvent(_handle);
|
||||||
|
ev->m_gamepad = _gamepad;
|
||||||
|
ev->m_axis = _axis;
|
||||||
|
ev->m_value = _value;
|
||||||
|
m_queue.push(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void postCharEvent(WindowHandle _handle, uint8_t _len, const uint8_t _char[4])
|
||||||
|
{
|
||||||
|
CharEvent* ev = new CharEvent(_handle);
|
||||||
|
ev->m_len = _len;
|
||||||
|
memcpy(ev->m_char, _char, 4);
|
||||||
|
m_queue.push(ev);
|
||||||
|
}
|
||||||
|
|
||||||
void postExitEvent()
|
void postExitEvent()
|
||||||
{
|
{
|
||||||
Event* ev = new Event(Event::Exit);
|
Event* ev = new Event(Event::Exit);
|
||||||
|
@ -134,14 +165,6 @@ namespace entry
|
||||||
m_queue.push(ev);
|
m_queue.push(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void postCharEvent(WindowHandle _handle, uint8_t _len, const uint8_t _char[4])
|
|
||||||
{
|
|
||||||
CharEvent* ev = new CharEvent(_handle);
|
|
||||||
ev->m_len = _len;
|
|
||||||
memcpy(ev->m_char, _char, 4);
|
|
||||||
m_queue.push(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void postMouseEvent(WindowHandle _handle, int32_t _mx, int32_t _my, int32_t _mz)
|
void postMouseEvent(WindowHandle _handle, int32_t _mx, int32_t _my, int32_t _mz)
|
||||||
{
|
{
|
||||||
MouseEvent* ev = new MouseEvent(_handle);
|
MouseEvent* ev = new MouseEvent(_handle);
|
||||||
|
|
|
@ -49,6 +49,80 @@ namespace entry
|
||||||
return (Key::Enum)s_translateKey[_sdl&0xff];
|
return (Key::Enum)s_translateKey[_sdl&0xff];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t s_translateGamepad[256];
|
||||||
|
|
||||||
|
static void initTranslateGamepad(uint8_t _sdl, Key::Enum _button)
|
||||||
|
{
|
||||||
|
s_translateGamepad[_sdl] = _button;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Key::Enum translateGamepad(uint8_t _sdl)
|
||||||
|
{
|
||||||
|
return Key::Enum(s_translateGamepad[_sdl]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t s_translateGamepadAxis[256];
|
||||||
|
|
||||||
|
static void initTranslateGamepadAxis(uint8_t _sdl, GamepadAxis::Enum _axis)
|
||||||
|
{
|
||||||
|
s_translateGamepadAxis[_sdl] = uint8_t(_axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GamepadAxis::Enum translateGamepadAxis(uint8_t _sdl)
|
||||||
|
{
|
||||||
|
return GamepadAxis::Enum(s_translateGamepadAxis[_sdl]);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GamepadSDL
|
||||||
|
{
|
||||||
|
GamepadSDL()
|
||||||
|
: m_controller(NULL)
|
||||||
|
, m_jid(INT32_MAX)
|
||||||
|
{
|
||||||
|
memset(m_value, 0, sizeof(m_value) );
|
||||||
|
|
||||||
|
// Deadzone values from xinput.h
|
||||||
|
m_deadzone[GamepadAxis::LeftX ] =
|
||||||
|
m_deadzone[GamepadAxis::LeftY ] = 7849;
|
||||||
|
m_deadzone[GamepadAxis::RightX] =
|
||||||
|
m_deadzone[GamepadAxis::RightY] = 8689;
|
||||||
|
m_deadzone[GamepadAxis::LeftZ ] =
|
||||||
|
m_deadzone[GamepadAxis::RightZ] = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
void create(int32_t _jid)
|
||||||
|
{
|
||||||
|
m_controller = SDL_GameControllerOpen(_jid);
|
||||||
|
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(m_controller);
|
||||||
|
m_jid = SDL_JoystickInstanceID(joystick);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
SDL_GameControllerClose(m_controller);
|
||||||
|
m_controller = NULL;
|
||||||
|
m_jid = INT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filter(GamepadAxis::Enum _axis, int32_t* _value)
|
||||||
|
{
|
||||||
|
const int32_t old = m_value[_axis];
|
||||||
|
const int32_t deadzone = m_deadzone[_axis];
|
||||||
|
int32_t value = *_value;
|
||||||
|
value = value > deadzone || value < -deadzone ? value : 0;
|
||||||
|
m_value[_axis] = value;
|
||||||
|
*_value = value;
|
||||||
|
return old != value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t m_value[GamepadAxis::Count];
|
||||||
|
int32_t m_deadzone[GamepadAxis::Count];
|
||||||
|
|
||||||
|
SDL_GameController* m_controller;
|
||||||
|
// SDL_Haptic* m_haptic;
|
||||||
|
SDL_JoystickID m_jid;
|
||||||
|
};
|
||||||
|
|
||||||
struct MainThreadEntry
|
struct MainThreadEntry
|
||||||
{
|
{
|
||||||
int m_argc;
|
int m_argc;
|
||||||
|
@ -213,6 +287,30 @@ namespace entry
|
||||||
initTranslateKey(SDL_SCANCODE_X, Key::KeyX);
|
initTranslateKey(SDL_SCANCODE_X, Key::KeyX);
|
||||||
initTranslateKey(SDL_SCANCODE_Y, Key::KeyY);
|
initTranslateKey(SDL_SCANCODE_Y, Key::KeyY);
|
||||||
initTranslateKey(SDL_SCANCODE_Z, Key::KeyZ);
|
initTranslateKey(SDL_SCANCODE_Z, Key::KeyZ);
|
||||||
|
|
||||||
|
memset(s_translateGamepad, uint8_t(Key::Count), sizeof(s_translateGamepad) );
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_A, Key::GamepadA);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_B, Key::GamepadB);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_X, Key::GamepadX);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_Y, Key::GamepadY);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_LEFTSTICK, Key::GamepadThumbL);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_RIGHTSTICK, Key::GamepadThumbR);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, Key::GamepadShoulderL);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, Key::GamepadShoulderR);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_DPAD_UP, Key::GamepadUp);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_DPAD_DOWN, Key::GamepadDown);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_DPAD_LEFT, Key::GamepadLeft);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_DPAD_RIGHT, Key::GamepadRight);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_BACK, Key::GamepadBack);
|
||||||
|
initTranslateGamepad(SDL_CONTROLLER_BUTTON_START, Key::GamepadStart);
|
||||||
|
|
||||||
|
memset(s_translateGamepadAxis, uint8_t(GamepadAxis::Count), sizeof(s_translateGamepadAxis) );
|
||||||
|
initTranslateGamepadAxis(SDL_CONTROLLER_AXIS_LEFTX, GamepadAxis::LeftX);
|
||||||
|
initTranslateGamepadAxis(SDL_CONTROLLER_AXIS_LEFTY, GamepadAxis::LeftY);
|
||||||
|
initTranslateGamepadAxis(SDL_CONTROLLER_AXIS_TRIGGERLEFT, GamepadAxis::LeftZ);
|
||||||
|
initTranslateGamepadAxis(SDL_CONTROLLER_AXIS_RIGHTX, GamepadAxis::RightX);
|
||||||
|
initTranslateGamepadAxis(SDL_CONTROLLER_AXIS_RIGHTY, GamepadAxis::RightY);
|
||||||
|
initTranslateGamepadAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT, GamepadAxis::RightZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(int _argc, char** _argv)
|
void run(int _argc, char** _argv)
|
||||||
|
@ -220,7 +318,10 @@ namespace entry
|
||||||
m_mte.m_argc = _argc;
|
m_mte.m_argc = _argc;
|
||||||
m_mte.m_argv = _argv;
|
m_mte.m_argv = _argv;
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(0
|
||||||
|
| SDL_INIT_VIDEO
|
||||||
|
| SDL_INIT_GAMECONTROLLER
|
||||||
|
);
|
||||||
|
|
||||||
m_windowAlloc.alloc();
|
m_windowAlloc.alloc();
|
||||||
m_window[0] = SDL_CreateWindow("bgfx"
|
m_window[0] = SDL_CreateWindow("bgfx"
|
||||||
|
@ -248,6 +349,12 @@ namespace entry
|
||||||
WindowHandle defaultWindow = { 0 };
|
WindowHandle defaultWindow = { 0 };
|
||||||
setWindowSize(defaultWindow, m_width, m_height, true);
|
setWindowSize(defaultWindow, m_width, m_height, true);
|
||||||
|
|
||||||
|
SDL_RWops* rw = SDL_RWFromFile("gamecontrollerdb.txt", "rb");
|
||||||
|
if (NULL != rw)
|
||||||
|
{
|
||||||
|
SDL_GameControllerAddMappingsFromRW(rw, 1);
|
||||||
|
}
|
||||||
|
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (!exit)
|
while (!exit)
|
||||||
|
@ -355,6 +462,68 @@ namespace entry
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_CONTROLLERAXISMOTION:
|
||||||
|
{
|
||||||
|
const SDL_ControllerAxisEvent& aev = event.caxis;
|
||||||
|
GamepadHandle handle = findGamepad(aev.which);
|
||||||
|
if (isValid(handle) )
|
||||||
|
{
|
||||||
|
GamepadAxis::Enum axis = translateGamepadAxis(aev.axis);
|
||||||
|
int32_t value = aev.value;
|
||||||
|
if (m_gamepad[handle.idx].filter(axis, &value) )
|
||||||
|
{
|
||||||
|
m_eventQueue.postAxisEvent(defaultWindow, handle, axis, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
|
case SDL_CONTROLLERBUTTONUP:
|
||||||
|
{
|
||||||
|
const SDL_ControllerButtonEvent& bev = event.cbutton;
|
||||||
|
GamepadHandle handle = findGamepad(bev.which);
|
||||||
|
if (isValid(handle) )
|
||||||
|
{
|
||||||
|
Key::Enum key = translateGamepad(bev.button);
|
||||||
|
if (Key::Count != key)
|
||||||
|
{
|
||||||
|
m_eventQueue.postKeyEvent(defaultWindow, key, 0, event.type == SDL_CONTROLLERBUTTONDOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
|
{
|
||||||
|
const SDL_ControllerDeviceEvent& cev = event.cdevice;
|
||||||
|
|
||||||
|
GamepadHandle handle = { m_gamepadAlloc.alloc() };
|
||||||
|
if (isValid(handle) )
|
||||||
|
{
|
||||||
|
m_gamepad[handle.idx].create(cev.which);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_CONTROLLERDEVICEREMAPPED:
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
|
{
|
||||||
|
const SDL_ControllerDeviceEvent& cev = event.cdevice;
|
||||||
|
GamepadHandle handle = findGamepad(cev.which);
|
||||||
|
if (isValid(handle) )
|
||||||
|
{
|
||||||
|
m_gamepad[handle.idx].destroy();
|
||||||
|
m_gamepadAlloc.free(handle.idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
const SDL_UserEvent& uev = event.user;
|
const SDL_UserEvent& uev = event.user;
|
||||||
|
@ -515,6 +684,22 @@ namespace entry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GamepadHandle findGamepad(SDL_JoystickID _jid)
|
||||||
|
{
|
||||||
|
for (uint32_t ii = 0, num = m_gamepadAlloc.getNumHandles(); ii < num; ++ii)
|
||||||
|
{
|
||||||
|
uint16_t idx = m_gamepadAlloc.getHandleAt(ii);
|
||||||
|
if (_jid == m_gamepad[idx].m_jid)
|
||||||
|
{
|
||||||
|
GamepadHandle handle = { idx };
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GamepadHandle invalid = { UINT16_MAX };
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
|
||||||
MainThreadEntry m_mte;
|
MainThreadEntry m_mte;
|
||||||
bx::Thread m_thread;
|
bx::Thread m_thread;
|
||||||
|
|
||||||
|
@ -525,6 +710,9 @@ namespace entry
|
||||||
SDL_Window* m_window[ENTRY_CONFIG_MAX_WINDOWS];
|
SDL_Window* m_window[ENTRY_CONFIG_MAX_WINDOWS];
|
||||||
uint32_t m_flags[ENTRY_CONFIG_MAX_WINDOWS];
|
uint32_t m_flags[ENTRY_CONFIG_MAX_WINDOWS];
|
||||||
|
|
||||||
|
bx::HandleAllocT<ENTRY_CONFIG_MAX_GAMEPADS> m_gamepadAlloc;
|
||||||
|
GamepadSDL m_gamepad[ENTRY_CONFIG_MAX_GAMEPADS];
|
||||||
|
|
||||||
uint32_t m_width;
|
uint32_t m_width;
|
||||||
uint32_t m_height;
|
uint32_t m_height;
|
||||||
float m_aspectRatio;
|
float m_aspectRatio;
|
||||||
|
|
|
@ -139,6 +139,31 @@ struct Keyboard
|
||||||
uint8_t m_char[256];
|
uint8_t m_char[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Gamepad
|
||||||
|
{
|
||||||
|
Gamepad()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
memset(m_axis, 0, sizeof(m_axis) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAxis(entry::GamepadAxis::Enum _axis, int32_t _value)
|
||||||
|
{
|
||||||
|
m_axis[_axis] = _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getAxis(entry::GamepadAxis::Enum _axis)
|
||||||
|
{
|
||||||
|
return m_axis[_axis];
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t m_axis[entry::GamepadAxis::Count];
|
||||||
|
};
|
||||||
|
|
||||||
struct Input
|
struct Input
|
||||||
{
|
{
|
||||||
Input()
|
Input()
|
||||||
|
@ -211,12 +236,17 @@ struct Input
|
||||||
{
|
{
|
||||||
m_mouse.reset();
|
m_mouse.reset();
|
||||||
m_keyboard.reset();
|
m_keyboard.reset();
|
||||||
|
for (uint32_t ii = 0; ii < BX_COUNTOF(m_gamepad); ++ii)
|
||||||
|
{
|
||||||
|
m_gamepad[ii].reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef stl::unordered_map<const char*, const InputBinding*> InputBindingMap;
|
typedef stl::unordered_map<const char*, const InputBinding*> InputBindingMap;
|
||||||
InputBindingMap m_inputBindingsMap;
|
InputBindingMap m_inputBindingsMap;
|
||||||
Mouse m_mouse;
|
Mouse m_mouse;
|
||||||
Keyboard m_keyboard;
|
Keyboard m_keyboard;
|
||||||
|
Gamepad m_gamepad[ENTRY_CONFIG_MAX_GAMEPADS];
|
||||||
};
|
};
|
||||||
|
|
||||||
static Input s_input;
|
static Input s_input;
|
||||||
|
@ -301,3 +331,13 @@ void inputSetMouseLock(bool _lock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void inputSetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis, int32_t _value)
|
||||||
|
{
|
||||||
|
s_input.m_gamepad[_handle.idx].setAxis(_axis, _value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t inputGetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis)
|
||||||
|
{
|
||||||
|
return s_input.m_gamepad[_handle.idx].getAxis(_axis);
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#ifndef INPUT_H_HEADER_GUARD
|
#ifndef INPUT_H_HEADER_GUARD
|
||||||
#define INPUT_H_HEADER_GUARD
|
#define INPUT_H_HEADER_GUARD
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
typedef void (*InputBindingFn)(const void* _userData);
|
typedef void (*InputBindingFn)(const void* _userData);
|
||||||
|
@ -61,4 +60,10 @@ void inputGetMouse(float _mouse[3]);
|
||||||
///
|
///
|
||||||
bool inputIsMouseLocked();
|
bool inputIsMouseLocked();
|
||||||
|
|
||||||
|
///
|
||||||
|
void inputSetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis, int32_t _value);
|
||||||
|
|
||||||
|
///
|
||||||
|
int32_t inputGetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis);
|
||||||
|
|
||||||
#endif // INPUT_H_HEADER_GUARD
|
#endif // INPUT_H_HEADER_GUARD
|
||||||
|
|
Loading…
Reference in a new issue