Clean up library includes
[lsnes.git] / src / library / joyfun.cpp
blob30397ec2028715e245aadb153ebfffc2a5ac5e42
1 #include "joyfun.hpp"
2 #include "string.hpp"
3 #include <sstream>
4 #include <iostream>
6 short calibration_correction(int64_t v, int64_t low, int64_t high)
8 double _v = v;
9 double _low = low;
10 double _high = high;
11 double _pos = 65535 * (_v - _low) / (_high - _low) - 32768;
12 if(_pos < -32768)
13 return -32768;
14 else if(_pos > 32767)
15 return 32767;
16 else
17 return static_cast<short>(_pos);
20 short angle_to_bitmask(int pov)
22 short m = 0;
23 if((pov >= 0 && pov <= 6000) || (pov >= 30000 && pov <= 36000))
24 m |= 1;
25 if(pov >= 3000 && pov <= 15000)
26 m |= 2;
27 if(pov >= 12000 && pov <= 24000)
28 m |= 4;
29 if(pov >= 21000 && pov <= 33000)
30 m |= 8;
31 return m;
34 joystick_model::change_info::change_info()
36 has_been_read = false;
37 last_read = 0;
38 last_known = 0;
41 void joystick_model::change_info::update(short newv)
43 last_known = newv;
46 bool joystick_model::change_info::read(short& val)
48 bool r = (last_known != last_read || !has_been_read);
49 has_been_read = true;
50 val = last_read = last_known;
51 return r;
54 bool joystick_model::read_common(std::vector<change_info>& i, unsigned id, short& res)
56 if(id >= i.size())
57 return false;
58 return i[id].read(res);
61 unsigned joystick_model::size_common(std::vector<change_info>& i)
63 return i.size();
66 void joystick_model::report_button(uint64_t id, bool value)
68 if(button_map.count(id))
69 _buttons[button_map[id]].update(value ? 1 : 0);
72 void joystick_model::report_pov(uint64_t id, int angle)
74 if(pov_map.count(id))
75 _hats[pov_map[id]].update(angle_to_bitmask(angle));
78 void joystick_model::report_axis(uint64_t id, int64_t value)
80 //The axis case.
81 if(axis_map.count(id))
82 _axes[axis_map[id]].update(calibration_correction(value, aranges[id].first, aranges[id].second));
83 //It isn't known axis. See if it is connected with axis pair for hat.
84 else if(hataxis_map.count(id)) {
85 struct hat_axis_info& ai = hataxis_map[id];
86 struct hat_info& hi = hatinfos[ai.hnum];
87 short v = 0;
88 if(value <= -ai.mindev) v = -1;
89 if(value >= ai.mindev) v = 1;
90 if(ai.yflag) hi.ystate = v;
91 else hi.xstate = v;
92 v = 0;
93 if(hi.ystate < 0) v |= 1;
94 if(hi.xstate > 0) v |= 2;
95 if(hi.ystate > 0) v |= 4;
96 if(hi.xstate < 0) v |= 8;
97 _hats[ai.hnum].update(v);
101 unsigned joystick_model::new_axis(uint64_t id, int64_t minv, int64_t maxv, const std::string& xname)
103 unsigned n = axes();
104 aranges[id] = std::make_pair(minv, maxv);
105 _axes.resize(n + 1);
106 axis_map[id] = n;
107 axisnames[n] = xname;
108 return n;
111 unsigned joystick_model::new_button(uint64_t id, const std::string& xname)
113 unsigned n = buttons();
114 _buttons.resize(n + 1);
115 button_map[id] = n;
116 buttonnames[n] = xname;
117 return n;
120 unsigned joystick_model::new_hat(uint64_t id_x, uint64_t id_y, int64_t min_dev, const std::string& xname_x,
121 const std::string& xname_y)
123 unsigned n = hats();
124 hatinfos.resize(n + 1);
125 hatinfos[n].xstate = 0;
126 hatinfos[n].ystate = 0;
127 _hats.resize(n + 1);
128 hataxis_map[id_x].yflag = false;
129 hataxis_map[id_x].hnum = n;
130 hataxis_map[id_x].mindev = min_dev;
131 hataxis_map[id_y].yflag = true;
132 hataxis_map[id_y].hnum = n;
133 hataxis_map[id_y].mindev = min_dev;
134 hatnames[n] = "<X: " + xname_x + " Y: " + xname_y + ">";
135 return n;
138 unsigned joystick_model::new_hat(uint64_t id, const std::string& xname)
140 unsigned n = hats();
141 _hats.resize(n + 1);
142 pov_map[id] = n;
143 hatnames[n] = xname;
144 return n;
147 std::pair<int64_t, int64_t> joystick_model::axiscalibration(unsigned id)
149 for(auto i : axis_map)
150 if(i.second == id)
151 return aranges[i.first];
152 return std::make_pair(0, 0);
155 std::string joystick_model::axisname(unsigned id)
157 if(axisnames.count(id)) return axisnames[id];
158 else return "";
161 std::string joystick_model::buttonname(unsigned id)
163 if(buttonnames.count(id)) return buttonnames[id];
164 else return "";
167 std::string joystick_model::hatname(unsigned id)
169 if(hatnames.count(id)) return hatnames[id];
170 else return "";
173 void joystick_model::name(const std::string& newn)
175 joyname = newn;
178 const std::string& joystick_model::name()
180 return joyname;
183 std::string joystick_model::compose_report(unsigned jnum)
185 std::ostringstream out;
186 out << "Joystick #" << jnum << ": " << joyname << std::endl;
187 for(size_t i = 0; i < _axes.size(); i++) {
188 auto c = axiscalibration(i);
189 out << " Axis #" << i << ": " << axisnames[i] << "(" << c.first << " - " << c.second << ")"
190 << std::endl;
192 for(size_t i = 0; i < _buttons.size(); i++)
193 out << " Button #" << i << ": " << buttonnames[i] << std::endl;
194 for(size_t i = 0; i < _hats.size(); i++)
195 out << " Hat #" << i << ": " << hatnames[i] << std::endl;
196 return out.str();