mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-01 07:33:17 +00:00
Implements most of keyboard input.
This commit is contained in:
parent
f93cdd21de
commit
f40dbefa67
Machines/AtariST
@ -9,6 +9,7 @@
|
||||
#include "AtariST.hpp"
|
||||
|
||||
#include "../CRTMachine.hpp"
|
||||
#include "../KeyboardMachine.hpp"
|
||||
#include "../MouseMachine.hpp"
|
||||
|
||||
//#define LOG_TRACE
|
||||
@ -45,7 +46,8 @@ class ConcreteMachine:
|
||||
public Motorola::ACIA::ACIA::InterruptDelegate,
|
||||
public Motorola::MFP68901::MFP68901::InterruptDelegate,
|
||||
public DMAController::InterruptDelegate,
|
||||
public MouseMachine::Machine {
|
||||
public MouseMachine::Machine,
|
||||
public KeyboardMachine::MappedMachine {
|
||||
public:
|
||||
ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
|
||||
mc68000_(*this),
|
||||
@ -488,7 +490,18 @@ class ConcreteMachine:
|
||||
Inputs::Mouse &get_mouse() final {
|
||||
return ikbd_;
|
||||
}
|
||||
};
|
||||
|
||||
// MARK: - KeyboardMachine
|
||||
void set_key_state(uint16_t key, bool is_pressed) final {
|
||||
ikbd_.set_key_state(Key(key), is_pressed);
|
||||
}
|
||||
|
||||
IntelligentKeyboard::KeyboardMapper keyboard_mapper_;
|
||||
KeyboardMapper *get_keyboard_mapper() final {
|
||||
return &keyboard_mapper_;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,16 @@ void IntelligentKeyboard::run_for(HalfCycles duration) {
|
||||
|
||||
}
|
||||
|
||||
// Forward key changes; implicit assumption here: mutexs are cheap while there's
|
||||
// negligible contention.
|
||||
{
|
||||
std::lock_guard<decltype(key_queue_mutex_)> guard(key_queue_mutex_);
|
||||
for(uint8_t key: key_queue_) {
|
||||
output_bytes({key});
|
||||
}
|
||||
key_queue_.clear();
|
||||
}
|
||||
|
||||
output_line_.advance_writer(duration);
|
||||
}
|
||||
|
||||
@ -66,8 +76,6 @@ void IntelligentKeyboard::output_bytes(std::initializer_list<uint8_t> values) {
|
||||
for(auto value : values) {
|
||||
output_line_.write(2, 10, 0x200 | (value << 1));
|
||||
}
|
||||
|
||||
// TODO: this isn't thread safe! Might need this class to imply a poll?
|
||||
update_clocking_observer();
|
||||
}
|
||||
|
||||
@ -225,6 +233,77 @@ void IntelligentKeyboard::post_relative_mouse_event(int x, int y) {
|
||||
} while(x || y);
|
||||
}
|
||||
|
||||
// MARK: - Keyboard Input
|
||||
void IntelligentKeyboard::set_key_state(Key key, bool is_pressed) {
|
||||
std::lock_guard<decltype(key_queue_mutex_)> guard(key_queue_mutex_);
|
||||
if(is_pressed) {
|
||||
key_queue_.push_back(uint8_t(key));
|
||||
} else {
|
||||
key_queue_.push_back(0x80 | uint8_t(key));
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t IntelligentKeyboard::KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
|
||||
using Key = Inputs::Keyboard::Key;
|
||||
using STKey = Atari::ST::Key;
|
||||
switch(key) {
|
||||
default: return KeyboardMachine::MappedMachine::KeyNotMapped;
|
||||
|
||||
#define Bind(x, y) case Key::x: return uint16_t(STKey::y)
|
||||
#define QBind(x) case Key::x: return uint16_t(STKey::x)
|
||||
|
||||
QBind(k1); QBind(k2); QBind(k3); QBind(k4); QBind(k5); QBind(k6); QBind(k7); QBind(k8); QBind(k9); QBind(k0);
|
||||
QBind(Q); QBind(W); QBind(E); QBind(R); QBind(T); QBind(Y); QBind(U); QBind(I); QBind(O); QBind(P);
|
||||
QBind(A); QBind(S); QBind(D); QBind(F); QBind(G); QBind(H); QBind(J); QBind(K); QBind(L);
|
||||
QBind(Z); QBind(X); QBind(C); QBind(V); QBind(B); QBind(N); QBind(M);
|
||||
|
||||
QBind(Left); QBind(Right); QBind(Up); QBind(Down);
|
||||
|
||||
QBind(BackTick); QBind(Tab);
|
||||
QBind(Hyphen); QBind(Equals); QBind(Backspace);
|
||||
QBind(OpenSquareBracket);
|
||||
QBind(CloseSquareBracket);
|
||||
QBind(CapsLock);
|
||||
QBind(Semicolon);
|
||||
QBind(Quote);
|
||||
Bind(Enter, Return);
|
||||
QBind(LeftShift);
|
||||
QBind(RightShift);
|
||||
|
||||
Bind(Comma, Comma);
|
||||
Bind(FullStop, FullStop);
|
||||
Bind(ForwardSlash, ForwardSlash);
|
||||
|
||||
Bind(LeftOption, Alt);
|
||||
Bind(RightOption, Alt);
|
||||
QBind(Space);
|
||||
QBind(Backslash);
|
||||
|
||||
/* Bind(KeyPadDelete, KeyPadDelete);
|
||||
Bind(KeyPadEquals, KeyPadEquals);
|
||||
Bind(KeyPadSlash, KeyPadSlash);
|
||||
Bind(KeyPadAsterisk, KeyPadAsterisk);
|
||||
Bind(KeyPadMinus, KeyPadMinus);
|
||||
Bind(KeyPadPlus, KeyPadPlus);
|
||||
Bind(KeyPadEnter, KeyPadEnter);
|
||||
Bind(KeyPadDecimalPoint, KeyPadDecimalPoint);
|
||||
|
||||
Bind(KeyPad9, KeyPad9);
|
||||
Bind(KeyPad8, KeyPad8);
|
||||
Bind(KeyPad7, KeyPad7);
|
||||
Bind(KeyPad6, KeyPad6);
|
||||
Bind(KeyPad5, KeyPad5);
|
||||
Bind(KeyPad4, KeyPad4);
|
||||
Bind(KeyPad3, KeyPad3);
|
||||
Bind(KeyPad2, KeyPad2);
|
||||
Bind(KeyPad1, KeyPad1);
|
||||
Bind(KeyPad0, KeyPad0);*/
|
||||
|
||||
#undef QBind
|
||||
#undef Bind
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Mouse Input
|
||||
|
||||
void IntelligentKeyboard::move(int x, int y) {
|
||||
@ -252,3 +331,4 @@ void IntelligentKeyboard::reset_all_buttons() {
|
||||
// MARK: - Joystick Output
|
||||
void IntelligentKeyboard::disable_joysticks() {
|
||||
}
|
||||
|
||||
|
@ -11,14 +11,38 @@
|
||||
|
||||
#include "../../ClockReceiver/ClockingHintSource.hpp"
|
||||
#include "../../Components/SerialPort/SerialPort.hpp"
|
||||
#include "../KeyboardMachine.hpp"
|
||||
|
||||
#include "../../Inputs/Mouse.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
namespace Atari {
|
||||
namespace ST {
|
||||
|
||||
enum class Key: uint16_t {
|
||||
Escape = 1,
|
||||
k1, k2, k3, k4, k5, k6, k7, k8, k9, k0, Hyphen, Equals, Backspace,
|
||||
Tab, Q, W, E, R, T, Y, U, I, O, P, OpenSquareBracket, CloseSquareBracket, Return,
|
||||
Control, A, S, D, F, G, H, J, K, L, Semicolon, Quote, BackTick,
|
||||
LeftShift, Backslash, Z, X, C, V, B, N, M, Comma, FullStop, ForwardSlash, RightShift,
|
||||
/* 0x37 is unused. */
|
||||
Alt = 0x38, Space, CapsLock, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10,
|
||||
/* Various gaps follow. */
|
||||
Home = 0x47, Up,
|
||||
KeypadMinus = 0x4a, Left,
|
||||
Right = 0x4d, KeypadPlus,
|
||||
Down = 0x50,
|
||||
Insert = 0x52, Delete,
|
||||
ISO = 0x60, Undo, Help, KeypadOpenBracket, KeypadCloseBracket, KeypadDivide, KeypadMultiply,
|
||||
Keypad7, Keypad8, Keypad9, Keypad4, KeyPad5, Keypad6, Keypad1, Keypad2, Keypad3, Keypad0, KeypadDecimalPoint,
|
||||
KeypadEnter
|
||||
};
|
||||
static_assert(uint16_t(Key::RightShift) == 0x36, "RightShift should have key code 0x36; check intermediate entries");
|
||||
static_assert(uint16_t(Key::F10) == 0x44, "F10 should have key code 0x44; check intermediate entries");
|
||||
static_assert(uint16_t(Key::KeypadEnter) == 0x72, "KeypadEnter should have key code 0x72; check intermediate entries");
|
||||
|
||||
/*!
|
||||
A receiver for the Atari ST's "intelligent keyboard" commands, which actually cover
|
||||
keyboard input and output and mouse handling.
|
||||
@ -32,7 +56,16 @@ class IntelligentKeyboard:
|
||||
ClockingHint::Preference preferred_clocking() final;
|
||||
void run_for(HalfCycles duration);
|
||||
|
||||
void set_key_state(Key key, bool is_pressed);
|
||||
class KeyboardMapper: public KeyboardMachine::MappedMachine::KeyboardMapper {
|
||||
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) final;
|
||||
};
|
||||
|
||||
private:
|
||||
// MARK: - Key queue.
|
||||
std::mutex key_queue_mutex_;
|
||||
std::vector<uint8_t> key_queue_;
|
||||
|
||||
// MARK: - Serial line state.
|
||||
int bit_count_ = 0;
|
||||
int command_ = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user