Separate JoystickConfig out into a separate class that can be stored in the global...
[supertux.git] / src / supertux / menu / joystick_menu.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
3 //           2007,2014 Ingo Ruhnke <grumbel@gmail.com>
4 //
5 //  This program is free software: you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation, either version 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 #include "supertux/menu/joystick_menu.hpp"
19
20 #include <sstream>
21
22 #include "control/joystick_manager.hpp"
23 #include "supertux/gameconfig.hpp"
24 #include "util/gettext.hpp"
25
26 namespace {
27
28 enum {
29   MNID_JUMP_WITH_UP = Controller::CONTROLCOUNT,
30   MNID_SCAN_JOYSTICKS,
31   MNID_AUTO_JOYSTICK_CFG
32 };
33
34 } // namespace
35
36 JoystickMenu::JoystickMenu(InputManager& input_manager) :
37   m_input_manager(input_manager),
38   m_joysticks_available(false)
39 {
40   recreate_menu();
41 }
42
43 JoystickMenu::~JoystickMenu()
44 {}
45
46 void
47 JoystickMenu::recreate_menu()
48 {
49   clear();
50   add_label(_("Setup Joystick"));
51   add_hl();
52
53   add_toggle(MNID_AUTO_JOYSTICK_CFG, _("Manual Configuration"),
54              !m_input_manager.use_game_controller())
55     ->set_help(_("Use manual configuration instead of SDL2's automatic GameController support"));
56
57   if (m_input_manager.use_game_controller())
58   {
59     m_joysticks_available = false;
60   }
61   else
62   {
63     if (m_input_manager.joystick_manager->joysticks.size() > 0)
64     {
65       m_joysticks_available = true;
66
67       add_controlfield(Controller::UP,          _("Up"));
68       add_controlfield(Controller::DOWN,        _("Down"));
69       add_controlfield(Controller::LEFT,        _("Left"));
70       add_controlfield(Controller::RIGHT,       _("Right"));
71       add_controlfield(Controller::JUMP,        _("Jump"));
72       add_controlfield(Controller::ACTION,      _("Action"));
73       add_controlfield(Controller::PAUSE_MENU,  _("Pause/Menu"));
74       add_controlfield(Controller::PEEK_LEFT,   _("Peek Left"));
75       add_controlfield(Controller::PEEK_RIGHT,  _("Peek Right"));
76       add_controlfield(Controller::PEEK_UP,     _("Peek Up"));
77       add_controlfield(Controller::PEEK_DOWN,   _("Peek Down"));
78
79       add_toggle(MNID_JUMP_WITH_UP, _("Jump with Up"), g_config->joystick_config.jump_with_up_joy);
80     }
81     else
82     {
83       m_joysticks_available = false;
84
85       add_inactive(-1, _("No Joysticks found"));
86       add_entry(MNID_SCAN_JOYSTICKS, _("Scan for Joysticks"));
87     }
88   }
89
90   add_hl();
91   add_back(_("Back"));
92   refresh();
93 }
94
95 std::string
96 JoystickMenu::get_button_name(int button)
97 {
98   if(button < 0)
99   {
100     return _("None");
101   }
102   else
103   {
104     std::ostringstream name;
105     name << "Button " << button;
106     return name.str();
107   }
108 }
109
110 void
111 JoystickMenu::menu_action(MenuItem* item)
112 {
113   if (0 <= item->id && item->id < Controller::CONTROLCOUNT)
114   {
115     item->change_input(_("Press Button"));
116     m_input_manager.joystick_manager->wait_for_joystick = item->id;
117   }
118   else if (item->id == MNID_JUMP_WITH_UP)
119   {
120     g_config->joystick_config.jump_with_up_joy = item->toggled;
121   }
122   else if (item->id == MNID_AUTO_JOYSTICK_CFG)
123   {
124     m_input_manager.use_game_controller(!item->toggled);
125     m_input_manager.reset();
126     recreate_menu();
127   }
128   else if(item->id == MNID_SCAN_JOYSTICKS)
129   {
130     m_input_manager.reset();
131     recreate_menu();
132   }
133 }
134
135 void
136 JoystickMenu::refresh_menu_item(Controller::Control id)
137 {
138   int button  = g_config->joystick_config.reversemap_joybutton(id);
139   int axis    = g_config->joystick_config.reversemap_joyaxis(id);
140   int hat_dir = g_config->joystick_config.reversemap_joyhat(id);
141
142   if (button != -1)
143   {
144     get_item_by_id(static_cast<int>(id)).change_input(get_button_name(button));
145   }
146   else if (axis != 0)
147   {
148     std::ostringstream name;
149
150     name << "Axis ";
151
152     if (axis < 0)
153       name << "-";
154     else
155       name << "+";
156
157     if (abs(axis) == 1)
158       name << "X";
159     else if (abs(axis) == 2)
160       name << "Y";
161     else if (abs(axis) == 2)
162       name << "X2";
163     else if (abs(axis) == 3)
164       name << "Y2";
165     else
166       name << abs(axis);
167
168     get_item_by_id(static_cast<int>(id)).change_input(name.str());
169   }
170   else if (hat_dir != -1)
171   {
172     std::string name;
173
174     switch (hat_dir)
175     {
176       case SDL_HAT_UP:
177         name = "Hat Up";
178         break;
179
180       case SDL_HAT_DOWN:
181         name = "Hat Down";
182         break;
183
184       case SDL_HAT_LEFT:
185         name = "Hat Left";
186         break;
187
188       case SDL_HAT_RIGHT:
189         name = "Hat Right";
190         break;
191
192       default:
193         name = "Unknown hat_dir";
194         break;
195     }
196
197     get_item_by_id(static_cast<int>(id)).change_input(name);
198   }
199   else
200   {
201     get_item_by_id(static_cast<int>(id)).change_input("None");
202   }
203 }
204
205 void
206 JoystickMenu::refresh()
207 {
208   if (m_joysticks_available)
209   {
210     refresh_menu_item(Controller::UP);
211     refresh_menu_item(Controller::DOWN);
212     refresh_menu_item(Controller::LEFT);
213     refresh_menu_item(Controller::RIGHT);
214
215     refresh_menu_item(Controller::JUMP);
216     refresh_menu_item(Controller::ACTION);
217     refresh_menu_item(Controller::PAUSE_MENU);
218     refresh_menu_item(Controller::PEEK_LEFT);
219     refresh_menu_item(Controller::PEEK_RIGHT);
220     refresh_menu_item(Controller::PEEK_UP);
221     refresh_menu_item(Controller::PEEK_DOWN);
222   }
223 }
224
225 /* EOF */