1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Merge pull request #709 from TomHarte/MoreMouse

Adds Atari ST mouse support for absolute positioning and inverted scales.
This commit is contained in:
Thomas Harte 2020-01-01 13:56:25 -05:00 committed by GitHub
commit 2456fb120d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 33 deletions

View File

@ -11,8 +11,11 @@
#include <algorithm>
#include <cstring>
#define LOG_PREFIX "[MFP] "
#ifndef NDEBUG
#define NDEBUG
#endif
#define LOG_PREFIX "[MFP] "
#include "../../Outputs/Log.hpp"
using namespace Motorola::MFP68901;

View File

@ -8,6 +8,8 @@
#include "IntelligentKeyboard.hpp"
#include <algorithm>
#define LOG_PREFIX "[IKYB] "
#include "../../../Outputs/Log.hpp"
@ -22,6 +24,7 @@ IntelligentKeyboard::IntelligentKeyboard(Serial::Line &input, Serial::Line &outp
joysticks_.emplace_back(new Joystick);
mouse_button_state_ = 0;
mouse_button_events_ = 0;
mouse_movement_[0] = 0;
mouse_movement_[1] = 0;
}
@ -49,20 +52,38 @@ ClockingHint::Preference IntelligentKeyboard::preferred_clocking() {
void IntelligentKeyboard::run_for(HalfCycles duration) {
// Take this opportunity to check for joystick, mouse and keyboard events,
// which will have been received asynchronously.
if(mouse_mode_ == MouseMode::Relative) {
const int captured_movement[2] = { mouse_movement_[0].load(), mouse_movement_[1].load() };
const int captured_button_state = mouse_button_state_;
if(
(posted_button_state_ != captured_button_state) ||
(abs(captured_movement[0]) >= mouse_threshold_[0]) ||
(abs(captured_movement[1]) >= mouse_threshold_[1]) ) {
mouse_movement_[0] -= captured_movement[0];
mouse_movement_[1] -= captured_movement[1];
const int captured_movement[2] = { mouse_movement_[0].load(), mouse_movement_[1].load() };
switch(mouse_mode_) {
case MouseMode::Relative: {
const int captured_button_state = mouse_button_state_;
if(
(posted_button_state_ != captured_button_state) ||
(abs(captured_movement[0]) >= mouse_threshold_[0]) ||
(abs(captured_movement[1]) >= mouse_threshold_[1]) ) {
mouse_movement_[0] -= captured_movement[0];
mouse_movement_[1] -= captured_movement[1];
post_relative_mouse_event(captured_movement[0], captured_movement[1]);
}
} else {
// TODO: absolute-mode mouse updates.
post_relative_mouse_event(captured_movement[0], captured_movement[1] * mouse_y_multiplier_);
}
} break;
case MouseMode::Absolute: {
const int scaled_movement[2] = { captured_movement[0] / mouse_scale_[0], captured_movement[1] / mouse_scale_[1] };
mouse_position_[0] += scaled_movement[0];
mouse_position_[1] += mouse_y_multiplier_ * scaled_movement[1];
// Clamp to range.
mouse_position_[0] = std::min(std::max(mouse_position_[0], 0), mouse_range_[0]);
mouse_position_[1] = std::min(std::max(mouse_position_[1], 0), mouse_range_[1]);
mouse_movement_[0] -= scaled_movement[0] * mouse_scale_[0];
mouse_movement_[1] -= scaled_movement[1] * mouse_scale_[1];
} break;
case MouseMode::Disabled:
mouse_movement_[0] = 0;
mouse_movement_[1] = 0;
break;
}
// Forward key changes; implicit assumption here: mutexs are cheap while there's
@ -219,19 +240,22 @@ void IntelligentKeyboard::pause() {
}
void IntelligentKeyboard::disable_mouse() {
LOG("Unimplemented: disable mouse");
mouse_mode_ = MouseMode::Disabled;
}
void IntelligentKeyboard::set_relative_mouse_position_reporting() {
LOG("Unimplemented: set relative mouse position reporting");
mouse_mode_ = MouseMode::Relative;
}
void IntelligentKeyboard::set_absolute_mouse_position_reporting(uint16_t max_x, uint16_t max_y) {
LOG("Unimplemented: set absolute mouse position reporting");
mouse_mode_ = MouseMode::Absolute;
mouse_range_[0] = int(max_x);
mouse_range_[1] = int(max_y);
}
void IntelligentKeyboard::set_mouse_position(uint16_t x, uint16_t y) {
LOG("Unimplemented: set mouse position");
mouse_position_[0] = std::min(int(x), mouse_range_[0]);
mouse_position_[1] = std::min(int(y), mouse_range_[1]);
}
void IntelligentKeyboard::set_mouse_keycode_reporting(uint8_t delta_x, uint8_t delta_y) {
@ -239,19 +263,21 @@ void IntelligentKeyboard::set_mouse_keycode_reporting(uint8_t delta_x, uint8_t d
}
void IntelligentKeyboard::set_mouse_threshold(uint8_t x, uint8_t y) {
LOG("Unimplemented: set mouse threshold");
mouse_threshold_[0] = x;
mouse_threshold_[1] = y;
}
void IntelligentKeyboard::set_mouse_scale(uint8_t x, uint8_t y) {
LOG("Unimplemented: set mouse scale");
mouse_scale_[0] = x;
mouse_scale_[1] = y;
}
void IntelligentKeyboard::set_mouse_y_downward() {
LOG("Unimplemented: set mouse y downward");
mouse_y_multiplier_ = 1;
}
void IntelligentKeyboard::set_mouse_y_upward() {
LOG("Unimplemented: set mouse y upward");
mouse_y_multiplier_ = -1;
}
void IntelligentKeyboard::set_mouse_button_actions(uint8_t actions) {
@ -259,14 +285,15 @@ void IntelligentKeyboard::set_mouse_button_actions(uint8_t actions) {
}
void IntelligentKeyboard::interrogate_mouse_position() {
LOG("Unimplemented: interrogate mouse position");
const int captured_mouse_button_events_ = mouse_button_events_;
mouse_button_events_ &= ~captured_mouse_button_events_;
output_bytes({
0xf7, // Beginning of mouse response.
0x00, // 0000dcba; a = right button down since last interrogation, b = right button up since, c/d = left button.
0x00, // x motion: MSB, LSB
0x00,
0x00, // y motion: MSB, LSB
0x00
0xf7, // Beginning of mouse response.
uint8_t(captured_mouse_button_events_), // 0000dcba; a = right button down since last interrogation, b = right button up since, c/d = left button.
uint8_t(mouse_position_[0] >> 8), // x position: MSB, LSB
uint8_t(mouse_position_[0] & 0xff),
uint8_t(mouse_position_[1] >> 8), // y position: MSB, LSB
uint8_t(mouse_position_[1] & 0xff)
});
}
@ -374,11 +401,16 @@ int IntelligentKeyboard::get_number_of_buttons() {
}
void IntelligentKeyboard::set_button_pressed(int index, bool is_pressed) {
const auto mask = 1 << (index ^ 1); // The primary button is b1; the secondary is b0.
index ^= 1; // The primary button is b1; the secondary is b0.
const auto mask = 1 << index;
const auto event_mask = 1 << (index << 1);
if(is_pressed) {
mouse_button_state_ |= mask;
mouse_button_events_ |= event_mask;
} else {
mouse_button_state_ &= ~mask;
mouse_button_events_ |= event_mask << 1;
}
}

View File

@ -110,12 +110,14 @@ class IntelligentKeyboard:
void reset_all_buttons() final;
enum class MouseMode {
Relative, Absolute
Relative, Absolute, Disabled
} mouse_mode_ = MouseMode::Relative;
// Absolute positioning state.
int mouse_range_[2] = {0, 0};
int mouse_scale_[2] = {0, 0};
int mouse_range_[2] = {320, 200};
int mouse_scale_[2] = {1, 1};
int mouse_position_[2] = {0, 0};
int mouse_y_multiplier_ = 1;
// Relative positioning state.
int posted_button_state_ = 0;
@ -125,6 +127,7 @@ class IntelligentKeyboard:
// Received mouse state.
std::atomic<int> mouse_movement_[2];
std::atomic<int> mouse_button_state_;
std::atomic<int> mouse_button_events_;
// MARK: - Joystick.
void disable_joysticks();