2019-06-11 21:47:24 +00:00
|
|
|
//
|
|
|
|
// QuadratureMouse.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 11/06/2019.
|
|
|
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef QuadratureMouse_hpp
|
|
|
|
#define QuadratureMouse_hpp
|
|
|
|
|
|
|
|
#include "../Mouse.hpp"
|
|
|
|
#include <atomic>
|
|
|
|
|
|
|
|
namespace Inputs {
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Provides a simple implementation of a Mouse, designed for simple
|
|
|
|
thread-safe feeding to a machine that accepts quadrature-encoded input.
|
|
|
|
*/
|
|
|
|
class QuadratureMouse: public Mouse {
|
|
|
|
public:
|
|
|
|
QuadratureMouse(int number_of_buttons) :
|
|
|
|
number_of_buttons_(number_of_buttons) {}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Inputs, to satisfy the Mouse interface.
|
|
|
|
*/
|
|
|
|
void move(int x, int y) override {
|
|
|
|
// Accumulate all provided motion.
|
|
|
|
axes_[0] += x;
|
|
|
|
axes_[1] += y;
|
|
|
|
}
|
|
|
|
|
|
|
|
int get_number_of_buttons() override {
|
|
|
|
return number_of_buttons_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_button_pressed(int index, bool is_pressed) override {
|
|
|
|
if(is_pressed)
|
|
|
|
button_flags_ |= (1 << index);
|
|
|
|
else
|
|
|
|
button_flags_ &= ~(1 << index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset_all_buttons() override {
|
|
|
|
button_flags_ = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Outputs.
|
|
|
|
*/
|
|
|
|
|
2019-06-11 23:52:37 +00:00
|
|
|
/*!
|
2019-06-12 21:51:50 +00:00
|
|
|
Applies a single step from the current accumulated mouse movement, which
|
|
|
|
might involve the mouse moving right, or left, or not at all.
|
2019-06-11 23:52:37 +00:00
|
|
|
*/
|
|
|
|
void prepare_step() {
|
|
|
|
for(int axis = 0; axis < 2; ++axis) {
|
|
|
|
const int axis_value = axes_[axis];
|
2019-06-12 21:51:50 +00:00
|
|
|
if(!axis_value) continue;
|
|
|
|
|
|
|
|
primaries_[axis] ^= 1;
|
|
|
|
secondaries_[axis] = primaries_[axis];
|
|
|
|
if(axis_value > 0) {
|
|
|
|
-- axes_[axis];
|
2019-06-13 02:19:25 +00:00
|
|
|
secondaries_[axis] ^= 1;
|
2019-06-11 23:52:37 +00:00
|
|
|
} else {
|
2019-06-12 21:51:50 +00:00
|
|
|
++ axes_[axis];
|
2019-06-11 23:52:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-11 21:47:24 +00:00
|
|
|
/*!
|
2019-06-12 21:51:50 +00:00
|
|
|
@returns the two quadrature channels — bit 0 is the 'primary' channel
|
|
|
|
(i.e. the one that can be monitored to observe velocity) and
|
|
|
|
bit 1 is the 'secondary' (i.e. that which can be queried to
|
|
|
|
observe direction).
|
2019-06-11 21:47:24 +00:00
|
|
|
*/
|
2019-06-12 21:51:50 +00:00
|
|
|
int get_channel(int axis) {
|
|
|
|
return primaries_[axis] | (secondaries_[axis] << 1);
|
2019-06-11 21:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@returns a bit mask of the currently pressed buttons.
|
|
|
|
*/
|
|
|
|
int get_button_mask() {
|
|
|
|
return button_flags_;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int number_of_buttons_ = 0;
|
|
|
|
std::atomic<int> button_flags_;
|
|
|
|
std::atomic<int> axes_[2];
|
|
|
|
|
2019-06-12 21:51:50 +00:00
|
|
|
int primaries_[2] = {0, 0};
|
|
|
|
int secondaries_[2] = {0, 0};
|
2019-06-11 21:47:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* QuadratureMouse_hpp */
|