mirror of
https://github.com/imaginaryPineapple/OpenRayman.git
synced 2024-10-19 22:47:37 -04:00
Add SDL_GameController support
This commit is contained in:
parent
1ed79727cb
commit
c277fb918d
|
@ -49,9 +49,9 @@ namespace openrayman
|
|||
// Provide more complete info for the user.
|
||||
std::stringstream title;
|
||||
title << "OpenRayman " << openrayman::version << " "
|
||||
<< (this_platform == platform::windows ? "Win32" : "Linux")
|
||||
<< " (OpenGL " << gl_major << "." << gl_minor << ")"
|
||||
<< " (Game \"" << load_game << "\")";
|
||||
<< (this_platform == platform::windows ? "Win32" : "Linux")
|
||||
<< " (OpenGL " << gl_major << "." << gl_minor << ")"
|
||||
<< " (Game \"" << load_game << "\")";
|
||||
m_window.set_title(title.str());
|
||||
|
||||
std::vector<std::uint8_t> icon_data;
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace openrayman
|
|||
{
|
||||
m_input.stick_x = m_input.stick_y = m_input.buttons = m_input.commands = 0;
|
||||
poll_keyboard();
|
||||
poll_game_controller();
|
||||
return m_input;
|
||||
}
|
||||
|
||||
|
@ -32,8 +33,6 @@ namespace openrayman
|
|||
// Keyboard
|
||||
// This is not 100% accurate to the original PC version because
|
||||
// the N64 version is not the same as the PC version
|
||||
// TODO: rebindable keyboard controls
|
||||
// and controller...
|
||||
|
||||
// Control stick
|
||||
// This simulates a slower walk done by the control stick
|
||||
|
@ -41,14 +40,23 @@ namespace openrayman
|
|||
// TODO: Is half (64) accurate?!?!
|
||||
int walk_strength = keyboard_state[SDL_SCANCODE_LSHIFT] ? 64 : 127;
|
||||
|
||||
int new_stick_x = m_input.stick_x;
|
||||
int new_stick_y = m_input.stick_y;
|
||||
|
||||
if(keyboard_state[SDL_SCANCODE_LEFT])
|
||||
m_input.stick_x -= walk_strength;
|
||||
new_stick_x -= walk_strength;
|
||||
if(keyboard_state[SDL_SCANCODE_RIGHT])
|
||||
m_input.stick_x += walk_strength;
|
||||
new_stick_x += walk_strength;
|
||||
if(keyboard_state[SDL_SCANCODE_UP])
|
||||
m_input.stick_y -= walk_strength;
|
||||
new_stick_y -= walk_strength;
|
||||
if(keyboard_state[SDL_SCANCODE_DOWN])
|
||||
m_input.stick_y += walk_strength;
|
||||
new_stick_y += walk_strength;
|
||||
|
||||
new_stick_x = std::min(127, std::max(-127, new_stick_x));
|
||||
new_stick_y = std::min(127, std::max(-127, new_stick_y));
|
||||
|
||||
m_input.stick_x = new_stick_x;
|
||||
m_input.stick_y = new_stick_y;
|
||||
|
||||
// Front buttons
|
||||
if(keyboard_state[SDL_SCANCODE_SPACE])
|
||||
|
@ -82,4 +90,63 @@ namespace openrayman
|
|||
if(keyboard_state[SDL_SCANCODE_F11])
|
||||
m_input.commands |= input_command::toggle_fullscreen;
|
||||
}
|
||||
|
||||
void standalone_input_provider::poll_game_controller()
|
||||
{
|
||||
// Game controller
|
||||
// Again, not 100% accurate to the original PC version because
|
||||
// the N64 version is not the same as the PC version and the original game
|
||||
// was not meant to be played with Xbox controllers and frankly, the original
|
||||
// layout is shit and doesn't work most of the time (dinput)
|
||||
|
||||
for(const std::pair<int, SDL_GameController*>& pair : m_game_controllers)
|
||||
{
|
||||
SDL_GameController* controller = pair.second;
|
||||
|
||||
// Control stick
|
||||
std::int16_t stick_x = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX) / 258;
|
||||
std::int16_t stick_y = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY) / 258;
|
||||
|
||||
int new_stick_x = m_input.stick_x;
|
||||
int new_stick_y = m_input.stick_y;
|
||||
|
||||
new_stick_x += stick_x;
|
||||
new_stick_y += stick_y;
|
||||
|
||||
new_stick_x = std::min(127, std::max(-127, new_stick_x));
|
||||
new_stick_y = std::min(127, std::max(-127, new_stick_y));
|
||||
|
||||
m_input.stick_x = new_stick_x;
|
||||
m_input.stick_y = new_stick_y;
|
||||
|
||||
// Front buttons
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A))
|
||||
m_input.buttons |= input_button::a;
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X))
|
||||
m_input.buttons |= input_button::b;
|
||||
|
||||
// Triggers
|
||||
if(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) > 20000 ||
|
||||
SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER))
|
||||
m_input.buttons |= input_button::z;
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_Y))
|
||||
m_input.buttons |= input_button::l;
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_B))
|
||||
m_input.buttons |= input_button::r;
|
||||
|
||||
// Start button
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_START))
|
||||
m_input.buttons |= input_button::start;
|
||||
|
||||
// C buttons
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
m_input.commands |= input_button::cbtn_left;
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
m_input.commands |= input_button::cbtn_right;
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP))
|
||||
m_input.commands |= input_button::cbtn_up;
|
||||
if(SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN))
|
||||
m_input.commands |= input_button::cbtn_down;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <input/input_provider.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace openrayman
|
||||
{
|
||||
|
@ -12,6 +13,7 @@ namespace openrayman
|
|||
// Sources are GLFW and libgcadapter.
|
||||
class standalone_input_provider : public input_provider
|
||||
{
|
||||
friend class sdl_window;
|
||||
public:
|
||||
standalone_input_provider(SDL_Window* window);
|
||||
~standalone_input_provider();
|
||||
|
@ -20,8 +22,10 @@ public:
|
|||
const input_state& poll() override;
|
||||
private:
|
||||
void poll_keyboard();
|
||||
void poll_game_controller();
|
||||
input_state m_input;
|
||||
SDL_Window* m_window;
|
||||
std::unordered_map<int, SDL_GameController*> m_game_controllers;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -105,6 +105,26 @@ namespace openrayman
|
|||
case SDL_QUIT:
|
||||
m_wants_close = true;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
{
|
||||
SDL_GameController* ctrl = SDL_GameControllerOpen(event.cdevice.which);
|
||||
if(ctrl)
|
||||
{
|
||||
SDL_Joystick* joy = SDL_GameControllerGetJoystick(ctrl);
|
||||
int id = SDL_JoystickInstanceID(joy);
|
||||
m_input_provider.m_game_controllers[id] = ctrl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
if(m_input_provider.m_game_controllers.count(event.cdevice.which) > 0)
|
||||
{
|
||||
SDL_GameControllerClose(m_input_provider.m_game_controllers[event.cdevice.which]);
|
||||
m_input_provider.m_game_controllers.erase(event.cdevice.which);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue