mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Add delta capper.
This commit is contained in:
parent
1125286b96
commit
3e2a82b638
@ -15,24 +15,34 @@ using namespace Apple::ADB;
|
|||||||
Mouse::Mouse(Bus &bus) : ReactiveDevice(bus, 3) {}
|
Mouse::Mouse(Bus &bus) : ReactiveDevice(bus, 3) {}
|
||||||
|
|
||||||
void Mouse::perform_command(const Command &command) {
|
void Mouse::perform_command(const Command &command) {
|
||||||
if(command.type == Command::Type::Talk && command.reg == 0) {
|
static constexpr int16_t max_delta = 30;
|
||||||
// Read current deltas and buttons, thread safely.
|
|
||||||
auto delta_x = delta_x_.exchange(0);
|
|
||||||
auto delta_y = delta_y_.exchange(0);
|
|
||||||
const int buttons = button_flags_;
|
|
||||||
|
|
||||||
// Clamp deltas.
|
if(command.type == Command::Type::Talk && command.reg == 0) {
|
||||||
delta_x = std::clamp(delta_x, int16_t(-128), int16_t(127));
|
// Read and clamp current deltas and buttons.
|
||||||
delta_y = std::clamp(delta_y, int16_t(-128), int16_t(127));
|
//
|
||||||
|
// There's some small chance of creating negative feedback here — taking too much off delta_x_ or delta_y_
|
||||||
|
// due to a change in the underlying value between the load and the arithmetic. But if that occurs it means
|
||||||
|
// the user moved the mouse again in the interim, so it'll just play out as very slight latency.
|
||||||
|
auto delta_x = delta_x_.load(std::memory_order::memory_order_relaxed);
|
||||||
|
auto delta_y = delta_y_.load(std::memory_order::memory_order_relaxed);
|
||||||
|
if(abs(delta_x) > max_delta || abs(delta_y) > max_delta) {
|
||||||
|
int max = std::max(abs(delta_x), abs(delta_y));
|
||||||
|
delta_x = delta_x * max_delta / max;
|
||||||
|
delta_y = delta_y * max_delta / max;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int buttons = button_flags_.load(std::memory_order::memory_order_relaxed);
|
||||||
|
delta_x_ -= delta_x;
|
||||||
|
delta_y_ -= delta_y;
|
||||||
|
|
||||||
// Figure out what that would look like, and don't respond if there's
|
// Figure out what that would look like, and don't respond if there's
|
||||||
// no change to report.
|
// no change or deltas to report.
|
||||||
const uint16_t reg0 =
|
const uint16_t reg0 =
|
||||||
((buttons & 1) ? 0x0000 : 0x8000) |
|
((buttons & 1) ? 0x0000 : 0x8000) |
|
||||||
((buttons & 2) ? 0x0000 : 0x0080) |
|
((buttons & 2) ? 0x0000 : 0x0080) |
|
||||||
uint16_t(delta_x & 0x7f) |
|
uint16_t(delta_x & 0x7f) |
|
||||||
uint16_t((delta_y & 0x7f) << 8);
|
uint16_t((delta_y & 0x7f) << 8);
|
||||||
if(reg0 == last_posted_reg0_) return;
|
if(!(reg0 & 0x7f7f) && (reg0 & 0x8080) == (last_posted_reg0_ & 0x8080)) return;
|
||||||
|
|
||||||
// Post change.
|
// Post change.
|
||||||
last_posted_reg0_ = reg0;
|
last_posted_reg0_ = reg0;
|
||||||
@ -41,7 +51,6 @@ void Mouse::perform_command(const Command &command) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mouse::move(int x, int y) {
|
void Mouse::move(int x, int y) {
|
||||||
// TODO: cap movement speed, feeding changes in slowly.
|
|
||||||
delta_x_ += int16_t(x);
|
delta_x_ += int16_t(x);
|
||||||
delta_y_ += int16_t(y);
|
delta_y_ += int16_t(y);
|
||||||
post_service_request();
|
post_service_request();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user