mirror of
https://github.com/jtgans/g13gui.git
synced 2025-06-20 08:23:50 -04:00
Late night hacking causes all kinds of silliness. We only want to stop running an action when the key is not pressed now, but was prior pressed. My logic caused it to fire when not pressed and not prior pressed, erroneously, leading to stuck keys.
174 lines
4.0 KiB
C++
174 lines
4.0 KiB
C++
/* This file contains code for managing keys and profiles
|
|
*
|
|
*/
|
|
|
|
#include <boost/foreach.hpp>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
|
|
#include "device.h"
|
|
|
|
namespace G13 {
|
|
|
|
Stick::Stick(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(StickZone(
|
|
*this, "STICK_" + name, ZoneBounds(x1, y1, x2, y2),
|
|
ActionPtr(new 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);
|
|
}
|
|
|
|
StickZone *Stick::zone(const std::string &name, bool create) {
|
|
BOOST_FOREACH (StickZone &zone, _zones) {
|
|
if (zone.name() == name) {
|
|
return &zone;
|
|
}
|
|
}
|
|
|
|
if (create) {
|
|
_zones.push_back(
|
|
StickZone(*this, name, ZoneBounds(0.0, 0.0, 0.0, 0.0)));
|
|
return zone(name);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void 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 = StickCoord(255, 255);
|
|
_bounds.br = StickCoord(0, 0);
|
|
}
|
|
}
|
|
|
|
void Stick::_recalc_calibrated() {
|
|
}
|
|
|
|
void Stick::remove_zone(const StickZone &zone) {
|
|
StickZone target(zone);
|
|
_zones.erase(std::remove(_zones.begin(), _zones.end(), target), _zones.end());
|
|
}
|
|
|
|
void Stick::dump(std::ostream &out) const {
|
|
BOOST_FOREACH (const StickZone &zone, _zones) {
|
|
zone.dump(out);
|
|
out << std::endl;
|
|
}
|
|
}
|
|
|
|
void StickZone::dump(std::ostream &out) const {
|
|
out << " " << std::setw(20) << name() << " " << _bounds << " ";
|
|
|
|
if (action()) {
|
|
action()->dump(out);
|
|
} else {
|
|
out << " (no action)";
|
|
}
|
|
}
|
|
|
|
void StickZone::test(const ZoneCoord &loc) {
|
|
if (!_action) return;
|
|
|
|
bool prior_active = _active;
|
|
_active = _bounds.contains(loc);
|
|
|
|
if (!_active) {
|
|
if (prior_active) {
|
|
_action->act(false);
|
|
}
|
|
} else {
|
|
_action->act(true);
|
|
}
|
|
}
|
|
|
|
StickZone::StickZone(Stick &stick, const std::string &name,
|
|
const ZoneBounds &b, ActionPtr action)
|
|
: Actionable<Stick>(stick, name),
|
|
_active(false),
|
|
_bounds(b) {
|
|
set_action(action);
|
|
}
|
|
|
|
void 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);
|
|
|
|
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 (StickZone &zone, _zones) { zone.test(jpos); }
|
|
return;
|
|
}
|
|
}
|
|
|
|
} // namespace G13
|