Skip to content

Commit 8cf5bdd

Browse files
author
Semphris
committed
Don't spawn a player immediately when a joystick is connected
A connected joystick will no longer automatically spawn a player until the user presses A.
1 parent 60572ba commit 8cf5bdd

File tree

4 files changed

+90
-28
lines changed

4 files changed

+90
-28
lines changed

src/control/game_controller_manager.cpp

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,24 @@ GameControllerManager::process_button_event(const SDL_ControllerButtonEvent& ev)
4848
int player_id;
4949

5050
{
51-
auto it = m_game_controllers.find(SDL_GameControllerFromInstanceID(ev.which));
51+
auto* controller = SDL_GameControllerFromInstanceID(ev.which);
52+
auto it = m_game_controllers.find(controller);
5253

53-
if (it == m_game_controllers.end() || it->second < 0)
54+
if (it == m_game_controllers.end())
5455
return;
5556

57+
if (it->second < 0)
58+
{
59+
if (ev.button == SDL_CONTROLLER_BUTTON_A && g_config->multiplayer_auto_manage_players)
60+
{
61+
autobind_controller(controller);
62+
}
63+
else
64+
{
65+
return;
66+
}
67+
}
68+
5669
player_id = it->second;
5770
}
5871

@@ -229,25 +242,22 @@ GameControllerManager::on_controller_added(int joystick_index)
229242

230243
if (m_parent->m_use_game_controller && g_config->multiplayer_auto_manage_players)
231244
{
232-
int id = m_parent->get_num_users();
245+
// TODO: Display a popup stating that a controller was connected and that the player may joind by pressing A
246+
247+
// If a player already exists, bind it immediately without waiting for the user to press A.
233248
for (int i = 0; i < m_parent->get_num_users(); i++)
234249
{
235250
if (!m_parent->has_corresponsing_controller(i) && !m_parent->m_uses_keyboard[i])
236251
{
237-
id = i;
252+
m_game_controllers[game_controller] = i;
253+
254+
if (i != 0)
255+
{
256+
GameSession::current()->on_player_added(i);
257+
}
238258
break;
239259
}
240260
}
241-
242-
if (id == m_parent->get_num_users())
243-
m_parent->push_user();
244-
245-
m_game_controllers[game_controller] = id;
246-
247-
if (GameSession::current() && (savegame && savegame->is_title_screen()) && id != 0)
248-
{
249-
GameSession::current()->on_player_added(id);
250-
}
251261
}
252262
}
253263
}
@@ -343,3 +353,21 @@ GameControllerManager::bind_controller(SDL_GameController* controller, int playe
343353
if (pair2.second == player_id && pair2.first != controller)
344354
pair2.second = -1;
345355
}
356+
357+
void
358+
GameControllerManager::autobind_controller(SDL_GameController* game_controller)
359+
{
360+
// This function only binds unbound controllers to a new player; binding to an
361+
// existing player or rebinding an already bound controller should be dealt
362+
// with elsewhere.
363+
assert(m_game_controllers[game_controller] == -1);
364+
365+
int id = m_parent->get_num_users();
366+
m_parent->push_user();
367+
m_game_controllers[game_controller] = id;
368+
369+
if (GameSession::current())
370+
{
371+
GameSession::current()->on_player_added(id);
372+
}
373+
}

src/control/game_controller_manager.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ class GameControllerManager final
5555

5656
inline std::unordered_map<SDL_GameController*, int>& get_controller_mapping() { return m_game_controllers; }
5757

58+
private:
59+
void autobind_controller(SDL_GameController* game_controller);
60+
5861
private:
5962
InputManager* m_parent;
6063
int m_deadzone;

src/control/joystick_manager.cpp

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,24 +82,22 @@ JoystickManager::on_joystick_added(int joystick_index)
8282

8383
if (!parent->m_use_game_controller && g_config->multiplayer_auto_manage_players)
8484
{
85-
int id = parent->get_num_users();
85+
// TODO: Display a popup stating that a controller was connected and that the player may joind by pressing A
86+
87+
// If a player already exists, bind it immediately without waiting for the user to press A.
8688
for (int i = 0; i < parent->get_num_users(); i++)
8789
{
8890
if (!parent->has_corresponsing_controller(i) && !parent->m_uses_keyboard[i])
8991
{
90-
id = i;
91-
break;
92-
}
93-
}
94-
95-
if (id == parent->get_num_users())
96-
parent->push_user();
92+
joysticks[joystick] = i;
9793

98-
joysticks[joystick] = id;
94+
if (i != 0)
95+
{
96+
GameSession::current()->on_player_added(i);
97+
}
9998

100-
if (GameSession::current() && !GameSession::current()->get_savegame().is_title_screen() && id != 0)
101-
{
102-
GameSession::current()->on_player_added(id);
99+
break;
100+
}
103101
}
104102
}
105103
}
@@ -257,7 +255,7 @@ JoystickManager::process_button_event(const SDL_JoyButtonEvent& jbutton)
257255
{
258256
auto i = m_joystick_config.m_joy_button_map.find(std::make_pair(jbutton.which, jbutton.button));
259257
if (i == m_joystick_config.m_joy_button_map.end()) {
260-
log_debug << "Unmapped joybutton " << static_cast<int>(jbutton.button) << " pressed" << std::endl;
258+
log_fatal << "Unmapped joybutton " << static_cast<int>(jbutton.button) << " pressed" << std::endl;
261259
} else {
262260
set_joy_controls(jbutton.which, i->second, (jbutton.state == SDL_PRESSED));
263261
}
@@ -274,9 +272,21 @@ void
274272
JoystickManager::set_joy_controls(SDL_JoystickID joystick, Control id, bool value)
275273
{
276274
auto it = joysticks.find(SDL_JoystickFromInstanceID(joystick));
277-
if (it == joysticks.end() || it->second < 0)
275+
if (it == joysticks.end())
278276
return;
279277

278+
if (it->second < 0)
279+
{
280+
if (id == Control::JUMP && g_config->multiplayer_auto_manage_players)
281+
{
282+
autobind_joystick(it->first);
283+
}
284+
else
285+
{
286+
return;
287+
}
288+
}
289+
280290
if (m_joystick_config.m_jump_with_up_joy &&
281291
id == Control::UP)
282292
{
@@ -346,3 +356,21 @@ JoystickManager::bind_joystick(SDL_Joystick* controller, int player_id)
346356
if (pair2.second == player_id && pair2.first != controller)
347357
pair2.second = -1;
348358
}
359+
360+
void
361+
JoystickManager::autobind_joystick(SDL_Joystick* joystick)
362+
{
363+
// This function only binds unbound joysticks to a new player; binding to an
364+
// existing player or rebinding an already bound joystick should be dealt with
365+
// elsewhere.
366+
assert(joysticks[joystick] == -1);
367+
368+
int id = parent->get_num_users();
369+
parent->push_user();
370+
joysticks[joystick] = id;
371+
372+
if (GameSession::current())
373+
{
374+
GameSession::current()->on_player_added(id);
375+
}
376+
}

src/control/joystick_manager.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class JoystickManager final
6363

6464
inline std::unordered_map<SDL_Joystick*, int>& get_joystick_mapping() { return joysticks; }
6565

66+
private:
67+
void autobind_joystick(SDL_Joystick* joystick);
68+
6669
private:
6770
InputManager* parent;
6871
JoystickConfig& m_joystick_config;

0 commit comments

Comments
 (0)