1 #include "options.h"
2 
3 #include "../nx.h"
4 #include "dialog.h"
5 #include "message.h"
6 #include "../ResourceManager.h"
7 #include "../common/misc.h"
8 #include "../game.h"
9 #include "../graphics/Renderer.h"
10 #include "../input.h"
11 #include "../map.h"
12 #include "../settings.h"
13 #include "../sound/SoundManager.h"
14 using namespace Options;
15 using namespace NXE::Graphics;
16 
17 std::vector<void *> optionstack;
18 
19 void DialogDismissed();
20 static void EnterMainMenu();
21 static void EnterSoundMenu(ODItem *item, int dir);
22 static void EnterGraphicsMenu(ODItem *item, int dir);
23 static void EnterControlsMenu(ODItem *item, int dir);
24 static void EnterRebindMenu(ODItem *item, int dir);
25 
26 void LeavingMainMenu();
27 void _res_get(ODItem *item);
28 void _res_change(ODItem *item, int dir);
29 void _fullscreen_get(ODItem *item);
30 void _fullscreen_change(ODItem *item, int dir);
31 void _facepics_get(ODItem *item);
32 void _facepics_change(ODItem *item, int dir);
33 void _lights_get(ODItem *item);
34 void _lights_change(ODItem *item, int dir);
35 
36 void _lang_get(ODItem *item);
37 void _lang_change(ODItem *item, int dir);
38 
39 void _sound_change(ODItem *item, int dir);
40 void _sound_get(ODItem *item);
41 void _music_change(ODItem *item, int dir);
42 void _music_get(ODItem *item);
43 void _tracks_change(ODItem *item, int dir);
44 void _tracks_get(ODItem *item);
45 void _sfx_volume_change(ODItem *item, int dir);
46 void _sfx_volume_get(ODItem *item);
47 void _music_volume_change(ODItem *item, int dir);
48 void _music_volume_get(ODItem *item);
49 void _music_interpolation_change(ODItem *item, int dir);
50 void _music_interpolation_get(ODItem *item);
51 void _rumble_change(ODItem *item, int dir);
52 void _rumble_get(ODItem *item);
53 void _strafe_change(ODItem *item, int dir);
54 void _strafe_get(ODItem *item);
55 void _scheme_change(ODItem *item, int dir);
56 void _scheme_get(ODItem *item);
57 void _scheme_get2(ODItem *item);
58 static void _upd_control(ODItem *item);
59 static void _edit_control(ODItem *item, int dir);
60 static void _finish_control_edit(Message *msg);
61 
62 #define SLIDE_SPEED 32
63 #define SLIDE_DIST (3 * SLIDE_SPEED)
64 
65 static struct
66 {
67   Dialog *dlg, *subdlg;
68   Dialog *dismiss_on_focus;
69   unsigned int mm_cursel;
70   bool InMainMenu;
71   bool InBindingMenu;
72   int xoffset;
73 
74   int32_t remapping_key;
75   in_action new_sdl_key;
76 } opt;
77 
options_init(int retmode)78 bool options_init(int retmode)
79 {
80   memset(&opt, 0, sizeof(opt));
81   Options::init_objects();
82   opt.dlg = new Dialog;
83 
84   opt.xoffset = SLIDE_DIST;
85   opt.dlg->offset(-SLIDE_DIST, 0);
86 
87   EnterMainMenu();
88   opt.dlg->ondismiss = DialogDismissed;
89   opt.dlg->ShowFull();
90 
91   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_MOVE);
92   return 0;
93 }
94 
options_close()95 void options_close()
96 {
97   Options::close_objects();
98   for (unsigned int i = 0; i < optionstack.size(); i++)
99   {
100     FocusHolder *fh = (FocusHolder *)optionstack.at(i);
101     delete fh;
102   }
103   optionstack.clear();
104   settings_save();
105 }
106 
107 /*
108 void c------------------------------() {}
109 */
110 
options_tick()111 void options_tick()
112 {
113   unsigned int i;
114   FocusHolder *fh;
115 
116   Renderer::getInstance()->clearScreen(BLACK);
117   Options::run_and_draw_objects();
118 
119   fh = (FocusHolder *)optionstack.at(optionstack.size() - 1);
120   if (fh)
121   {
122     fh->RunInput();
123     if (game.paused != GP_OPTIONS)
124       return;
125 
126     fh = (FocusHolder *)optionstack.at(optionstack.size() - 1);
127     if (fh == opt.dismiss_on_focus && fh)
128     {
129       opt.dismiss_on_focus = NULL;
130       delete fh;
131       //			optionstack.erase(optionstack.begin()+(optionstack.size() - 1));
132     }
133   }
134 
135   for (i = 0; i < optionstack.size(); i++)
136   {
137     fh = (FocusHolder *)optionstack.at(i);
138     if (fh)
139       fh->Draw();
140   }
141 
142   if (opt.xoffset > 0)
143   {
144     opt.dlg->offset(SLIDE_SPEED, 0);
145     opt.xoffset -= SLIDE_SPEED;
146   }
147 }
148 
149 /*
150 void c------------------------------() {}
151 */
152 
DialogDismissed()153 void DialogDismissed()
154 {
155   if (opt.InMainMenu)
156   {
157     memset(inputs, 0, sizeof(inputs));
158     game.pause(false);
159   }
160   else if (opt.InBindingMenu)
161   {
162     EnterControlsMenu(NULL,0);
163   }
164   else
165   {
166     EnterMainMenu();
167   }
168 }
169 
170 /*
171 void c------------------------------() {}
172 */
173 
EnterMainMenu()174 static void EnterMainMenu()
175 {
176   Dialog *dlg = opt.dlg;
177 
178   dlg->Clear();
179 
180   dlg->AddItem("Graphics", EnterGraphicsMenu);
181   dlg->AddItem("Sound", EnterSoundMenu);
182   dlg->AddItem("Controls", EnterControlsMenu);
183 
184   dlg->AddSeparator();
185 
186   if (game.mode == GM_TITLE)
187     dlg->AddItem("Language: ", _lang_change, _lang_get, -1, OD_CHOICE);
188 
189   dlg->AddSeparator();
190   dlg->AddDismissalItem();
191 
192   dlg->SetSelection(opt.mm_cursel);
193   dlg->onclear   = LeavingMainMenu;
194   opt.InMainMenu = true;
195 }
196 
LeavingMainMenu()197 void LeavingMainMenu()
198 {
199   opt.mm_cursel    = opt.dlg->GetSelection();
200   opt.dlg->onclear = NULL;
201   opt.InMainMenu   = false;
202 }
203 
EnterControlsMenu(ODItem * item,int dir)204 static void EnterControlsMenu(ODItem *item, int dir)
205 {
206   Dialog *dlg = opt.dlg;
207 
208   dlg->Clear();
209   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_MOVE);
210   dlg->AddItem("Force feedback: ", _rumble_change, _rumble_get, -1, OD_CHOICE);
211   dlg->AddItem("Strafing: ", _strafe_change, _strafe_get, -1, OD_CHOICE);
212   dlg->AddSeparator();
213   dlg->AddItem("Ok: ", _scheme_change, _scheme_get, -1, OD_CHOICE);
214   dlg->AddItem("Cancel: ", _scheme_change, _scheme_get2, -1, OD_CHOICE);
215   dlg->AddSeparator();
216   dlg->AddItem("Bind keys", EnterRebindMenu);
217 
218   dlg->AddSeparator();
219   dlg->AddDismissalItem();
220   opt.InBindingMenu = false;
221 }
222 
EnterRebindMenu(ODItem * item,int dir)223 static void EnterRebindMenu(ODItem *item, int dir)
224 {
225   Dialog *dlg = opt.dlg;
226   opt.InBindingMenu = true;
227   dlg->Clear();
228   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_MOVE);
229   dlg->AddItem("Left", _edit_control, _upd_control, LEFTKEY);
230   dlg->AddItem("Right", _edit_control, _upd_control, RIGHTKEY);
231   dlg->AddItem("Up", _edit_control, _upd_control, UPKEY);
232   dlg->AddItem("Down", _edit_control, _upd_control, DOWNKEY);
233   dlg->AddItem("Jump", _edit_control, _upd_control, JUMPKEY);
234   dlg->AddItem("Strafe", _edit_control, _upd_control, STRAFEKEY);
235   dlg->AddItem("Fire", _edit_control, _upd_control, FIREKEY);
236   dlg->AddItem("Wpn Prev", _edit_control, _upd_control, PREVWPNKEY);
237   dlg->AddItem("Wpn Next", _edit_control, _upd_control, NEXTWPNKEY);
238   dlg->AddItem("Inventory", _edit_control, _upd_control, INVENTORYKEY);
239   dlg->AddItem("Map", _edit_control, _upd_control, MAPSYSTEMKEY);
240   dlg->AddItem("Pause", _edit_control, _upd_control, ESCKEY);
241 
242   dlg->AddSeparator();
243   dlg->AddDismissalItem();
244   opt.InBindingMenu = true;
245 }
246 
EnterGraphicsMenu(ODItem * item,int dir)247 static void EnterGraphicsMenu(ODItem *item, int dir)
248 {
249   Dialog *dlg = opt.dlg;
250 
251   dlg->Clear();
252   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_MOVE);
253   dlg->AddItem("Resolution: ", _res_change, _res_get, -1, OD_CHOICE);
254   dlg->AddItem("Fullscreen: ", _fullscreen_change, _fullscreen_get, -1, OD_CHOICE);
255   dlg->AddItem("Animated facepics: ", _facepics_change, _facepics_get, -1, OD_CHOICE);
256   dlg->AddItem("Lights: ", _lights_change, _lights_get, -1, OD_CHOICE);
257   dlg->AddSeparator();
258   dlg->AddDismissalItem();
259 }
260 
EnterSoundMenu(ODItem * item,int dir)261 static void EnterSoundMenu(ODItem *item, int dir)
262 {
263   Dialog *dlg = opt.dlg;
264 
265   dlg->Clear();
266   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_MOVE);
267   dlg->AddItem("Music: ", _music_change, _music_get, -1, OD_CHOICE);
268   dlg->AddItem("Tracks: ", _tracks_change, _tracks_get, -1, OD_CHOICE);
269   dlg->AddItem("Sound: ", _sound_change, _sound_get, -1, OD_CHOICE);
270   dlg->AddSeparator();
271   dlg->AddItem("SFX volume: ", _sfx_volume_change, _sfx_volume_get, -1, OD_CHOICE);
272   dlg->AddItem("Music volume: ", _music_volume_change, _music_volume_get, -1, OD_CHOICE);
273   dlg->AddItem("Music interpolation: ", _music_interpolation_change, _music_interpolation_get, -1, OD_CHOICE);
274   dlg->AddSeparator();
275   dlg->AddDismissalItem();
276 }
277 
278 
_res_get(ODItem * item)279 void _res_get(ODItem *item)
280 {
281   const gres_t *reslist = Renderer::getInstance()->getResolutions();
282 
283   if (settings->resolution < 0 || settings->resolution >= Renderer::getInstance()->getResolutionCount())
284   {
285     item->suffix[0] = 0;
286   }
287   else
288   {
289     strcpy(item->suffix, reslist[settings->resolution].name);
290   }
291 }
292 
_res_change(ODItem * item,int dir)293 void _res_change(ODItem *item, int dir)
294 {
295   int numres = Renderer::getInstance()->getResolutionCount();
296   int newres;
297 
298   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_DOOR);
299 
300   newres = (settings->resolution + dir);
301   if (newres >= numres)
302     newres = 1;
303   if (newres < 1)
304     newres = (numres - 1);
305   const gres_t *res = Renderer::getInstance()->getResolutions();
306   while (!res[newres].enabled)
307   {
308     newres += dir;
309     if (newres >= numres)
310       newres = 1;
311     if (newres < 1)
312       newres = (numres - 1);
313   }
314 
315   if (Renderer::getInstance()->setResolution(newres, true))
316   {
317     settings->resolution = newres;
318   }
319   else
320   {
321     new Message("Resolution change failed");
322     NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_GUN_CLICK);
323   }
324 }
325 
_lang_get(ODItem * item)326 void _lang_get(ODItem *item)
327 {
328   std::vector<std::string> langs = ResourceManager::getInstance()->languages();
329   for (auto &l : langs)
330   {
331     if (strcmp(settings->language, l.c_str()) == 0)
332     {
333       strcpy(item->suffix, l.c_str());
334     }
335   }
336 }
337 
_lang_change(ODItem * item,int dir)338 void _lang_change(ODItem *item, int dir)
339 {
340   std::vector<std::string> langs = ResourceManager::getInstance()->languages();
341   int i                          = 0;
342   for (auto &l : langs)
343   {
344     if (l == settings->language)
345       break;
346     i++;
347   }
348   i += dir;
349   if (i < 0)
350   {
351     i = langs.size() - 1;
352   }
353   if (i >= (int)langs.size())
354   {
355     i = 0;
356   }
357   memset(settings->language, 0, 256);
358   strncpy(settings->language, langs[i].c_str(), 255);
359   game.lang->load();
360 //  font_reload();
361   game.tsc->Init();
362   if (!Renderer::getInstance()->flushAll())
363   {
364     LOG_CRITICAL("Failed to re-init graphics");
365     exit(-1);
366   }
367 }
368 
_fullscreen_get(ODItem * item)369 void _fullscreen_get(ODItem *item)
370 {
371   static const char *strs[] = {"Off", "On"};
372   strcpy(item->suffix, strs[settings->fullscreen]);
373 }
374 
_fullscreen_change(ODItem * item,int dir)375 void _fullscreen_change(ODItem *item, int dir)
376 {
377   settings->fullscreen ^= 1;
378   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
379   Renderer::getInstance()->setFullscreen(settings->fullscreen);
380 }
381 
_facepics_get(ODItem * item)382 void _facepics_get(ODItem *item)
383 {
384   static const char *strs[] = {"Off", "On"};
385   strcpy(item->suffix, strs[settings->animated_facepics]);
386 }
387 
_facepics_change(ODItem * item,int dir)388 void _facepics_change(ODItem *item, int dir)
389 {
390   settings->animated_facepics ^= 1;
391   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
392 }
393 
_lights_change(ODItem * item,int dir)394 void _lights_change(ODItem *item, int dir)
395 {
396   settings->lights ^= 1;
397   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
398 }
399 
_lights_get(ODItem * item)400 void _lights_get(ODItem *item)
401 {
402   static const char *strs[] = {"Off", "On"};
403   strcpy(item->suffix, strs[settings->lights]);
404 }
405 
_sound_change(ODItem * item,int dir)406 void _sound_change(ODItem *item, int dir)
407 {
408   settings->sound_enabled ^= 1;
409   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
410 }
411 
_sound_get(ODItem * item)412 void _sound_get(ODItem *item)
413 {
414   static const char *strs[] = {"Off", "On"};
415   strcpy(item->suffix, strs[settings->sound_enabled]);
416 }
417 
_strafe_change(ODItem * item,int dir)418 void _strafe_change(ODItem *item, int dir)
419 {
420   settings->strafing ^= 1;
421   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
422 }
423 
_strafe_get(ODItem * item)424 void _strafe_get(ODItem *item)
425 {
426   static const char *strs[] = {"Off", "On"};
427   strcpy(item->suffix, strs[settings->strafing]);
428 }
429 
_music_change(ODItem * item,int dir)430 void _music_change(ODItem *item, int dir)
431 {
432   int result = settings->music_enabled + dir;
433   if (result < 0)
434     result = 2;
435   if (result > 2)
436     result = 0;
437   NXE::Sound::SoundManager::getInstance()->enableMusic(result);
438   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
439 }
440 
_music_get(ODItem * item)441 void _music_get(ODItem *item)
442 {
443   static const char *strs[] = {"Off", "On", "Boss Only"};
444   strcpy(item->suffix, strs[settings->music_enabled]);
445 }
446 
_tracks_change(ODItem * item,int dir)447 void _tracks_change(ODItem *item, int dir)
448 {
449   std::vector<std::string> names = NXE::Sound::SoundManager::getInstance()->music_dir_names();
450   int result = settings->new_music + dir;
451 
452   if (result < 0)
453     result = names.size()-1;
454   if (result >= (int)names.size())
455     result = 0;
456   NXE::Sound::SoundManager::getInstance()->setNewmusic(result);
457   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
458 }
459 
_tracks_get(ODItem * item)460 void _tracks_get(ODItem *item)
461 {
462   std::vector<std::string> names = NXE::Sound::SoundManager::getInstance()->music_dir_names();
463   strcpy(item->suffix, names.at(settings->new_music).c_str());
464 }
465 
_sfx_volume_change(ODItem * item,int dir)466 void _sfx_volume_change(ODItem *item, int dir)
467 {
468   settings->sfx_volume += 5*dir;
469 
470   if (settings->sfx_volume <= 0)
471     settings->sfx_volume = 0;
472   else if (settings->sfx_volume >= 100)
473     settings->sfx_volume = 100;
474   NXE::Sound::SoundManager::getInstance()->updateSfxVolume();
475   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
476 }
477 
_sfx_volume_get(ODItem * item)478 void _sfx_volume_get(ODItem *item)
479 {
480   char str[10];
481   sprintf(str, "%d%%", settings->sfx_volume);
482   strcpy(item->suffix, str);
483 }
484 
_music_volume_change(ODItem * item,int dir)485 void _music_volume_change(ODItem *item, int dir)
486 {
487   settings->music_volume += 5*dir;
488 
489   if (settings->music_volume <= 0)
490     settings->music_volume = 0;
491   else if (settings->music_volume >= 100)
492     settings->music_volume = 100;
493 
494   NXE::Sound::SoundManager::getInstance()->updateMusicVolume();
495   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
496 }
497 
_music_volume_get(ODItem * item)498 void _music_volume_get(ODItem *item)
499 {
500   char str[10];
501   sprintf(str, "%d%%", settings->music_volume);
502   strcpy(item->suffix, str);
503 }
504 
505 
_music_interpolation_change(ODItem * item,int dir)506 void _music_interpolation_change(ODItem *item, int dir)
507 {
508   int result = settings->music_interpolation + dir;
509   if (result < 0)
510     result = 2;
511   if (result > 2)
512     result = 0;
513   settings->music_interpolation = result;
514 }
515 
_music_interpolation_get(ODItem * item)516 void _music_interpolation_get(ODItem *item)
517 {
518   static const char *strs[] = {"Nearest", "Linear", "Cubic"};
519   strcpy(item->suffix, strs[settings->music_interpolation]);
520 }
521 
522 
523 /*
524 void c------------------------------() {}
525 */
526 
_rumble_change(ODItem * item,int dir)527 void _rumble_change(ODItem *item, int dir)
528 {
529   settings->rumble ^= 1;
530   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
531 }
532 
_rumble_get(ODItem * item)533 void _rumble_get(ODItem *item)
534 {
535   static const char *strs[] = {"Off", "On"};
536   strcpy(item->suffix, strs[settings->rumble]);
537 }
538 
539 
_scheme_change(ODItem * item,int dir)540 void _scheme_change(ODItem *item, int dir)
541 {
542   settings->control_scheme ^= 1;
543   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
544   opt.dlg->Refresh();
545   if (settings->control_scheme)
546   {
547     ACCEPT_BUTTON = FIREKEY;
548     DECLINE_BUTTON = JUMPKEY;
549   }
550   else
551   {
552     ACCEPT_BUTTON = JUMPKEY;
553     DECLINE_BUTTON = FIREKEY;
554   }
555 }
556 
_scheme_get(ODItem * item)557 void _scheme_get(ODItem *item)
558 {
559   static const char *strs[] = {"Jump", "Fire"};
560   strcpy(item->suffix, strs[settings->control_scheme]);
561 }
562 
_scheme_get2(ODItem * item)563 void _scheme_get2(ODItem *item)
564 {
565   static const char *strs[] = {"Fire", "Jump"};
566   strcpy(item->suffix, strs[settings->control_scheme]);
567 }
568 
_upd_control(ODItem * item)569 static void _upd_control(ODItem *item)
570 {
571   char keyname[64];
572 
573   in_action action = input_get_mapping(item->id);
574 
575   if (action.key != -1)
576   {
577     int keysym = action.key;
578     snprintf(keyname, 64, "%s", SDL_GetKeyName((SDL_Keycode)keysym));
579   }
580   else if (action.jbut != -1)
581   {
582     snprintf(keyname, 64, "JBut %d", action.jbut);
583   }
584   else if (action.jaxis != -1)
585   {
586     if (action.jaxis_value > 0)
587       snprintf(keyname, 64, "JAxis %d+", action.jaxis);
588     else
589       snprintf(keyname, 64, "JAxis %d-", action.jaxis);
590   }
591   else if (action.jhat != -1)
592   {
593     if (action.jhat_value & SDL_HAT_LEFT)
594       snprintf(keyname, 64, "JHat %d L", action.jhat);
595     else if (action.jhat_value & SDL_HAT_RIGHT)
596       snprintf(keyname, 64, "JHat %d R", action.jhat);
597     else if (action.jhat_value & SDL_HAT_UP)
598       snprintf(keyname, 64, "JHat %d U", action.jhat);
599     else if (action.jhat_value & SDL_HAT_DOWN)
600       snprintf(keyname, 64, "JHat %d D", action.jhat);
601   }
602 
603   maxcpy(item->righttext, _(keyname).c_str(), sizeof(item->righttext) - 1);
604 }
605 
_edit_control(ODItem * item,int dir)606 static void _edit_control(ODItem *item, int dir)
607 {
608   Message *msg;
609 
610   opt.remapping_key     = item->id;
611   opt.new_sdl_key.key   = -1;
612   opt.new_sdl_key.jbut  = -1;
613   opt.new_sdl_key.jhat  = -1;
614   opt.new_sdl_key.jaxis = -1;
615 
616   msg               = new Message("Press new key for:", input_get_name(opt.remapping_key));
617   msg->rawKeyReturn = &opt.new_sdl_key;
618   msg->on_dismiss   = _finish_control_edit;
619 
620   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_DOOR);
621 }
622 
_finish_control_edit(Message * msg)623 static void _finish_control_edit(Message *msg)
624 {
625   int inputno           = opt.remapping_key;
626   in_action new_sdl_key = opt.new_sdl_key;
627   int i;
628   in_action action = input_get_mapping(inputno);
629 
630   // check if key is already in use
631   for (i = 0; i < INPUT_COUNT; i++)
632   {
633     action = input_get_mapping(i);
634     if (i != inputno && action.key != -1 && action.key == new_sdl_key.key)
635     {
636       new Message("Key already in use by:", input_get_name(i));
637       NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_GUN_CLICK);
638       return;
639     }
640 
641     if (i != inputno && action.jbut != -1 && action.jbut == new_sdl_key.jbut)
642     {
643       new Message("Key already in use by:", input_get_name(i));
644       NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_GUN_CLICK);
645       return;
646     }
647 
648     if (i != inputno && action.jhat != -1 && action.jhat == new_sdl_key.jhat
649         && action.jhat_value & new_sdl_key.jhat_value)
650     {
651       new Message("Key already in use by:", input_get_name(i));
652       NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_GUN_CLICK);
653       return;
654     }
655 
656     if (i != inputno && action.jaxis != -1 && action.jaxis == new_sdl_key.jaxis)
657     {
658       if (((action.jaxis_value > 0) && (new_sdl_key.jaxis_value > 0))
659           || ((action.jaxis_value < 0) && (new_sdl_key.jaxis_value < 0)))
660       {
661         new Message("Key already in use by:", input_get_name(i));
662         NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_GUN_CLICK);
663         return;
664       }
665     }
666   }
667 
668   input_remap(inputno, new_sdl_key);
669   NXE::Sound::SoundManager::getInstance()->playSfx(NXE::Sound::SFX::SND_MENU_SELECT);
670   opt.dlg->Refresh();
671 }
672