Skip to content

Commit 1dd542a

Browse files
committed
Adding game controller support
Using the SDL2 library to use gamecontrollers/joypads as user input method.
1 parent df6bfb5 commit 1dd542a

File tree

4 files changed

+182
-2
lines changed

4 files changed

+182
-2
lines changed

Diff for: src/RenderLoop.cpp

+130
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ void RenderLoop::Run()
3030

3131
_projectMWrapper.DisplayInitialPreset();
3232

33+
_controller = _sdlRenderingWindow.FindController();
34+
3335
while (!_wantsToQuit)
3436
{
3537
limiter.TargetFPS(_projectMWrapper.TargetFPS());
@@ -49,6 +51,10 @@ void RenderLoop::Run()
4951
_projectMWrapper.UpdateRealFPS(limiter.FPS());
5052
}
5153

54+
//Close game controller
55+
SDL_GameControllerClose(_controller);
56+
_controller = nullptr;
57+
5258
notificationCenter.removeObserver(_quitNotificationObserver);
5359

5460
projectm_playlist_set_preset_switched_event_callback(_playlistHandle, nullptr, nullptr);
@@ -103,6 +109,26 @@ void RenderLoop::PollEvents()
103109

104110
break;
105111

112+
case SDL_CONTROLLERDEVICEADDED:
113+
ControllerAdd(event.cdevice.which);
114+
115+
break;
116+
117+
case SDL_CONTROLLERDEVICEREMOVED:
118+
ControllerRemove(event.cdevice.which);
119+
120+
break;
121+
122+
case SDL_CONTROLLERBUTTONDOWN:
123+
ControllerDownEvent(event);
124+
125+
break;
126+
127+
case SDL_CONTROLLERBUTTONUP:
128+
ControllerUpEvent(event);
129+
130+
break;
131+
106132
case SDL_QUIT:
107133
_wantsToQuit = true;
108134
break;
@@ -324,6 +350,110 @@ void RenderLoop::MouseUpEvent(const SDL_MouseButtonEvent& event)
324350
}
325351
}
326352

353+
void RenderLoop::ControllerAdd(const int id )
354+
{
355+
if (!_controller)
356+
{
357+
_controller = SDL_GameControllerOpen(id);
358+
}
359+
poco_debug(_logger, "Controller added!");
360+
}
361+
362+
void RenderLoop::ControllerRemove(const int id )
363+
{
364+
if (_controller && id == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(_controller)))
365+
{
366+
SDL_GameControllerClose(_controller);
367+
_controller = _sdlRenderingWindow.FindController();
368+
}
369+
poco_debug(_logger, "Controller removed!");
370+
}
371+
372+
void RenderLoop::ControllerDownEvent(const SDL_Event& event)
373+
{
374+
if (!_controller || event.cdevice.which != SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(_controller)))
375+
{
376+
poco_debug(_logger, "No controller initialized");
377+
return;
378+
}
379+
380+
switch (event.cbutton.button)
381+
{
382+
case SDL_CONTROLLER_BUTTON_A:
383+
_sdlRenderingWindow.ToggleFullscreen();
384+
poco_debug(_logger, "A pressed!");
385+
break;
386+
387+
case SDL_CONTROLLER_BUTTON_B:
388+
Poco::NotificationCenter::defaultCenter().postNotification(new PlaybackControlNotification(PlaybackControlNotification::Action::RandomPreset, _keyStates._shiftPressed));
389+
poco_debug(_logger, "B pressed!");
390+
break;
391+
392+
case SDL_CONTROLLER_BUTTON_X:
393+
Poco::NotificationCenter::defaultCenter().postNotification(new PlaybackControlNotification(PlaybackControlNotification::Action::TogglePresetLocked));
394+
poco_debug(_logger, "X pressed!");
395+
break;
396+
397+
case SDL_CONTROLLER_BUTTON_Y:
398+
Poco::NotificationCenter::defaultCenter().postNotification(new PlaybackControlNotification(PlaybackControlNotification::Action::ToggleShuffle));
399+
poco_debug(_logger, "Y pressed!");
400+
break;
401+
402+
case SDL_CONTROLLER_BUTTON_BACK:
403+
_wantsToQuit = true;
404+
poco_debug(_logger, "Back pressed!");
405+
break;
406+
407+
case SDL_CONTROLLER_BUTTON_GUIDE:
408+
Poco::NotificationCenter::defaultCenter().postNotification(new PlaybackControlNotification(PlaybackControlNotification::Action::LastPreset, _keyStates._shiftPressed));
409+
poco_debug(_logger, "Guide pressed!");
410+
break;
411+
412+
case SDL_CONTROLLER_BUTTON_START:
413+
_projectMGui.Toggle();
414+
_sdlRenderingWindow.ShowCursor(_projectMGui.Visible());
415+
poco_debug(_logger, "Start pressed!");
416+
break;
417+
418+
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
419+
_audioCapture.NextAudioDevice();
420+
poco_debug(_logger, "Shoulder left pressed!");
421+
break;
422+
423+
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
424+
_sdlRenderingWindow.NextDisplay();
425+
poco_debug(_logger, "Shoulder right pressed!");
426+
break;
427+
428+
case SDL_CONTROLLER_BUTTON_DPAD_UP:
429+
// Increase beat sensitivity
430+
_projectMWrapper.ChangeBeatSensitivity(0.05f);
431+
poco_debug(_logger, "DPad up pressed!");
432+
break;
433+
434+
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
435+
// Decrease beat sensitivity
436+
_projectMWrapper.ChangeBeatSensitivity(-0.05f);
437+
poco_debug(_logger, "DPad down pressed!");
438+
break;
439+
440+
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
441+
Poco::NotificationCenter::defaultCenter().postNotification(new PlaybackControlNotification(PlaybackControlNotification::Action::PreviousPreset, _keyStates._shiftPressed));
442+
poco_debug(_logger, "DPad left pressed!");
443+
break;
444+
445+
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
446+
Poco::NotificationCenter::defaultCenter().postNotification(new PlaybackControlNotification(PlaybackControlNotification::Action::NextPreset, _keyStates._shiftPressed));
447+
poco_debug(_logger, "DPad right pressed!");
448+
break;
449+
}
450+
}
451+
452+
void RenderLoop::ControllerUpEvent(const SDL_Event& event)
453+
{
454+
455+
}
456+
327457
void RenderLoop::QuitNotificationHandler(const Poco::AutoPtr<QuitNotification>& notification)
328458
{
329459
_wantsToQuit = true;

Diff for: src/RenderLoop.h

+26
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,30 @@ class RenderLoop
6161
*/
6262
void MouseUpEvent(const SDL_MouseButtonEvent& event);
6363

64+
/**
65+
* @brief Handles SDL game controller add events (plugin in a new controller) events.
66+
* @param id The added controller id
67+
*/
68+
void ControllerAdd( int id );
69+
70+
/**
71+
* @brief Handles SDL game controller remove events.
72+
* @param id The removed controller id
73+
*/
74+
void ControllerRemove( int id );
75+
76+
/**
77+
* @brief Handles SDL game controller button down events.
78+
* @param event The controller button event
79+
*/
80+
void ControllerDownEvent(const SDL_Event& event);
81+
82+
/**
83+
* @brief Handles SDL game controller button up events.
84+
* @param event The controller button event
85+
*/
86+
void ControllerUpEvent(const SDL_Event& event);
87+
6488
/**
6589
* @brief Handler for quit notifications.
6690
* @param notification The received notification.
@@ -88,4 +112,6 @@ class RenderLoop
88112
ModifierKeyStates _keyStates; //!< Current "pressed" states of modifier keys
89113

90114
Poco::Logger& _logger{Poco::Logger::get("RenderLoop")}; //!< The class logger.
115+
116+
SDL_GameController *_controller;
91117
};

Diff for: src/SDLRenderingWindow.cpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ void SDLRenderingWindow::NextDisplay()
196196

197197
void SDLRenderingWindow::CreateSDLWindow()
198198
{
199-
SDL_InitSubSystem(SDL_INIT_VIDEO);
199+
SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER);
200200

201201
int width{_config->getInt("width", 800)};
202202
int height{_config->getInt("height", 600)};
@@ -307,7 +307,7 @@ void SDLRenderingWindow::DestroySDLWindow()
307307
SDL_DestroyWindow(_renderingWindow);
308308
_renderingWindow = nullptr;
309309

310-
SDL_QuitSubSystem(SDL_INIT_VIDEO);
310+
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER);
311311
}
312312

313313
void SDLRenderingWindow::DumpOpenGLInfo()
@@ -461,3 +461,21 @@ void SDLRenderingWindow::OnConfigurationPropertyRemoved(const std::string& key)
461461
UpdateWindowTitle();
462462
}
463463
}
464+
465+
SDL_GameController* SDLRenderingWindow::FindController() {
466+
//Check for joysticks
467+
if( SDL_NumJoysticks() < 1 )
468+
{
469+
poco_debug(_logger, "No joysticks connected");
470+
}
471+
472+
//For simplicity, we’ll only be setting up and tracking a single
473+
//controller at a time
474+
for (int i = 0; i < SDL_NumJoysticks(); i++) {
475+
if (SDL_IsGameController(i)) {
476+
return SDL_GameControllerOpen(i);
477+
}
478+
}
479+
480+
return nullptr;
481+
}

Diff for: src/SDLRenderingWindow.h

+6
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ class SDLRenderingWindow : public Poco::Util::Subsystem
9696

9797
SDL_GLContext GetGlContext() const;
9898

99+
/**
100+
* @brief Returns the ID of the first game controller found
101+
* @return SDL_GameController * Returns a gamecontroller identifier or NULL
102+
*/
103+
SDL_GameController* FindController();
104+
99105
protected:
100106

101107
/**

0 commit comments

Comments
 (0)