g13gui/g13d/g13_stick.cc
2021-04-25 14:39:54 -05:00

170 lines
4.4 KiB
C++

/* This file contains code for managing keys and profiles
*
*/
#include "g13.h"
using namespace std;
namespace G13 {
// *************************************************************************
void G13_Device::parse_joystick(unsigned char *buf) {
_stick.parse_joystick(buf);
}
G13_Stick::G13_Stick(G13_Device &keypad)
: _keypad(keypad), _bounds(0, 0, 255, 255), _center_pos(127, 127),
_north_pos(127, 0) {
_stick_mode = STICK_KEYS;
auto add_zone = [this, &keypad](const std::string &name, double x1, double y1,
double x2, double y2) {
_zones.push_back(G13_StickZone(
*this, "STICK_" + name, G13_ZoneBounds(x1, y1, x2, y2),
G13_ActionPtr(new G13_Action_Keys(keypad, "KEY_" + name))));
};
add_zone("UP", 0.0, 0.1, 1.0, 0.3);
add_zone("DOWN", 0.0, 0.7, 1.0, 0.9);
add_zone("LEFT", 0.0, 0.0, 0.2, 1.0);
add_zone("RIGHT", 0.8, 0.0, 1.0, 1.0);
add_zone("PAGEUP", 0.0, 0.0, 1.0, 0.1);
add_zone("PAGEDOWN", 0.0, 0.9, 1.0, 1.0);
}
G13_StickZone *G13_Stick::zone(const std::string &name, bool create) {
BOOST_FOREACH (G13_StickZone &zone, _zones) {
if (zone.name() == name) {
return &zone;
}
}
if (create) {
_zones.push_back(
G13_StickZone(*this, name, G13_ZoneBounds(0.0, 0.0, 0.0, 0.0)));
return zone(name);
}
return 0;
}
void G13_Stick::set_mode(stick_mode_t m) {
if (m == _stick_mode)
return;
if (_stick_mode == STICK_CALCENTER || _stick_mode == STICK_CALBOUNDS ||
_stick_mode == STICK_CALNORTH) {
_recalc_calibrated();
}
_stick_mode = m;
switch (_stick_mode) {
case STICK_CALBOUNDS:
_bounds.tl = G13_StickCoord(255, 255);
_bounds.br = G13_StickCoord(0, 0);
break;
}
}
void G13_Stick::_recalc_calibrated() {}
void G13_Stick::remove_zone(const G13_StickZone &zone) {
G13_StickZone target(zone);
_zones.erase(std::remove(_zones.begin(), _zones.end(), target), _zones.end());
}
void G13_Stick::dump(std::ostream &out) const {
BOOST_FOREACH (const G13_StickZone &zone, _zones) {
zone.dump(out);
out << endl;
}
}
void G13_StickZone::dump(std::ostream &out) const {
out << " " << setw(20) << name() << " " << _bounds << " ";
if (action()) {
action()->dump(out);
} else {
out << " (no action)";
}
}
void G13_StickZone::test(const G13_ZoneCoord &loc) {
if (!_action)
return;
bool prior_active = _active;
_active = _bounds.contains(loc);
if (!_active) {
if (prior_active) {
// cout << "exit stick zone " << _name << std::endl;
_action->act(false);
}
} else {
// cout << "in stick zone " << _name << std::endl;
_action->act(true);
}
}
G13_StickZone::G13_StickZone(G13_Stick &stick, const std::string &name,
const G13_ZoneBounds &b, G13_ActionPtr action)
: G13_Actionable<G13_Stick>(stick, name), _active(false), _bounds(b) {
set_action(action);
}
void G13_Stick::parse_joystick(unsigned char *buf) {
_current_pos.x = buf[1];
_current_pos.y = buf[2];
// update targets if we're in calibration mode
switch (_stick_mode) {
case STICK_CALCENTER:
_center_pos = _current_pos;
return;
case STICK_CALNORTH:
_north_pos = _current_pos;
return;
case STICK_CALBOUNDS:
_bounds.expand(_current_pos);
return;
};
// determine our normalized position
double dx = 0.5;
if (_current_pos.x <= _center_pos.x) {
dx = _current_pos.x - _bounds.tl.x;
dx /= (_center_pos.x - _bounds.tl.x) * 2;
} else {
dx = _bounds.br.x - _current_pos.x;
dx /= (_bounds.br.x - _center_pos.x) * 2;
dx = 1.0 - dx;
}
double dy = 0.5;
if (_current_pos.y <= _center_pos.y) {
dy = _current_pos.y - _bounds.tl.y;
dy /= (_center_pos.y - _bounds.tl.y) * 2;
} else {
dy = _bounds.br.y - _current_pos.y;
dy /= (_bounds.br.y - _center_pos.y) * 2;
dy = 1.0 - dy;
}
G13_LOG(trace, "x=" << _current_pos.x << " y=" << _current_pos.y
<< " dx=" << dx << " dy=" << dy);
G13_ZoneCoord jpos(dx, dy);
if (_stick_mode == STICK_ABSOLUTE) {
_keypad.send_event(EV_ABS, ABS_X, _current_pos.x);
_keypad.send_event(EV_ABS, ABS_Y, _current_pos.y);
} else if (_stick_mode == STICK_KEYS) {
BOOST_FOREACH (G13_StickZone &zone, _zones) { zone.test(jpos); }
return;
} else {
/* send_event(g13->uinput_file, EV_REL, REL_X, stick_x/16 - 8);
send_event(g13->uinput_file, EV_REL, REL_Y, stick_y/16 - 8);*/
}
}
} // namespace G13