1 /*
2  * CRRCsim - the Charles River Radio Control Club Flight Simulator Project
3  *
4  * Copyright (C) 2005, 2008 Jens Wilhelm Wulf (original author)
5  * Copyright (C) 2005, 2006, 2007, 2008, 2009 Jan Reucker
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2
9  * as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
23 #include "i18n.h"
24 #include "mouse_kbd.h"
25 #include "defines.h"
26 #include "GUI/util.h"
27 #include "mod_misc/lib_conversions.h"
28 #include "mod_fdm/fdm_inputs.h"
29 
30 #include <stdio.h>
31 #include <sstream>
32 
init(SimpleXMLTransfer * cfgfile)33 void TInputDev::init(SimpleXMLTransfer* cfgfile)
34 {
35   int size;
36   SimpleXMLTransfer* item;
37   SimpleXMLTransfer* group;
38   SimpleXMLTransfer* item2;
39 
40   // set defaults
41   for (int n=0; n<MAXJOYBUTTON + 1; n++)
42     joystick_bind_b[n] = NOTHING;
43 
44   item = cfgfile->getChild("inputMethod.mouse.bindings.buttons", true);
45 
46   mouse_bind_l= getValButton(item->attribute("l",    "RESUME"), RESUME);
47   mouse_bind_m= getValButton(item->attribute("m",    "RESET"),  RESET);
48   mouse_bind_r= getValButton(item->attribute("r",    "PAUSE"),  PAUSE);
49   mouse_bind_u= getValButton(item->attribute("up",   "INCTHROTTLE"),  INCTHROTTLE);
50   mouse_bind_d= getValButton(item->attribute("down", "DECTHROTTLE"),  DECTHROTTLE);
51 
52   item = cfgfile->getChild("inputMethod.joystick", true);
53   joystick_n = item->attributeAsInt("number", 0);
54 
55   group = item->getChild("bindings.buttons", true);
56   size  = group->getChildCount();
57   if (size > MAXJOYBUTTON + 1)
58     size = MAXJOYBUTTON + 1;
59   for (int n=0; n<size; n++)
60   {
61     item2 = group->getChildAt(n);
62     joystick_bind_b[n] = getValButton(item2->attribute("bind", "NOTHING"), NOTHING);
63   }
64 
65   // zoom control
66   std::string zctr = strU(cfgfile->getString("zoom.control", ZoomControlStrings[0]));
67   for (int n=0; n<NUM_ZOMCONTROL; n++)
68   {
69     if (zctr.compare(ZoomControlStrings[n]) == 0)
70             zoom_control = n;
71   }
72 
73 }
74 
putBackIntoCfg(SimpleXMLTransfer * cfgfile)75 void TInputDev::putBackIntoCfg(SimpleXMLTransfer* cfgfile)
76 {
77   int size;
78   SimpleXMLTransfer* item; // = cfgfile->getChild("inputMethod.mouse.bindings.axes");
79   SimpleXMLTransfer* group;
80   SimpleXMLTransfer* item2;
81 
82   item = cfgfile->getChild("inputMethod.mouse.bindings.buttons");
83 
84   item->setAttributeOverwrite("l",    ActionButtonStrings[mouse_bind_l]);
85   item->setAttributeOverwrite("m",    ActionButtonStrings[mouse_bind_m]);
86   item->setAttributeOverwrite("r",    ActionButtonStrings[mouse_bind_r]);
87   item->setAttributeOverwrite("up",   ActionButtonStrings[mouse_bind_u]);
88   item->setAttributeOverwrite("down", ActionButtonStrings[mouse_bind_d]);
89 
90   item = cfgfile->getChild("inputMethod.joystick");
91   item->setAttributeOverwrite("number", joystick_n);
92 
93   group = item->getChild("bindings.buttons");
94 
95   // clean list
96   size = group->getChildCount();
97   for (int n=0; n<size; n++)
98   {
99     item2 = group->getChildAt(0);
100     group->removeChildAt(0);
101     delete item2;
102   }
103   // create new list
104   for (int n=0; n<MAXJOYBUTTON + 1; n++)
105   {
106     item2 = new SimpleXMLTransfer();
107     item2->setName("button");
108     item2->addAttribute("bind", ActionButtonStrings[joystick_bind_b[n]]);
109     group->addChild(item2);
110   }
111 
112   // zoom control
113   cfgfile->setAttributeOverwrite("zoom.control",ZoomControlStrings[zoom_control]);
114 
115 }
116 
getValAxis(std::string asString,int nDefault)117 int  TInputDev::getValAxis  (std::string asString, int nDefault)
118 {
119   asString = strU(asString);
120 
121   if (asString.compare("AILERON") == 0)
122     return(T_AxisMapper::AILERON);
123   else if (asString.compare("ELEVATOR") == 0)
124     return(T_AxisMapper::ELEVATOR);
125   else if (asString.compare("RUDDER") == 0)
126     return(T_AxisMapper::RUDDER);
127   else if (asString.compare("THROTTLE") == 0)
128     return(T_AxisMapper::THROTTLE);
129   else
130     return(nDefault);
131 }
132 
getValButton(std::string asString,int nDefault)133 int  TInputDev::getValButton(std::string asString, int nDefault)
134 {
135   asString = strU(asString);
136 
137   if (asString.compare("RESUME") == 0)
138     return(RESUME);
139   else if (asString.compare("PAUSE") == 0)
140     return(PAUSE);
141   else if (asString.compare("RESET") == 0)
142     return(RESET);
143   else if (asString.compare("INCTHROTTLE") == 0)
144     return(INCTHROTTLE);
145   else if (asString.compare("DECTHROTTLE") == 0)
146     return(DECTHROTTLE);
147   else if (asString.compare("ZOOMIN") == 0)
148     return(ZOOMIN);
149   else if (asString.compare("ZOOMOUT") == 0)
150     return(ZOOMOUT);
151   else
152     return(nDefault);
153 }
154 
155 // description: see header file
openJoystick()156 std::string TInputDev::openJoystick()
157 {
158 #if TEST_WITHOUT_JOYSTICK == 0
159   int numJoysticks;
160 
161   // check if the joystick subsystem is initialized,
162   // and maybe initialize again
163   if (!SDL_WasInit(SDL_INIT_JOYSTICK))
164   {
165     printf("TInputDev::openJoystick: Joystick subsystem not initialized, doing it now...\n");
166     SDL_InitSubSystem(SDL_INIT_JOYSTICK);
167     if (!SDL_WasInit(SDL_INIT_JOYSTICK))
168     {
169       std::string SDLerr = SDL_GetError();
170       printf("Can't initialize joystick subsystem!\n");
171       printf("SDL says: %s\n", SDLerr.c_str());
172       return ("Unable to initialize joystick subsystem. " + SDLerr);
173     }
174   }
175 
176   closeJoystick();
177 
178   numJoysticks = SDL_NumJoysticks();
179   printf("TInputDev::openJoystick: SDL found %d joysticks\n", numJoysticks);
180   if (numJoysticks > 0)
181   {
182     for (int i = 0; i < numJoysticks; i++)
183     {
184       printf("%d: %s\n", i, SDL_JoystickName(i));
185     }
186     printf("Trying to open joystick %d\n", joystick_n);
187     joy = SDL_JoystickOpen(joystick_n);
188     if (joy)
189     {
190       printf("Opened Joystick %d\n", joystick_n);
191       printf("Name: %s\n", SDL_JoystickName(joystick_n));
192       printf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
193       printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
194       return("");
195     }
196     else
197     {
198       std::string SDLerr = SDL_GetError();
199       printf("SDL says: %s\n", SDLerr.c_str());
200       return("Couldn't open Joystick " + itoStr(joystick_n, ' ', 1) + ": " + SDLerr);
201     }
202   }
203   else
204   {
205     return(_("No Joysticks found\n"));
206   }
207 #else
208   printf("Opened fake joystick %d\n", joystick_n);
209   return("");
210 #endif
211 }
212 
213 
214 // description: see header file
openJoystick(int joy_n)215 std::string TInputDev::openJoystick(int joy_n)
216 {
217   joystick_n = joy_n;
218   return openJoystick();
219 }
220 
221 
TInputDev()222 TInputDev::TInputDev()//constructor
223 {
224   joy = (SDL_Joystick*)0;
225   //Initialization of strings used for the configuration of the controls.
226   {   //for XML
227     std::vector<std::string> lAxisStringsXML(T_AxisMapper::NUM_AXISFUNCS);
228     lAxisStringsXML[T_AxisMapper::NOTHING]  = "nothing";
229     lAxisStringsXML[T_AxisMapper::AILERON]  = "aileron";
230     lAxisStringsXML[T_AxisMapper::ELEVATOR] = "elevator";
231     lAxisStringsXML[T_AxisMapper::RUDDER]   = "rudder";
232     lAxisStringsXML[T_AxisMapper::THROTTLE] = "throttle";
233     lAxisStringsXML[T_AxisMapper::FLAP]     = "flap";
234     lAxisStringsXML[T_AxisMapper::SPOILER]  = "spoiler";
235     lAxisStringsXML[T_AxisMapper::RETRACT]  = "retract";
236     lAxisStringsXML[T_AxisMapper::PITCH]    = "pitch";
237     int size;
238     AxisStringsXML = T_GUI_Util::loadnames(lAxisStringsXML, size);
239   }
240   {   //for GUI, possibly translated
241     std::vector<std::string> lAxisStringsGUI(T_AxisMapper::NUM_AXISFUNCS);
242     lAxisStringsGUI[T_AxisMapper::NOTHING]  =  _("nothing");
243     lAxisStringsGUI[T_AxisMapper::AILERON]  =  _("Aileron");
244     lAxisStringsGUI[T_AxisMapper::ELEVATOR] =  _("Elevator");
245     lAxisStringsGUI[T_AxisMapper::RUDDER]   =  _("Rudder");
246     lAxisStringsGUI[T_AxisMapper::THROTTLE] =  _("Throttle");
247     lAxisStringsGUI[T_AxisMapper::FLAP]     =  _("Flap");
248     lAxisStringsGUI[T_AxisMapper::SPOILER]  =  _("Spoiler");
249     lAxisStringsGUI[T_AxisMapper::RETRACT]  =  _("Retract");
250     lAxisStringsGUI[T_AxisMapper::PITCH]    =  _("Pitch");
251     int size;
252     AxisStringsGUI = T_GUI_Util::loadnames(lAxisStringsGUI, size);
253   }
254 
255 
256   {   //for XML
257     std::vector<std::string> lInputMethodStrings(T_TX_Interface::NUM_INPUTMETHODS);
258     lInputMethodStrings[T_TX_Interface::eIM_keyboard] = "Keyboard";
259     lInputMethodStrings[T_TX_Interface::eIM_mouse]    = "Mouse";
260     lInputMethodStrings[T_TX_Interface::eIM_joystick] = "Joystick";
261     lInputMethodStrings[T_TX_Interface::eIM_rctran]   = "RCTran";
262     lInputMethodStrings[T_TX_Interface::eIM_audio]    = "Audio";
263     lInputMethodStrings[T_TX_Interface::eIM_parallel] = "Parallel";
264     lInputMethodStrings[T_TX_Interface::eIM_serial2]  = "Serial2";
265     lInputMethodStrings[T_TX_Interface::eIM_rctran2]  = "RCTran2";
266     lInputMethodStrings[T_TX_Interface::eIM_serpic]   = "FMSPIC";
267     lInputMethodStrings[T_TX_Interface::eIM_mnav]     = "MNAV";
268     lInputMethodStrings[T_TX_Interface::eIM_zhenhua]  = "ZhenHua";
269     lInputMethodStrings[T_TX_Interface::eIM_CT6A]     = "CT6A";
270     int size;
271     InputMethodStrings = T_GUI_Util::loadnames(lInputMethodStrings, size);
272   }
273   {   // The same but possibly translated
274     std::vector<std::string> lInputMethodStrings(T_TX_Interface::NUM_INPUTMETHODS);
275     lInputMethodStrings[T_TX_Interface::eIM_keyboard] = _("Keyboard");
276     lInputMethodStrings[T_TX_Interface::eIM_mouse]    = _("Mouse");
277     lInputMethodStrings[T_TX_Interface::eIM_joystick] = _("Joystick");
278     lInputMethodStrings[T_TX_Interface::eIM_rctran]   = _("RCTran");
279     lInputMethodStrings[T_TX_Interface::eIM_audio]    = _("Audio");
280     lInputMethodStrings[T_TX_Interface::eIM_parallel] = _("Parallel");
281     lInputMethodStrings[T_TX_Interface::eIM_serial2]  = "Serial2";
282     lInputMethodStrings[T_TX_Interface::eIM_rctran2]  = "RCTran2";
283     lInputMethodStrings[T_TX_Interface::eIM_serpic]   = "FMSPIC";
284     lInputMethodStrings[T_TX_Interface::eIM_mnav]     = "MNAV";
285     lInputMethodStrings[T_TX_Interface::eIM_zhenhua]  = "ZhenHua";
286     lInputMethodStrings[T_TX_Interface::eIM_CT6A]     = "CT6A";
287     int size;
288     InputMethodStringsGUI = T_GUI_Util::loadnames(lInputMethodStrings, size);
289   }
290   {   // for XML
291     std::vector<std::string> lActionButtonStrings(NUM_BUTTONACTION);
292     lActionButtonStrings[NOTHING]      = "NOTHING";
293     lActionButtonStrings[RESUME]       = "RESUME";
294     lActionButtonStrings[PAUSE]        = "PAUSE";
295     lActionButtonStrings[RESET]        = "RESET";
296     lActionButtonStrings[INCTHROTTLE]  = "INCTHROTTLE";
297     lActionButtonStrings[DECTHROTTLE]  = "DECTHROTTLE";
298     lActionButtonStrings[ZOOMIN]       = "ZOOMIN";
299     lActionButtonStrings[ZOOMIN]       = "ZOOMIN";
300     int size;
301     ActionButtonStrings = T_GUI_Util::loadnames(lActionButtonStrings, size);
302   }
303   {   //for GUI, possibly translated
304     std::vector<std::string> lActionButtonStringsGUI(NUM_BUTTONACTION);
305     lActionButtonStringsGUI[NOTHING]      = _("Nothing");
306     lActionButtonStringsGUI[RESUME]       = _("Resume");
307     lActionButtonStringsGUI[PAUSE]        = _("Pause");
308     lActionButtonStringsGUI[RESET]        = _("Reset");
309     lActionButtonStringsGUI[INCTHROTTLE]  = _("Inc Throttle");
310     lActionButtonStringsGUI[DECTHROTTLE]  = _("Dec Throttle");
311     lActionButtonStringsGUI[ZOOMIN]       = _("Zoom In");
312     lActionButtonStringsGUI[ZOOMOUT]      = _("Zoom Out");
313     int size;
314     ActionButtonStringsGUI = T_GUI_Util::loadnames(lActionButtonStringsGUI, size);
315   }
316   {   // for XML
317     std::vector<std::string> lZoomControlStrings(NUM_ZOMCONTROL);
318     lZoomControlStrings[KEYBOARD]    = "KEYBOARD";
319     lZoomControlStrings[MOUSE]       = "MOUSE";
320     int size;
321     ZoomControlStrings = T_GUI_Util::loadnames(lZoomControlStrings, size);
322   }
323   {   //for GUI, possibly translated
324     std::vector<std::string> lZoomControlStrings(NUM_ZOMCONTROL);
325     lZoomControlStrings[KEYBOARD]    = _("Keyboard");
326     lZoomControlStrings[MOUSE]       = _("Mouse");
327     int size;
328     ZoomControlStringsGUI = T_GUI_Util::loadnames(lZoomControlStrings, size);
329   }
330   {
331     std::vector<std::string> lMixerStringsXML(T_TX_Mixer::NUM_MIXERS);
332     std::vector<std::string> lMixerStringsGUI(T_TX_Mixer::NUM_MIXERS);
333     for (int i = 0; i < T_TX_Mixer::NUM_MIXERS; i++)
334     {
335       std::string s;
336       std::stringstream out;
337       out << (i+1);
338       s = out.str();
339       lMixerStringsXML[i] = "mixer" + s;
340       lMixerStringsGUI[i] = _("Mixer") + s;
341     }
342     int size;
343     MixerStringsXML = T_GUI_Util::loadnames(lMixerStringsXML, size);
344     MixerStringsGUI = T_GUI_Util::loadnames(lMixerStringsGUI, size);
345   }
346 }
347 
closeJoystick()348 void TInputDev::closeJoystick()
349 {
350   if (joy != (SDL_Joystick*)0)
351   {
352     SDL_JoystickClose(joy);
353     joy = (SDL_Joystick*)0;
354   }
355 }
356 
getJoystickNumAxes()357 int TInputDev::getJoystickNumAxes()
358 {
359   #if TEST_WITHOUT_JOYSTICK == 0
360   if (joy != NULL)
361   {
362     return SDL_JoystickNumAxes(joy);
363   }
364   else
365   {
366     return 0;
367   }
368   #else
369   return SIMULATED_JOYSTICK_AXES;
370   #endif
371 }
372 
getJoystickNumButtons()373 int TInputDev::getJoystickNumButtons()
374 {
375   #if TEST_WITHOUT_JOYSTICK == 0
376   if (joy != NULL)
377   {
378     return SDL_JoystickNumButtons(joy);
379   }
380   else
381   {
382     return 0;
383   }
384   #else
385   return SIMULATED_JOYSTICK_BUTTONS;
386   #endif
387 }
388