g13gui/g13d/g13_stick.cc
June Tate-Gans ae6cf5084a g13d: Rework and cleanup namespaces and files
This is the first half of some major rework of the g13d codebase to make things
a bit more manageable. This splits out a great deal of stuff from helper.h into
separate translation units, and also breaks out a great deal of the g13.h header
into separate translation units as well.

Doing this saves in compilation time as we make changes to the system, and also
helps to clean up a whole bunch of leaking symbols.
2021-04-25 16:35:44 -05:00

182 lines
4.5 KiB
C++

/* This file contains code for managing keys and profiles
*
*/
#include <iomanip>
#include <iostream>
#include <boost/foreach.hpp>
#include "device.h"
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;
if (_stick_mode == STICK_CALBOUNDS) {
_bounds.tl = G13_StickCoord(255, 255);
_bounds.br = G13_StickCoord(0, 0);
}
}
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 << std::endl;
}
}
void G13_StickZone::dump(std::ostream &out) const {
out << " " << std::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;
default:
break;
};
// 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