Reinitialize gamepads command and fix EVDEV going bonkers on gamepad suddenly disconn...
[lsnes.git] / src / core / keymapper.cpp
blob36b92cee92756a8253e06924a8cbaf6cf2fe5499
1 #include "core/command.hpp"
2 #include "core/instance.hpp"
3 #include "core/joystickapi.hpp"
4 #include "core/keymapper.hpp"
5 #include "core/memorymanip.hpp"
6 #include "core/messages.hpp"
7 #include "core/queue.hpp"
8 #include "library/globalwrap.hpp"
9 #include "library/string.hpp"
10 #include "library/zip.hpp"
11 #include "lua/lua.hpp"
13 #include <stdexcept>
14 #include <stdexcept>
15 #include <iostream>
16 #include <list>
17 #include <map>
18 #include <sstream>
19 #include <set>
21 keyboard::invbind_set lsnes_invbinds;
22 gamepad::set lsnes_gamepads;
24 namespace
26 globalwrap<std::map<std::pair<unsigned, unsigned>, keyboard::key*>> buttons;
27 globalwrap<std::map<std::pair<unsigned, unsigned>, keyboard::key*>> axes;
28 globalwrap<std::map<std::pair<unsigned, unsigned>, keyboard::key*>> hats;
31 void lsnes_gamepads_init()
33 lsnes_gamepads.set_button_cb([](unsigned jnum, unsigned num, bool val) {
34 if(!buttons().count(std::make_pair(jnum, num)))
35 return;
36 lsnes_instance.iqueue->queue(keypress_info(keyboard::modifier_set(), *buttons()[std::make_pair(jnum,
37 num)], val));
38 });
39 lsnes_gamepads.set_hat_cb([](unsigned jnum, unsigned num, unsigned val) {
40 if(!hats().count(std::make_pair(jnum, num)))
41 return;
42 lsnes_instance.iqueue->queue(keypress_info(keyboard::modifier_set(), *hats()[std::make_pair(
43 jnum, num)], val));
44 });
45 lsnes_gamepads.set_axis_cb([](unsigned jnum, unsigned num, int16_t val) {
46 if(!axes().count(std::make_pair(jnum, num)))
47 return;
48 lsnes_instance.iqueue->queue(keypress_info(keyboard::modifier_set(), *axes()[std::make_pair(jnum,
49 num)], val));
50 });
51 lsnes_gamepads.set_axismode_cb([](unsigned jnum, unsigned num, int mode, double tolerance) {
52 if(!axes().count(std::make_pair(jnum, num)))
53 return;
54 axes()[std::make_pair(jnum, num)]->cast_axis()->set_mode(mode, tolerance);
55 });
56 lsnes_gamepads.set_newitem_cb([](unsigned jnum, unsigned num, int type) {
57 if(type == 0) {
58 std::string name = (stringfmt() << "joystick" << jnum << "axis" << num).str();
59 int mode = lsnes_gamepads[jnum].get_mode(num);
60 axes()[std::make_pair(jnum, num)] = new keyboard::key_axis(*lsnes_instance.keyboard, name,
61 "joystick", mode);
62 //Axis.
63 } else if(type == 1) {
64 std::string name = (stringfmt() << "joystick" << jnum << "button" << num).str();
65 buttons()[std::make_pair(jnum, num)] = new keyboard::key_key(*lsnes_instance.keyboard, name,
66 "joystick");
67 //Button.
68 } else if(type == 2) {
69 std::string name = (stringfmt() << "joystick" << jnum << "hat" << num).str();
70 hats()[std::make_pair(jnum, num)] = new keyboard::key_hat(*lsnes_instance.keyboard, name,
71 "joystick");
72 //Hat.
74 });
75 try {
76 auto cfg = zip::readrel(get_config_path() + "/gamepads.json", "");
77 std::string _cfg(cfg.begin(), cfg.end());
78 JSON::node config(_cfg);
79 lsnes_gamepads.load(config);
80 } catch(...) {
84 void lsnes_gamepads_deinit()
86 std::ofstream cfg(get_config_path() + "/gamepads.json");
87 JSON::printer_indenting printer;
88 if(cfg)
89 cfg << lsnes_gamepads.save().serialize(&printer);
92 void cleanup_keymapper()
94 for(auto i : buttons()) delete i.second;
95 for(auto i : axes()) delete i.second;
96 for(auto i : hats()) delete i.second;
99 namespace
101 command::fnptr<> CMD_show_joysticks(lsnes_cmds, "show-joysticks", "Show joystick info",
102 "Syntax: show-joysticks\nShow joystick info.\n",
103 []() throw(std::bad_alloc, std::runtime_error) {
104 messages << "--------------------------------------------" << std::endl;
105 messages << lsnes_gamepads.get_summary() << std::endl;
106 messages << "--------------------------------------------" << std::endl;
109 command::fnptr<> reset_joysticks(lsnes_cmds, "reset-gamepads", "Reset gamepads",
110 "Syntax: reset-gamepads\nResets gamepads.\n",
111 []() throw(std::bad_alloc, std::runtime_error) {
112 joystick_driver_quit();
113 lsnes_gamepads.offline_all(); //Not supposed to have online gamepads.
114 joystick_driver_init();
115 messages << "Reset gamepads" << std::endl;