mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-18 16:30:29 +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:
commit
2456fb120d
@ -11,8 +11,11 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#define LOG_PREFIX "[MFP] "
|
#ifndef NDEBUG
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LOG_PREFIX "[MFP] "
|
||||||
#include "../../Outputs/Log.hpp"
|
#include "../../Outputs/Log.hpp"
|
||||||
|
|
||||||
using namespace Motorola::MFP68901;
|
using namespace Motorola::MFP68901;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "IntelligentKeyboard.hpp"
|
#include "IntelligentKeyboard.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#define LOG_PREFIX "[IKYB] "
|
#define LOG_PREFIX "[IKYB] "
|
||||||
#include "../../../Outputs/Log.hpp"
|
#include "../../../Outputs/Log.hpp"
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ IntelligentKeyboard::IntelligentKeyboard(Serial::Line &input, Serial::Line &outp
|
|||||||
joysticks_.emplace_back(new Joystick);
|
joysticks_.emplace_back(new Joystick);
|
||||||
|
|
||||||
mouse_button_state_ = 0;
|
mouse_button_state_ = 0;
|
||||||
|
mouse_button_events_ = 0;
|
||||||
mouse_movement_[0] = 0;
|
mouse_movement_[0] = 0;
|
||||||
mouse_movement_[1] = 0;
|
mouse_movement_[1] = 0;
|
||||||
}
|
}
|
||||||
@ -49,20 +52,38 @@ ClockingHint::Preference IntelligentKeyboard::preferred_clocking() {
|
|||||||
void IntelligentKeyboard::run_for(HalfCycles duration) {
|
void IntelligentKeyboard::run_for(HalfCycles duration) {
|
||||||
// Take this opportunity to check for joystick, mouse and keyboard events,
|
// Take this opportunity to check for joystick, mouse and keyboard events,
|
||||||
// which will have been received asynchronously.
|
// 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_movement[2] = { mouse_movement_[0].load(), mouse_movement_[1].load() };
|
switch(mouse_mode_) {
|
||||||
const int captured_button_state = mouse_button_state_;
|
case MouseMode::Relative: {
|
||||||
if(
|
const int captured_button_state = mouse_button_state_;
|
||||||
(posted_button_state_ != captured_button_state) ||
|
if(
|
||||||
(abs(captured_movement[0]) >= mouse_threshold_[0]) ||
|
(posted_button_state_ != captured_button_state) ||
|
||||||
(abs(captured_movement[1]) >= mouse_threshold_[1]) ) {
|
(abs(captured_movement[0]) >= mouse_threshold_[0]) ||
|
||||||
mouse_movement_[0] -= captured_movement[0];
|
(abs(captured_movement[1]) >= mouse_threshold_[1]) ) {
|
||||||
mouse_movement_[1] -= captured_movement[1];
|
mouse_movement_[0] -= captured_movement[0];
|
||||||
|
mouse_movement_[1] -= captured_movement[1];
|
||||||
|
|
||||||
post_relative_mouse_event(captured_movement[0], captured_movement[1]);
|
post_relative_mouse_event(captured_movement[0], captured_movement[1] * mouse_y_multiplier_);
|
||||||
}
|
}
|
||||||
} else {
|
} break;
|
||||||
// TODO: absolute-mode mouse updates.
|
|
||||||
|
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
|
// Forward key changes; implicit assumption here: mutexs are cheap while there's
|
||||||
@ -219,19 +240,22 @@ void IntelligentKeyboard::pause() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IntelligentKeyboard::disable_mouse() {
|
void IntelligentKeyboard::disable_mouse() {
|
||||||
LOG("Unimplemented: disable mouse");
|
mouse_mode_ = MouseMode::Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntelligentKeyboard::set_relative_mouse_position_reporting() {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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() {
|
void IntelligentKeyboard::set_mouse_y_downward() {
|
||||||
LOG("Unimplemented: set mouse y downward");
|
mouse_y_multiplier_ = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntelligentKeyboard::set_mouse_y_upward() {
|
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) {
|
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() {
|
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({
|
output_bytes({
|
||||||
0xf7, // Beginning of mouse response.
|
0xf7, // Beginning of mouse response.
|
||||||
0x00, // 0000dcba; a = right button down since last interrogation, b = right button up since, c/d = left button.
|
uint8_t(captured_mouse_button_events_), // 0000dcba; a = right button down since last interrogation, b = right button up since, c/d = left button.
|
||||||
0x00, // x motion: MSB, LSB
|
uint8_t(mouse_position_[0] >> 8), // x position: MSB, LSB
|
||||||
0x00,
|
uint8_t(mouse_position_[0] & 0xff),
|
||||||
0x00, // y motion: MSB, LSB
|
uint8_t(mouse_position_[1] >> 8), // y position: MSB, LSB
|
||||||
0x00
|
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) {
|
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) {
|
if(is_pressed) {
|
||||||
mouse_button_state_ |= mask;
|
mouse_button_state_ |= mask;
|
||||||
|
mouse_button_events_ |= event_mask;
|
||||||
} else {
|
} else {
|
||||||
mouse_button_state_ &= ~mask;
|
mouse_button_state_ &= ~mask;
|
||||||
|
mouse_button_events_ |= event_mask << 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,12 +110,14 @@ class IntelligentKeyboard:
|
|||||||
void reset_all_buttons() final;
|
void reset_all_buttons() final;
|
||||||
|
|
||||||
enum class MouseMode {
|
enum class MouseMode {
|
||||||
Relative, Absolute
|
Relative, Absolute, Disabled
|
||||||
} mouse_mode_ = MouseMode::Relative;
|
} mouse_mode_ = MouseMode::Relative;
|
||||||
|
|
||||||
// Absolute positioning state.
|
// Absolute positioning state.
|
||||||
int mouse_range_[2] = {0, 0};
|
int mouse_range_[2] = {320, 200};
|
||||||
int mouse_scale_[2] = {0, 0};
|
int mouse_scale_[2] = {1, 1};
|
||||||
|
int mouse_position_[2] = {0, 0};
|
||||||
|
int mouse_y_multiplier_ = 1;
|
||||||
|
|
||||||
// Relative positioning state.
|
// Relative positioning state.
|
||||||
int posted_button_state_ = 0;
|
int posted_button_state_ = 0;
|
||||||
@ -125,6 +127,7 @@ class IntelligentKeyboard:
|
|||||||
// Received mouse state.
|
// Received mouse state.
|
||||||
std::atomic<int> mouse_movement_[2];
|
std::atomic<int> mouse_movement_[2];
|
||||||
std::atomic<int> mouse_button_state_;
|
std::atomic<int> mouse_button_state_;
|
||||||
|
std::atomic<int> mouse_button_events_;
|
||||||
|
|
||||||
// MARK: - Joystick.
|
// MARK: - Joystick.
|
||||||
void disable_joysticks();
|
void disable_joysticks();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user