mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-26 15:32:04 +00:00
Takes a shot at an ADB mouse.
This commit is contained in:
parent
e16d5f33d1
commit
fa8236741d
@ -12,5 +12,51 @@ using namespace Apple::ADB;
|
||||
|
||||
Mouse::Mouse(Bus &bus) : ReactiveDevice(bus, 3) {}
|
||||
|
||||
void Mouse::perform_command(const Command &) {
|
||||
void Mouse::perform_command(const Command &command) {
|
||||
if(command.type == Command::Type::Talk && command.reg == 0) {
|
||||
// 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.
|
||||
delta_x = std::max(std::min(delta_x, int16_t(127)), int16_t(-128));
|
||||
delta_y = std::max(std::min(delta_y, int16_t(127)), int16_t(-128));
|
||||
|
||||
// Figure out what that would look like, and don't respond if there's
|
||||
// no change to report.
|
||||
const uint16_t reg0 =
|
||||
((buttons & 1) ? 0x0000 : 0x8000) |
|
||||
((buttons & 2) ? 0x0000 : 0x0080) |
|
||||
uint16_t(delta_x & 0x7f) |
|
||||
uint16_t((delta_y & 0x7f) << 8);
|
||||
if(reg0 == last_posted_reg0_) return;
|
||||
|
||||
// Post change.
|
||||
last_posted_reg0_ = reg0;
|
||||
post_response({uint8_t(reg0 >> 8), uint8_t(reg0)});
|
||||
}
|
||||
}
|
||||
|
||||
void Mouse::move(int x, int y) {
|
||||
delta_x_ += int16_t(x);
|
||||
delta_y_ += int16_t(y);
|
||||
post_service_request();
|
||||
}
|
||||
|
||||
int Mouse::get_number_of_buttons() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void Mouse::set_button_pressed(int index, bool is_pressed) {
|
||||
if(is_pressed)
|
||||
button_flags_ |= (1 << index);
|
||||
else
|
||||
button_flags_ &= ~(1 << index);
|
||||
post_service_request();
|
||||
}
|
||||
|
||||
void Mouse::reset_all_buttons() {
|
||||
button_flags_ = 0;
|
||||
post_service_request();
|
||||
}
|
||||
|
@ -10,16 +10,26 @@
|
||||
#define Mouse_hpp
|
||||
|
||||
#include "ReactiveDevice.hpp"
|
||||
#include "../../../Inputs/Mouse.hpp"
|
||||
|
||||
namespace Apple {
|
||||
namespace ADB {
|
||||
|
||||
class Mouse: public ReactiveDevice {
|
||||
class Mouse: public ReactiveDevice, public Inputs::Mouse {
|
||||
public:
|
||||
Mouse(Bus &);
|
||||
|
||||
private:
|
||||
void perform_command(const Command &command) override;
|
||||
|
||||
void move(int x, int y) override;
|
||||
int get_number_of_buttons() override;
|
||||
void set_button_pressed(int index, bool is_pressed) override;
|
||||
void reset_all_buttons() override;
|
||||
|
||||
std::atomic<int16_t> delta_x_, delta_y_;
|
||||
std::atomic<int> button_flags_ = 0;
|
||||
uint16_t last_posted_reg0_ = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
|
||||
phase_ = Phase::AwaitingAttention;
|
||||
|
||||
command_ = decode_command(value);
|
||||
LOG(command_);
|
||||
// LOG(command_);
|
||||
|
||||
// If this command doesn't apply here, but a service request is requested,
|
||||
// post a service request.
|
||||
|
@ -45,10 +45,16 @@ class GLU: public InstructionSet::M50740::PortHandler {
|
||||
bool get_option_button() const;
|
||||
|
||||
void set_vertical_blank(bool);
|
||||
bool get_vertical_blank() {
|
||||
return vertical_blank_;
|
||||
}
|
||||
|
||||
Apple::ADB::Keyboard &keyboard() {
|
||||
return keyboard_;
|
||||
}
|
||||
Inputs::Mouse &get_mouse() {
|
||||
return mouse_;
|
||||
}
|
||||
|
||||
private:
|
||||
InstructionSet::M50740::Executor executor_;
|
||||
@ -70,6 +76,8 @@ class GLU: public InstructionSet::M50740::PortHandler {
|
||||
|
||||
uint8_t modifier_state_ = 0;
|
||||
|
||||
bool vertical_blank_ = false;
|
||||
|
||||
// For now, attach only a keyboard and mouse.
|
||||
Apple::ADB::Mouse mouse_;
|
||||
Apple::ADB::Keyboard keyboard_;
|
||||
|
@ -52,6 +52,7 @@ class ConcreteMachine:
|
||||
public MachineTypes::ScanProducer,
|
||||
public MachineTypes::TimedMachine,
|
||||
public MachineTypes::MappedKeyboardMachine,
|
||||
public MachineTypes::MouseMachine,
|
||||
public CPU::MOS6502Esque::BusHandler<uint32_t> {
|
||||
|
||||
public:
|
||||
@ -898,7 +899,9 @@ class ConcreteMachine:
|
||||
update_interrupts();
|
||||
|
||||
const bool is_vertical_blank = video_.last_valid()->get_is_vertical_blank(video_.time_since_flush());
|
||||
adb_glu_->set_vertical_blank(is_vertical_blank);
|
||||
if(is_vertical_blank != adb_glu_.last_valid()->get_vertical_blank()) {
|
||||
adb_glu_->set_vertical_blank(is_vertical_blank);
|
||||
}
|
||||
}
|
||||
|
||||
return duration;
|
||||
@ -910,7 +913,7 @@ class ConcreteMachine:
|
||||
m65816_.set_irq_line(video_.last_valid()->get_interrupt_line() || sound_glu_.get_interrupt_line());
|
||||
}
|
||||
|
||||
// MARK: - Keyboard input.
|
||||
// MARK: - Input.
|
||||
KeyboardMapper *get_keyboard_mapper() final {
|
||||
return &keyboard_mapper_;
|
||||
}
|
||||
@ -923,6 +926,10 @@ class ConcreteMachine:
|
||||
adb_glu_.last_valid()->keyboard().clear_all_keys();
|
||||
}
|
||||
|
||||
Inputs::Mouse &get_mouse() final {
|
||||
return adb_glu_.last_valid()->get_mouse();
|
||||
}
|
||||
|
||||
private:
|
||||
CPU::WDC65816::Processor<ConcreteMachine, false> m65816_;
|
||||
MemoryMap memory_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user