1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-09 01:29:44 +00:00

Transfers possession of keyboard mappings from the Mac side over to individual machines.

Specifically by establishing an intermediate representation of a useful mix between the American and British IBM and Mac keyboard layouts, and routing through that.
This commit is contained in:
Thomas Harte 2017-10-12 22:25:02 -04:00
parent edb632af52
commit 78ee46270b
34 changed files with 649 additions and 404 deletions

View File

@ -28,19 +28,20 @@ class Keyboard {
Tab, Q, W, E, R, T, Y, U, I, O, P, OpenSquareBracket, CloseSquareBracket, BackSlash,
CapsLock, A, S, D, F, G, H, J, K, L, Semicolon, Quote, Hash, Enter,
LeftShift, Z, X, C, V, B, N, M, Comma, FullStop, ForwardSlash, RightShift,
LeftControl, LeftOption, LeftMeta, Space, RightMeta, RightOption,
LeftControl, LeftOption, LeftMeta, Space, RightMeta, RightOption, RightControl,
Left, Right, Up, Down,
Insert, Home, PageUp, Delete, End, PageDown,
NumLock, KeyPadSlash, KeyPadAsterisk, KeyPadDelete,
KeyPad7, KeyPad8, KeyPad9, KeyPadPlus,
KeyPad4, KeyPad5, KeyPad6,
KeyPad4, KeyPad5, KeyPad6, KeyPadMinus,
KeyPad1, KeyPad2, KeyPad3, KeyPadEnter,
KeyPad0, KeyPadDecimalPoint
KeyPad0, KeyPadDecimalPoint, KeyPadEquals,
Help
};
// Host interface.
void set_key_pressed(Key key, bool is_pressed);
void reset_all_keys();
virtual void set_key_pressed(Key key, bool is_pressed);
virtual void reset_all_keys();
// Delegate interface.
struct Delegate {

View File

@ -9,6 +9,7 @@
#include "AmstradCPC.hpp"
#include "CharacterMapper.hpp"
#include "KeyboardMapper.hpp"
#include "../../Processors/Z80/Z80.hpp"
@ -965,6 +966,10 @@ class ConcreteMachine:
key_state_.clear_all_keys();
}
KeyboardMapper &get_keyboard_mapper() override {
return keyboard_mapper_;
}
private:
inline void write_to_gate_array(uint8_t value) {
switch(value >> 6) {
@ -1044,6 +1049,7 @@ class ConcreteMachine:
uint8_t *write_pointers_[4];
KeyboardState key_state_;
AmstradCPC::KeyboardMapper keyboard_mapper_;
};
}

View File

@ -12,9 +12,9 @@
using namespace AmstradCPC;
uint16_t *CharacterMapper::sequence_for_character(char character) {
#define KEYS(...) {__VA_ARGS__, EndSequence}
#define SHIFT(...) {KeyShift, __VA_ARGS__, EndSequence}
#define X {NotMapped}
#define KEYS(...) {__VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define SHIFT(...) {KeyShift, __VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define X {KeyboardMachine::Machine::KeyNotMapped}
static KeySequence key_sequences[] = {
/* NUL */ X, /* SOH */ X,
/* STX */ X, /* ETX */ X,

View File

@ -0,0 +1,76 @@
//
// KeyboardMapper.cpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#include "KeyboardMapper.hpp"
#include "AmstradCPC.hpp"
using namespace AmstradCPC;
uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return dest
switch(key) {
default: return KeyCopy;
BIND(k0, Key0); BIND(k1, Key1); BIND(k2, Key2); BIND(k3, Key3); BIND(k4, Key4);
BIND(k5, Key5); BIND(k6, Key6); BIND(k7, Key7); BIND(k8, Key8); BIND(k9, Key9);
BIND(Q, KeyQ); BIND(W, KeyW); BIND(E, KeyE); BIND(R, KeyR); BIND(T, KeyT);
BIND(Y, KeyY); BIND(U, KeyU); BIND(I, KeyI); BIND(O, KeyO); BIND(P, KeyP);
BIND(A, KeyA); BIND(S, KeyS); BIND(D, KeyD); BIND(F, KeyF); BIND(G, KeyG);
BIND(H, KeyH); BIND(J, KeyJ); BIND(K, KeyK); BIND(L, KeyL);
BIND(Z, KeyZ); BIND(X, KeyX); BIND(C, KeyC); BIND(V, KeyV);
BIND(B, KeyB); BIND(N, KeyN); BIND(M, KeyM);
BIND(Escape, KeyEscape);
BIND(F1, KeyF1); BIND(F2, KeyF2); BIND(F3, KeyF3); BIND(F4, KeyF4); BIND(F5, KeyF5);
BIND(F6, KeyF6); BIND(F7, KeyF7); BIND(F8, KeyF8); BIND(F9, KeyF9); BIND(F10, KeyF0);
BIND(F11, KeyRightSquareBracket);
BIND(F12, KeyClear);
BIND(Hyphen, KeyMinus); BIND(Equals, KeyCaret); BIND(BackSpace, KeyDelete);
BIND(Tab, KeyTab);
BIND(OpenSquareBracket, KeyAt);
BIND(CloseSquareBracket, KeyLeftSquareBracket);
BIND(BackSlash, KeyBackSlash);
BIND(CapsLock, KeyCapsLock);
BIND(Semicolon, KeyColon);
BIND(Quote, KeySemicolon);
BIND(Hash, KeyRightSquareBracket);
BIND(Enter, KeyReturn);
BIND(LeftShift, KeyShift);
BIND(Comma, KeyComma);
BIND(FullStop, KeyFullStop);
BIND(ForwardSlash, KeyForwardSlash);
BIND(RightShift, KeyShift);
BIND(LeftControl, KeyControl); BIND(LeftOption, KeyControl); BIND(LeftMeta, KeyControl);
BIND(Space, KeySpace);
BIND(RightMeta, KeyControl); BIND(RightOption, KeyControl); BIND(RightControl, KeyControl);
BIND(Left, KeyLeft); BIND(Right, KeyRight);
BIND(Up, KeyUp); BIND(Down, KeyDown);
BIND(KeyPad0, KeyF0);
BIND(KeyPad1, KeyF1); BIND(KeyPad2, KeyF2); BIND(KeyPad3, KeyF3);
BIND(KeyPad4, KeyF4); BIND(KeyPad5, KeyF5); BIND(KeyPad6, KeyF6);
BIND(KeyPad7, KeyF7); BIND(KeyPad8, KeyF8); BIND(KeyPad9, KeyF9);
BIND(KeyPadPlus, KeySemicolon);
BIND(KeyPadMinus, KeyMinus);
BIND(KeyPadEnter, KeyEnter);
BIND(KeyPadDecimalPoint, KeyFullStop);
BIND(KeyPadEquals, KeyMinus);
BIND(KeyPadSlash, KeyForwardSlash);
BIND(KeyPadAsterisk, KeyColon);
BIND(KeyPadDelete, KeyDelete);
}
#undef BIND
}

View File

@ -0,0 +1,22 @@
//
// KeyboardMapper.hpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#ifndef Machines_AmstradCPC_KeyboardMapper_hpp
#define Machines_AmstradCPC_KeyboardMapper_hpp
#include "../KeyboardMachine.hpp"
namespace AmstradCPC {
struct KeyboardMapper: public KeyboardMachine::Machine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key);
};
};
#endif /* KeyboardMapper_hpp */

View File

@ -12,9 +12,9 @@
using namespace Commodore::Vic20;
uint16_t *CharacterMapper::sequence_for_character(char character) {
#define KEYS(...) {__VA_ARGS__, EndSequence}
#define SHIFT(...) {KeyLShift, __VA_ARGS__, EndSequence}
#define X {NotMapped}
#define KEYS(...) {__VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define SHIFT(...) {KeyLShift, __VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define X {KeyboardMachine::Machine::KeyNotMapped}
static KeySequence key_sequences[] = {
/* NUL */ X, /* SOH */ X,
/* STX */ X, /* ETX */ X,

View File

@ -0,0 +1,67 @@
//
// KeyboardMapper.cpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#include "KeyboardMapper.hpp"
#include "Vic20.hpp"
using namespace Commodore::Vic20;
uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return Commodore::Vic20::dest
switch(key) {
default: break;
BIND(k0, Key0); BIND(k1, Key1); BIND(k2, Key2); BIND(k3, Key3); BIND(k4, Key4);
BIND(k5, Key5); BIND(k6, Key6); BIND(k7, Key7); BIND(k8, Key8); BIND(k9, Key9);
BIND(Q, KeyQ); BIND(W, KeyW); BIND(E, KeyE); BIND(R, KeyR); BIND(T, KeyT);
BIND(Y, KeyY); BIND(U, KeyU); BIND(I, KeyI); BIND(O, KeyO); BIND(P, KeyP);
BIND(A, KeyA); BIND(S, KeyS); BIND(D, KeyD); BIND(F, KeyF); BIND(G, KeyG);
BIND(H, KeyH); BIND(J, KeyJ); BIND(K, KeyK); BIND(L, KeyL);
BIND(Z, KeyZ); BIND(X, KeyX); BIND(C, KeyC); BIND(V, KeyV);
BIND(B, KeyB); BIND(N, KeyN); BIND(M, KeyM);
BIND(BackTick, KeyLeft);
BIND(Hyphen, KeyPlus);
BIND(Equals, KeyDash);
BIND(F11, KeyGBP);
BIND(F12, KeyHome);
BIND(Tab, KeyControl);
BIND(OpenSquareBracket, KeyAt);
BIND(CloseSquareBracket, KeyAsterisk);
BIND(BackSlash, KeyRestore);
BIND(Hash, KeyUp);
BIND(F10, KeyUp);
BIND(Semicolon, KeyColon);
BIND(Quote, KeySemicolon);
BIND(F9, KeyEquals);
BIND(LeftMeta, KeyCBM);
BIND(LeftOption, KeyCBM);
BIND(RightOption, KeyCBM);
BIND(RightMeta, KeyCBM);
BIND(LeftShift, KeyLShift);
BIND(RightShift, KeyRShift);
BIND(Comma, KeyComma);
BIND(FullStop, KeyFullStop);
BIND(ForwardSlash, KeySlash);
BIND(Right, KeyRight);
BIND(Down, KeyDown);
BIND(Enter, KeyReturn);
BIND(Space, KeySpace);
BIND(BackSpace, KeyDelete);
}
#undef BIND
return KeyboardMachine::Machine::KeyNotMapped;
}

View File

@ -0,0 +1,24 @@
//
// KeyboardMapper.hpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#ifndef Machines_Commodore_Vic20_KeyboardMapper_hpp
#define Machines_Commodore_Vic20_KeyboardMapper_hpp
#include "../../KeyboardMachine.hpp"
namespace Commodore {
namespace Vic20 {
struct KeyboardMapper: public KeyboardMachine::Machine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key);
};
}
}
#endif /* KeyboardMapper_hpp */

View File

@ -9,6 +9,7 @@
#include "Vic20.hpp"
#include "CharacterMapper.hpp"
#include "KeyboardMapper.hpp"
#include "../../../Processors/6502/6502.hpp"
#include "../../../Components/6560/6560.hpp"
@ -541,6 +542,10 @@ class ConcreteMachine:
keyboard_via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !tape->get_input());
}
KeyboardMapper &get_keyboard_mapper() override {
return keyboard_mapper_;
}
private:
CPU::MOS6502::Processor<ConcreteMachine, false> m6502_;
@ -570,6 +575,7 @@ class ConcreteMachine:
}
Region region_;
Commodore::Vic20::KeyboardMapper keyboard_mapper_;
std::unique_ptr<Vic6560> mos6560_;
std::shared_ptr<UserPortVIA> user_port_via_port_handler_;

View File

@ -54,6 +54,8 @@ enum Key: uint16_t {
KeyI = key(1, 0x10), KeyP = key(1, 0x20), KeyAsterisk = key(1, 0x40), KeyReturn = key(1, 0x80),
Key1 = key(0, 0x01), Key3 = key(0, 0x02), Key5 = key(0, 0x04), Key7 = key(0, 0x08),
Key9 = key(0, 0x10), KeyPlus = key(0, 0x20), KeyGBP = key(0, 0x40), KeyDelete = key(0, 0x80),
KeyRestore = 0xfffe
#undef key
};

View File

@ -12,10 +12,10 @@
using namespace Electron;
uint16_t *CharacterMapper::sequence_for_character(char character) {
#define KEYS(...) {__VA_ARGS__, EndSequence}
#define SHIFT(...) {KeyShift, __VA_ARGS__, EndSequence}
#define CTRL(...) {KeyControl, __VA_ARGS__, EndSequence}
#define X {NotMapped}
#define KEYS(...) {__VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define SHIFT(...) {KeyShift, __VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define CTRL(...) {KeyControl, __VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define X {KeyboardMachine::Machine::KeyNotMapped}
static KeySequence key_sequences[] = {
/* NUL */ X, /* SOH */ X,
/* STX */ X, /* ETX */ X,

View File

@ -17,6 +17,7 @@
#include "CharacterMapper.hpp"
#include "Interrupts.hpp"
#include "KeyboardMapper.hpp"
#include "Plus3.hpp"
#include "Speaker.hpp"
#include "Tape.hpp"
@ -387,6 +388,10 @@ class ConcreteMachine:
Utility::TypeRecipient::set_typer_for_string(string, std::move(mapper));
}
KeyboardMapper &get_keyboard_mapper() override {
return keyboard_mapper_;
}
private:
inline void update_display() {
if(cycles_since_display_update_ > 0) {
@ -442,6 +447,7 @@ class ConcreteMachine:
uint8_t interrupt_status_ = Interrupt::PowerOnReset | Interrupt::TransmitDataEmpty | 0x80;
uint8_t interrupt_control_ = 0;
uint8_t key_states_[14];
Electron::KeyboardMapper keyboard_mapper_;
// Counters related to simultaneous subsystems
Cycles cycles_since_display_update_ = 0;

View File

@ -0,0 +1,57 @@
//
// KeyboardMapper.cpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#include "KeyboardMapper.hpp"
#include "Electron.hpp"
using namespace Electron;
uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return Electron::Key::dest
switch(key) {
default: return KeyCopy;
BIND(k0, Key0); BIND(k1, Key1); BIND(k2, Key2); BIND(k3, Key3); BIND(k4, Key4);
BIND(k5, Key5); BIND(k6, Key6); BIND(k7, Key7); BIND(k8, Key8); BIND(k9, Key9);
BIND(Q, KeyQ); BIND(W, KeyW); BIND(E, KeyE); BIND(R, KeyR); BIND(T, KeyT);
BIND(Y, KeyY); BIND(U, KeyU); BIND(I, KeyI); BIND(O, KeyO); BIND(P, KeyP);
BIND(A, KeyA); BIND(S, KeyS); BIND(D, KeyD); BIND(F, KeyF); BIND(G, KeyG);
BIND(H, KeyH); BIND(J, KeyJ); BIND(K, KeyK); BIND(L, KeyL);
BIND(Z, KeyZ); BIND(X, KeyX); BIND(C, KeyC); BIND(V, KeyV);
BIND(B, KeyB); BIND(N, KeyN); BIND(M, KeyM);
BIND(Comma, KeyComma);
BIND(FullStop, KeyFullStop);
BIND(ForwardSlash, KeySlash);
BIND(Semicolon, KeySemiColon);
BIND(Quote, KeyColon);
BIND(Escape, KeyEscape);
BIND(Equals, KeyBreak);
BIND(F12, KeyBreak);
BIND(Left, KeyLeft); BIND(Right, KeyRight); BIND(Up, KeyUp); BIND(Down, KeyDown);
BIND(Tab, KeyFunc); BIND(LeftOption, KeyFunc); BIND(RightOption, KeyFunc);
BIND(LeftMeta, KeyFunc); BIND(RightMeta, KeyFunc);
BIND(CapsLock, KeyControl); BIND(LeftControl, KeyControl); BIND(RightControl, KeyControl);
BIND(LeftShift, KeyShift); BIND(RightShift, KeyShift);
BIND(Hyphen, KeyMinus);
BIND(Delete, KeyDelete);
BIND(Enter, KeyReturn); BIND(KeyPadEnter, KeyReturn);
BIND(KeyPad0, Key0); BIND(KeyPad1, Key1); BIND(KeyPad2, Key2); BIND(KeyPad3, Key3); BIND(KeyPad4, Key4);
BIND(KeyPad5, Key5); BIND(KeyPad6, Key6); BIND(KeyPad7, Key7); BIND(KeyPad8, Key8); BIND(KeyPad9, Key9);
BIND(KeyPadMinus, KeyMinus); BIND(KeyPadPlus, KeyColon);
BIND(Space, KeySpace);
}
#undef BIND
}

View File

@ -0,0 +1,22 @@
//
// KeyboardMapper.hpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#ifndef Machines_Electron_KeyboardMapper_hpp
#define Machines_Electron_KeyboardMapper_hpp
#include "../KeyboardMachine.hpp"
namespace Electron {
struct KeyboardMapper: public KeyboardMachine::Machine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key);
};
};
#endif /* KeyboardMapper_hpp */

View File

@ -0,0 +1,29 @@
//
// KeyboardMachine.cpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#include "KeyboardMachine.hpp"
using namespace KeyboardMachine;
Machine::Machine() {
keyboard_.set_delegate(this);
}
void Machine::keyboard_did_change_key(Inputs::Keyboard *keyboard, Inputs::Keyboard::Key key, bool is_pressed) {
uint16_t mapped_key = get_keyboard_mapper().mapped_key_for_key(key);
if(mapped_key != KeyNotMapped) set_key_state(mapped_key, is_pressed);
}
void Machine::reset_all_keys() {
// TODO: unify naming.
clear_all_keys();
}
Inputs::Keyboard &Machine::get_keyboard() {
return keyboard_;
}

View File

@ -9,20 +9,59 @@
#ifndef KeyboardMachine_h
#define KeyboardMachine_h
#include "../Inputs/Keyboard.hpp"
namespace KeyboardMachine {
class Machine {
class Machine: public Inputs::Keyboard::Delegate {
public:
Machine();
/*!
Indicates that the key @c key has been either pressed or released, according to
the state of @c isPressed.
*/
virtual void set_key_state(uint16_t key, bool isPressed) = 0;
virtual void set_key_state(uint16_t key, bool is_pressed) = 0;
/*!
Instructs that all keys should now be treated as released.
*/
virtual void clear_all_keys() = 0;
/*!
Provides a destination for keyboard input.
*/
virtual Inputs::Keyboard &get_keyboard();
/*!
A keyboard mapper attempts to provide a physical mapping between host keys and emulated keys.
See the character mapper for logical mapping.
*/
class KeyboardMapper {
public:
virtual uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) = 0;
};
/// Terminates a key sequence from the character mapper.
static const uint16_t KeyEndSequence = 0xffff;
/*!
Indicates that a key is not mapped (for the keyboard mapper) or that a
character cannot be typed (for the character mapper).
*/
static const uint16_t KeyNotMapped = 0xfffe;
protected:
/*!
Allows individual machines to provide the mapping between host keys
as per Inputs::Keyboard and their native scheme.
*/
virtual KeyboardMapper &get_keyboard_mapper() = 0;
private:
void keyboard_did_change_key(Inputs::Keyboard *keyboard, Inputs::Keyboard::Key key, bool is_pressed);
void reset_all_keys();
Inputs::Keyboard keyboard_;
};
}

View File

@ -12,9 +12,9 @@
using namespace Oric;
uint16_t *CharacterMapper::sequence_for_character(char character) {
#define KEYS(...) {__VA_ARGS__, EndSequence}
#define SHIFT(...) {KeyLeftShift, __VA_ARGS__, EndSequence}
#define X {NotMapped}
#define KEYS(...) {__VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define SHIFT(...) {KeyLeftShift, __VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define X {KeyboardMachine::Machine::KeyNotMapped}
static KeySequence key_sequences[] = {
/* NUL */ X, /* SOH */ X,
/* STX */ X, /* ETX */ X,

View File

@ -0,0 +1,53 @@
//
// KeyboardMapper.cpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#include "KeyboardMapper.hpp"
#include "Oric.hpp"
using namespace Oric;
uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return Oric::dest
switch(key) {
default: break;
BIND(k0, Key0); BIND(k1, Key1); BIND(k2, Key2); BIND(k3, Key3); BIND(k4, Key4);
BIND(k5, Key5); BIND(k6, Key6); BIND(k7, Key7); BIND(k8, Key8); BIND(k9, Key9);
BIND(Q, KeyQ); BIND(W, KeyW); BIND(E, KeyE); BIND(R, KeyR); BIND(T, KeyT);
BIND(Y, KeyY); BIND(U, KeyU); BIND(I, KeyI); BIND(O, KeyO); BIND(P, KeyP);
BIND(A, KeyA); BIND(S, KeyS); BIND(D, KeyD); BIND(F, KeyF); BIND(G, KeyG);
BIND(H, KeyH); BIND(J, KeyJ); BIND(K, KeyK); BIND(L, KeyL);
BIND(Z, KeyZ); BIND(X, KeyX); BIND(C, KeyC); BIND(V, KeyV);
BIND(B, KeyB); BIND(N, KeyN); BIND(M, KeyM);
BIND(Left, KeyLeft); BIND(Right, KeyRight); BIND(Up, KeyUp); BIND(Down, KeyDown);
BIND(Hyphen, KeyMinus); BIND(Equals, KeyEquals); BIND(BackSlash, KeyBackSlash);
BIND(OpenSquareBracket, KeyOpenSquare); BIND(CloseSquareBracket, KeyCloseSquare);
BIND(BackSpace, KeyDelete); BIND(Delete, KeyDelete);
BIND(Semicolon, KeySemiColon); BIND(Quote, KeyQuote);
BIND(Comma, KeyComma); BIND(FullStop, KeyFullStop); BIND(ForwardSlash, KeyForwardSlash);
BIND(Escape, KeyEscape); BIND(Tab, KeyEscape);
BIND(CapsLock, KeyControl); BIND(LeftControl, KeyControl); BIND(RightControl, KeyControl);
BIND(LeftOption, KeyFunction);
BIND(RightOption, KeyFunction);
BIND(LeftMeta, KeyFunction);
BIND(RightMeta, KeyFunction);
BIND(LeftShift, KeyLeftShift);
BIND(RightShift, KeyRightShift);
BIND(Space, KeySpace);
BIND(Enter, KeyReturn);
}
#undef BIND
return KeyboardMachine::Machine::KeyNotMapped;
}

View File

@ -0,0 +1,22 @@
//
// KeyboardMapper.hpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#ifndef Machines_Oric_KeyboardMapper_hpp
#define Machines_Oric_KeyboardMapper_hpp
#include "../KeyboardMachine.hpp"
namespace Oric {
struct KeyboardMapper: public KeyboardMachine::Machine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key);
};
};
#endif /* KeyboardMapper_hpp */

View File

@ -8,9 +8,10 @@
#include "Oric.hpp"
#include "Video.hpp"
#include "Microdisc.hpp"
#include "CharacterMapper.hpp"
#include "KeyboardMapper.hpp"
#include "Microdisc.hpp"
#include "Video.hpp"
#include "../MemoryFuzzer.hpp"
#include "../Typer.hpp"
@ -405,6 +406,10 @@ class ConcreteMachine:
set_interrupt_line();
}
KeyboardMapper &get_keyboard_mapper() override {
return keyboard_mapper_;
}
private:
CPU::MOS6502::Processor<ConcreteMachine, false> m6502_;
@ -425,6 +430,9 @@ class ConcreteMachine:
std::unique_ptr<VideoOutput> video_output_;
std::shared_ptr<GI::AY38910::AY38910> ay8910_;
// Inputs
Oric::KeyboardMapper keyboard_mapper_;
// The tape
TapePlayer tape_player_;
bool use_fast_tape_hack_ = false;

View File

@ -44,14 +44,14 @@ void Typer::run_for(const HalfCycles duration) {
bool Typer::try_type_next_character() {
uint16_t *sequence = character_mapper_->sequence_for_character(string_[string_pointer_]);
if(!sequence || sequence[0] == CharacterMapper::NotMapped) {
if(!sequence || sequence[0] == KeyboardMachine::Machine::KeyNotMapped) {
return false;
}
if(!phase_) delegate_->clear_all_keys();
else {
delegate_->set_key_state(sequence[phase_ - 1], true);
return sequence[phase_] != CharacterMapper::EndSequence;
return sequence[phase_] != KeyboardMachine::Machine::KeyEndSequence;
}
return true;
@ -85,6 +85,6 @@ Typer::~Typer() {
uint16_t *CharacterMapper::table_lookup_sequence_for_character(KeySequence *sequences, size_t length, char character) {
size_t ucharacter = static_cast<size_t>((unsigned char)character);
if(ucharacter > (length / sizeof(KeySequence))) return nullptr;
if(sequences[ucharacter][0] == NotMapped) return nullptr;
if(sequences[ucharacter][0] == KeyboardMachine::Machine::KeyNotMapped) return nullptr;
return sequences[ucharacter];
}

View File

@ -24,15 +24,6 @@ class CharacterMapper {
/// @returns The EndSequence-terminated sequence of keys that would cause @c character to be typed.
virtual uint16_t *sequence_for_character(char character) = 0;
/// Terminates a key sequence.
static const uint16_t EndSequence = 0xffff;
/*!
If returned as the first entry in a key sequence, indicates that the requested character
cannot be mapped.
*/
static const uint16_t NotMapped = 0xfffe;
protected:
typedef uint16_t KeySequence[16];

View File

@ -14,9 +14,9 @@ using namespace ZX8081;
CharacterMapper::CharacterMapper(bool is_zx81) : is_zx81_(is_zx81) {}
uint16_t *CharacterMapper::sequence_for_character(char character) {
#define KEYS(...) {__VA_ARGS__, EndSequence}
#define SHIFT(...) {KeyShift, __VA_ARGS__, EndSequence}
#define X {NotMapped}
#define KEYS(...) {__VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define SHIFT(...) {KeyShift, __VA_ARGS__, KeyboardMachine::Machine::KeyEndSequence}
#define X {KeyboardMachine::Machine::KeyNotMapped}
static KeySequence zx81_key_sequences[] = {
/* NUL */ X, /* SOH */ X,
/* STX */ X, /* ETX */ X,

View File

@ -0,0 +1,35 @@
//
// KeyboardMapper.cpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#include "KeyboardMapper.hpp"
#include "ZX8081.hpp"
using namespace ZX8081;
uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return ZX8081::dest
switch(key) {
default: break;
BIND(k0, Key0); BIND(k1, Key1); BIND(k2, Key2); BIND(k3, Key3); BIND(k4, Key4);
BIND(k5, Key5); BIND(k6, Key6); BIND(k7, Key7); BIND(k8, Key8); BIND(k9, Key9);
BIND(Q, KeyQ); BIND(W, KeyW); BIND(E, KeyE); BIND(R, KeyR); BIND(T, KeyT);
BIND(Y, KeyY); BIND(U, KeyU); BIND(I, KeyI); BIND(O, KeyO); BIND(P, KeyP);
BIND(A, KeyA); BIND(S, KeyS); BIND(D, KeyD); BIND(F, KeyF); BIND(G, KeyG);
BIND(H, KeyH); BIND(J, KeyJ); BIND(K, KeyK); BIND(L, KeyL);
BIND(Z, KeyZ); BIND(X, KeyX); BIND(C, KeyC); BIND(V, KeyV);
BIND(B, KeyB); BIND(N, KeyN); BIND(M, KeyM);
BIND(LeftShift, KeyShift); BIND(RightShift, KeyShift);
BIND(FullStop, KeyDot);
BIND(Enter, KeyEnter);
BIND(Space, KeySpace);
}
#undef BIND
return KeyboardMachine::Machine::KeyNotMapped;
}

View File

@ -0,0 +1,22 @@
//
// KeyboardMapper.hpp
// Clock Signal
//
// Created by Thomas Harte on 10/10/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
#ifndef Machines_ZX8081_KeyboardMapper_hpp
#define Machines_ZX8081_KeyboardMapper_hpp
#include "../KeyboardMachine.hpp"
namespace ZX8081 {
struct KeyboardMapper: public KeyboardMachine::Machine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key);
};
};
#endif /* KeyboardMapper_hpp */

View File

@ -18,6 +18,7 @@
#include "../Typer.hpp"
#include "CharacterMapper.hpp"
#include "KeyboardMapper.hpp"
#include "Video.hpp"
#include <memory>
@ -331,6 +332,10 @@ template<bool is_zx81> class ConcreteMachine:
HalfCycles get_typer_delay() override final { return Cycles(7000000); }
HalfCycles get_typer_frequency() override final { return Cycles(390000); }
KeyboardMapper &get_keyboard_mapper() override {
return keyboard_mapper_;
}
private:
CPU::Z80::Processor<ConcreteMachine, false, is_zx81> z80_;
@ -350,6 +355,7 @@ template<bool is_zx81> class ConcreteMachine:
int line_counter_;
uint8_t key_states_[8];
ZX8081::KeyboardMapper keyboard_mapper_;
HalfClockReceiver<Storage::Tape::BinaryTapePlayer> tape_player_;
Storage::Tape::ZX8081::Parser parser_;

View File

@ -81,6 +81,12 @@
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
4B5073071DDD3B9400C48FBD /* ArrayBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */; };
4B50730A1DDFCFDF00C48FBD /* ArrayBuilderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B5073091DDFCFDF00C48FBD /* ArrayBuilderTests.mm */; };
4B54C0BC1F8D8E790050900F /* KeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */; };
4B54C0BF1F8D8F450050900F /* KeyboardMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0BD1F8D8F450050900F /* KeyboardMapper.cpp */; };
4B54C0C21F8D91CD0050900F /* KeyboardMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C11F8D91CD0050900F /* KeyboardMapper.cpp */; };
4B54C0C51F8D91D90050900F /* KeyboardMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C41F8D91D90050900F /* KeyboardMapper.cpp */; };
4B54C0C81F8D91E50050900F /* KeyboardMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0C61F8D91E50050900F /* KeyboardMapper.cpp */; };
4B54C0CB1F8D92590050900F /* KeyboardMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B54C0CA1F8D92580050900F /* KeyboardMapper.cpp */; };
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */; };
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */; };
4B58601E1F806AB200AEE2E3 /* MFMSectorDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */; };
@ -629,6 +635,17 @@
4B5073051DDD3B9400C48FBD /* ArrayBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBuilder.cpp; sourceTree = "<group>"; };
4B5073061DDD3B9400C48FBD /* ArrayBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ArrayBuilder.hpp; sourceTree = "<group>"; };
4B5073091DDFCFDF00C48FBD /* ArrayBuilderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ArrayBuilderTests.mm; sourceTree = "<group>"; };
4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardMachine.cpp; sourceTree = "<group>"; };
4B54C0BD1F8D8F450050900F /* KeyboardMapper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = KeyboardMapper.cpp; path = Oric/KeyboardMapper.cpp; sourceTree = "<group>"; };
4B54C0BE1F8D8F450050900F /* KeyboardMapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = KeyboardMapper.hpp; path = Oric/KeyboardMapper.hpp; sourceTree = "<group>"; };
4B54C0C01F8D91CD0050900F /* KeyboardMapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = KeyboardMapper.hpp; path = AmstradCPC/KeyboardMapper.hpp; sourceTree = "<group>"; };
4B54C0C11F8D91CD0050900F /* KeyboardMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyboardMapper.cpp; path = AmstradCPC/KeyboardMapper.cpp; sourceTree = "<group>"; };
4B54C0C31F8D91D90050900F /* KeyboardMapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KeyboardMapper.hpp; sourceTree = "<group>"; };
4B54C0C41F8D91D90050900F /* KeyboardMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyboardMapper.cpp; sourceTree = "<group>"; };
4B54C0C61F8D91E50050900F /* KeyboardMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyboardMapper.cpp; path = Electron/KeyboardMapper.cpp; sourceTree = "<group>"; };
4B54C0C71F8D91E50050900F /* KeyboardMapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = KeyboardMapper.hpp; path = Electron/KeyboardMapper.hpp; sourceTree = "<group>"; };
4B54C0C91F8D92580050900F /* KeyboardMapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = KeyboardMapper.hpp; path = ZX8081/KeyboardMapper.hpp; sourceTree = "<group>"; };
4B54C0CA1F8D92580050900F /* KeyboardMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyboardMapper.cpp; path = ZX8081/KeyboardMapper.cpp; sourceTree = "<group>"; };
4B55CE5B1C3B7D6F0093A61B /* CSOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSOpenGLView.h; sourceTree = "<group>"; };
4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSOpenGLView.m; sourceTree = "<group>"; };
4B55CE5E1C3B7D960093A61B /* MachineDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MachineDocument.swift; sourceTree = "<group>"; };
@ -1207,9 +1224,11 @@
isa = PBXGroup;
children = (
4B8378DD1F33675F005CA9E4 /* CharacterMapper.cpp */,
4B54C0CA1F8D92580050900F /* KeyboardMapper.cpp */,
4BD3A3091EE755C800B5B501 /* Video.cpp */,
4B1497901EE4B5A800CE2596 /* ZX8081.cpp */,
4B8378DE1F33675F005CA9E4 /* CharacterMapper.hpp */,
4B54C0C91F8D92580050900F /* KeyboardMapper.hpp */,
4BD3A30A1EE755C800B5B501 /* Video.hpp */,
4B1497911EE4B5A800CE2596 /* ZX8081.hpp */,
);
@ -1319,6 +1338,7 @@
children = (
4B8378DA1F336631005CA9E4 /* CharacterMapper.cpp */,
4B2E2D9B1C3A070400138695 /* Electron.cpp */,
4B54C0C61F8D91E50050900F /* KeyboardMapper.cpp */,
4B30512E1D98ACC600B4FED8 /* Plus3.cpp */,
4BEA52611DF339D7007E74F2 /* Speaker.cpp */,
4BEA525D1DF33323007E74F2 /* Tape.cpp */,
@ -1326,6 +1346,7 @@
4B8378DB1F336631005CA9E4 /* CharacterMapper.hpp */,
4B2E2D9C1C3A070400138695 /* Electron.hpp */,
4BEA52601DF3343A007E74F2 /* Interrupts.hpp */,
4B54C0C71F8D91E50050900F /* KeyboardMapper.hpp */,
4B30512F1D98ACC600B4FED8 /* Plus3.hpp */,
4BEA52621DF339D7007E74F2 /* Speaker.hpp */,
4BEA525F1DF333D8007E74F2 /* Tape.hpp */,
@ -1379,9 +1400,11 @@
isa = PBXGroup;
children = (
4B38F3461F2EC11D00D9235D /* AmstradCPC.cpp */,
4B38F3471F2EC11D00D9235D /* AmstradCPC.hpp */,
4BACC5AF1F3DFF7C0037C015 /* CharacterMapper.cpp */,
4B54C0C11F8D91CD0050900F /* KeyboardMapper.cpp */,
4B38F3471F2EC11D00D9235D /* AmstradCPC.hpp */,
4BACC5B01F3DFF7C0037C015 /* CharacterMapper.hpp */,
4B54C0C01F8D91CD0050900F /* KeyboardMapper.hpp */,
);
name = AmstradCPC;
sourceTree = "<group>";
@ -1525,8 +1548,10 @@
isa = PBXGroup;
children = (
4B8378E31F3378C4005CA9E4 /* CharacterMapper.cpp */,
4B54C0C41F8D91D90050900F /* KeyboardMapper.cpp */,
4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */,
4B8378E41F3378C4005CA9E4 /* CharacterMapper.hpp */,
4B54C0C31F8D91D90050900F /* KeyboardMapper.hpp */,
4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */,
);
path = "Vic-20";
@ -2173,6 +2198,7 @@
4BB73EDC1B587CA500552FC2 /* Machines */ = {
isa = PBXGroup;
children = (
4B54C0BB1F8D8E790050900F /* KeyboardMachine.cpp */,
4B2A33281DB8544D002876E3 /* MemoryFuzzer.cpp */,
4B1E85731D170228001EF87D /* Typer.cpp */,
4BA9C3CF1D8164A9002DDB61 /* ConfigurationTarget.hpp */,
@ -2316,10 +2342,12 @@
isa = PBXGroup;
children = (
4B8378E01F336920005CA9E4 /* CharacterMapper.cpp */,
4B54C0BD1F8D8F450050900F /* KeyboardMapper.cpp */,
4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */,
4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */,
4B2BFDB01DAEF5FF001A68B8 /* Video.cpp */,
4B8378E11F336920005CA9E4 /* CharacterMapper.hpp */,
4B54C0BE1F8D8F450050900F /* KeyboardMapper.hpp */,
4B5FADBF1DE3BF2B00AEC565 /* Microdisc.hpp */,
4BCF1FA31DADC3DD0039D2E7 /* Oric.hpp */,
4B2BFDB11DAEF5FF001A68B8 /* Video.hpp */,
@ -2926,12 +2954,14 @@
4B4518A11F75FD1C00926311 /* D64.cpp in Sources */,
4B1558C01F844ECD006E9A97 /* BitReverse.cpp in Sources */,
4BCF1FA41DADC3DD0039D2E7 /* Oric.cpp in Sources */,
4B54C0CB1F8D92590050900F /* KeyboardMapper.cpp in Sources */,
4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */,
4B8334951F5E25B60097E338 /* C1540.cpp in Sources */,
4B1497921EE4B5A800CE2596 /* ZX8081.cpp in Sources */,
4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */,
4B4518861F75E91A00926311 /* MFMDiskController.cpp in Sources */,
4BA799951D8B656E0045123D /* StaticAnalyser.cpp in Sources */,
4B54C0BF1F8D8F450050900F /* KeyboardMapper.cpp in Sources */,
4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */,
4B2BFDB21DAEF5FF001A68B8 /* Video.cpp in Sources */,
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */,
@ -2964,6 +2994,7 @@
4BEA52631DF339D7007E74F2 /* Speaker.cpp in Sources */,
4BC5E4921D7ED365008CF980 /* StaticAnalyser.cpp in Sources */,
4BC830D11D6E7C690000A26F /* Tape.cpp in Sources */,
4B54C0C51F8D91D90050900F /* KeyboardMapper.cpp in Sources */,
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */,
4B86E25B1F8C628F006FAA45 /* Keyboard.cpp in Sources */,
4B4518851F75E91A00926311 /* DiskController.cpp in Sources */,
@ -2994,6 +3025,7 @@
4B8FE2291DA1EDDF0090D3CE /* ElectronOptionsPanel.swift in Sources */,
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */,
4BB697CB1D4B6D3E00248BDF /* TimedEventLoop.cpp in Sources */,
4B54C0C21F8D91CD0050900F /* KeyboardMapper.cpp in Sources */,
4BBC951E1F368D83008F4C34 /* i8272.cpp in Sources */,
4BF1354C1D6D2C300054B2EA /* StaticAnalyser.cpp in Sources */,
4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */,
@ -3024,6 +3056,7 @@
4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */,
4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */,
4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */,
4B54C0C81F8D91E50050900F /* KeyboardMapper.cpp in Sources */,
4BEE0A701D72496600532C7B /* PRG.cpp in Sources */,
4B8334861F5DA3780097E338 /* 6502Storage.cpp in Sources */,
4B8FE2271DA1DE2D0090D3CE /* NSBundle+DataResource.m in Sources */,
@ -3034,6 +3067,7 @@
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
4B37EE821D7345A6006A09A4 /* BinaryDump.cpp in Sources */,
4B8334821F5D9FF70097E338 /* PartialMachineCycle.cpp in Sources */,
4B54C0BC1F8D8E790050900F /* KeyboardMachine.cpp in Sources */,
4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -46,4 +46,9 @@
- (void)paste:(NSString *)string;
// This is an informal implementation of the CSKeyboardMachine protocol; specific machines
// can decide whether they opt in as keyboard machines.
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed;
- (void)clearAllKeys;
@end

View File

@ -10,6 +10,8 @@
#import "CSMachine+Subclassing.h"
#import "CSMachine+Target.h"
#import "CSKeyboardMachine.h"
#include "Typer.hpp"
#include "ConfigurationTarget.hpp"
@ -183,4 +185,78 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
}
}
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
auto keyboard_machine = dynamic_cast<KeyboardMachine::Machine *>(_machine);
if(!keyboard_machine) return;
@synchronized(self) {
Inputs::Keyboard &keyboard = keyboard_machine->get_keyboard();
// Connect the Carbon-era Mac keyboard scancodes to Clock Signal's 'universal' enumeration in order
// to pass into the platform-neutral realm.
#define BIND(source, dest) case source: keyboard.set_key_pressed(Inputs::Keyboard::Key::dest, isPressed); break
switch(key) {
BIND(VK_ANSI_0, k0); BIND(VK_ANSI_1, k1); BIND(VK_ANSI_2, k2); BIND(VK_ANSI_3, k3); BIND(VK_ANSI_4, k4);
BIND(VK_ANSI_5, k5); BIND(VK_ANSI_6, k6); BIND(VK_ANSI_7, k7); BIND(VK_ANSI_8, k8); BIND(VK_ANSI_9, k9);
BIND(VK_ANSI_Q, Q); BIND(VK_ANSI_W, W); BIND(VK_ANSI_E, E); BIND(VK_ANSI_R, R); BIND(VK_ANSI_T, T);
BIND(VK_ANSI_Y, Y); BIND(VK_ANSI_U, U); BIND(VK_ANSI_I, I); BIND(VK_ANSI_O, O); BIND(VK_ANSI_P, P);
BIND(VK_ANSI_A, A); BIND(VK_ANSI_S, S); BIND(VK_ANSI_D, D); BIND(VK_ANSI_F, F); BIND(VK_ANSI_G, G);
BIND(VK_ANSI_H, H); BIND(VK_ANSI_J, J); BIND(VK_ANSI_K, K); BIND(VK_ANSI_L, L);
BIND(VK_ANSI_Z, Z); BIND(VK_ANSI_X, X); BIND(VK_ANSI_C, C); BIND(VK_ANSI_V, V);
BIND(VK_ANSI_B, B); BIND(VK_ANSI_N, N); BIND(VK_ANSI_M, M);
BIND(VK_F1, F1); BIND(VK_F2, F2); BIND(VK_F3, F3); BIND(VK_F4, F4);
BIND(VK_F5, F5); BIND(VK_F6, F6); BIND(VK_F7, F7); BIND(VK_F8, F8);
BIND(VK_F9, F9); BIND(VK_F10, F10); BIND(VK_F11, F11); BIND(VK_F12, F12);
BIND(VK_ANSI_Keypad0, KeyPad0); BIND(VK_ANSI_Keypad1, KeyPad1); BIND(VK_ANSI_Keypad2, KeyPad2);
BIND(VK_ANSI_Keypad3, KeyPad3); BIND(VK_ANSI_Keypad4, KeyPad4); BIND(VK_ANSI_Keypad5, KeyPad5);
BIND(VK_ANSI_Keypad6, KeyPad6); BIND(VK_ANSI_Keypad7, KeyPad7); BIND(VK_ANSI_Keypad8, KeyPad8);
BIND(VK_ANSI_Keypad9, KeyPad9);
BIND(VK_ANSI_Equal, Equals); BIND(VK_ANSI_Minus, Hyphen);
BIND(VK_ANSI_RightBracket, CloseSquareBracket); BIND(VK_ANSI_LeftBracket, OpenSquareBracket);
BIND(VK_ANSI_Quote, Quote); BIND(VK_ANSI_Grave, BackTick);
BIND(VK_ANSI_Semicolon, Semicolon);
BIND(VK_ANSI_Backslash, BackSlash); BIND(VK_ANSI_Slash, ForwardSlash);
BIND(VK_ANSI_Comma, Comma); BIND(VK_ANSI_Period, FullStop);
BIND(VK_ANSI_KeypadDecimal, KeyPadDecimalPoint); BIND(VK_ANSI_KeypadEquals, KeyPadEquals);
BIND(VK_ANSI_KeypadMultiply, KeyPadAsterisk); BIND(VK_ANSI_KeypadDivide, KeyPadSlash);
BIND(VK_ANSI_KeypadPlus, KeyPadPlus); BIND(VK_ANSI_KeypadMinus, KeyPadMinus);
BIND(VK_ANSI_KeypadClear, KeyPadDelete); BIND(VK_ANSI_KeypadEnter, KeyPadEnter);
BIND(VK_Return, Enter); BIND(VK_Tab, Tab);
BIND(VK_Space, Space); BIND(VK_Delete, BackSpace);
BIND(VK_Control, LeftControl); BIND(VK_Option, LeftOption);
BIND(VK_Command, LeftMeta); BIND(VK_Shift, LeftShift);
BIND(VK_RightControl, RightControl); BIND(VK_RightOption, RightOption);
BIND(VK_Escape, Escape); BIND(VK_CapsLock, CapsLock);
BIND(VK_Home, Home); BIND(VK_End, End);
BIND(VK_PageUp, PageUp); BIND(VK_PageDown, PageDown);
BIND(VK_RightShift, RightShift);
BIND(VK_Help, Help);
BIND(VK_ForwardDelete, Delete);
BIND(VK_LeftArrow, Left); BIND(VK_RightArrow, Right);
BIND(VK_DownArrow, Down); BIND(VK_UpArrow, Up);
}
#undef BIND
}
}
- (void)clearAllKeys {
auto keyboard_machine = dynamic_cast<KeyboardMachine::Machine *>(_machine);
if(!keyboard_machine) return;
@synchronized(self) {
keyboard_machine->get_keyboard().reset_all_keys();
}
}
@end

View File

@ -55,98 +55,4 @@
- (NSString *)userDefaultsPrefix { return @"amstradCPC"; }
#pragma mark - Keyboard Mapping
- (void)clearAllKeys {
@synchronized(self) {
_amstradCPC->clear_all_keys();
}
}
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
@synchronized(self) {
switch(key) {
case VK_ANSI_0: _amstradCPC->set_key_state(AmstradCPC::Key::Key0, isPressed); break;
case VK_ANSI_1: _amstradCPC->set_key_state(AmstradCPC::Key::Key1, isPressed); break;
case VK_ANSI_2: _amstradCPC->set_key_state(AmstradCPC::Key::Key2, isPressed); break;
case VK_ANSI_3: _amstradCPC->set_key_state(AmstradCPC::Key::Key3, isPressed); break;
case VK_ANSI_4: _amstradCPC->set_key_state(AmstradCPC::Key::Key4, isPressed); break;
case VK_ANSI_5: _amstradCPC->set_key_state(AmstradCPC::Key::Key5, isPressed); break;
case VK_ANSI_6: _amstradCPC->set_key_state(AmstradCPC::Key::Key6, isPressed); break;
case VK_ANSI_7: _amstradCPC->set_key_state(AmstradCPC::Key::Key7, isPressed); break;
case VK_ANSI_8: _amstradCPC->set_key_state(AmstradCPC::Key::Key8, isPressed); break;
case VK_ANSI_9: _amstradCPC->set_key_state(AmstradCPC::Key::Key9, isPressed); break;
case VK_ANSI_Q: _amstradCPC->set_key_state(AmstradCPC::Key::KeyQ, isPressed); break;
case VK_ANSI_W: _amstradCPC->set_key_state(AmstradCPC::Key::KeyW, isPressed); break;
case VK_ANSI_E: _amstradCPC->set_key_state(AmstradCPC::Key::KeyE, isPressed); break;
case VK_ANSI_R: _amstradCPC->set_key_state(AmstradCPC::Key::KeyR, isPressed); break;
case VK_ANSI_T: _amstradCPC->set_key_state(AmstradCPC::Key::KeyT, isPressed); break;
case VK_ANSI_Y: _amstradCPC->set_key_state(AmstradCPC::Key::KeyY, isPressed); break;
case VK_ANSI_U: _amstradCPC->set_key_state(AmstradCPC::Key::KeyU, isPressed); break;
case VK_ANSI_I: _amstradCPC->set_key_state(AmstradCPC::Key::KeyI, isPressed); break;
case VK_ANSI_O: _amstradCPC->set_key_state(AmstradCPC::Key::KeyO, isPressed); break;
case VK_ANSI_P: _amstradCPC->set_key_state(AmstradCPC::Key::KeyP, isPressed); break;
case VK_ANSI_A: _amstradCPC->set_key_state(AmstradCPC::Key::KeyA, isPressed); break;
case VK_ANSI_S: _amstradCPC->set_key_state(AmstradCPC::Key::KeyS, isPressed); break;
case VK_ANSI_D: _amstradCPC->set_key_state(AmstradCPC::Key::KeyD, isPressed); break;
case VK_ANSI_F: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF, isPressed); break;
case VK_ANSI_G: _amstradCPC->set_key_state(AmstradCPC::Key::KeyG, isPressed); break;
case VK_ANSI_H: _amstradCPC->set_key_state(AmstradCPC::Key::KeyH, isPressed); break;
case VK_ANSI_J: _amstradCPC->set_key_state(AmstradCPC::Key::KeyJ, isPressed); break;
case VK_ANSI_K: _amstradCPC->set_key_state(AmstradCPC::Key::KeyK, isPressed); break;
case VK_ANSI_L: _amstradCPC->set_key_state(AmstradCPC::Key::KeyL, isPressed); break;
case VK_ANSI_Z: _amstradCPC->set_key_state(AmstradCPC::Key::KeyZ, isPressed); break;
case VK_ANSI_X: _amstradCPC->set_key_state(AmstradCPC::Key::KeyX, isPressed); break;
case VK_ANSI_C: _amstradCPC->set_key_state(AmstradCPC::Key::KeyC, isPressed); break;
case VK_ANSI_V: _amstradCPC->set_key_state(AmstradCPC::Key::KeyV, isPressed); break;
case VK_ANSI_B: _amstradCPC->set_key_state(AmstradCPC::Key::KeyB, isPressed); break;
case VK_ANSI_N: _amstradCPC->set_key_state(AmstradCPC::Key::KeyN, isPressed); break;
case VK_ANSI_M: _amstradCPC->set_key_state(AmstradCPC::Key::KeyM, isPressed); break;
case VK_Space: _amstradCPC->set_key_state(AmstradCPC::Key::KeySpace, isPressed); break;
case VK_ANSI_Grave: _amstradCPC->set_key_state(AmstradCPC::Key::KeyCopy, isPressed); break;
case VK_Return: _amstradCPC->set_key_state(AmstradCPC::Key::KeyReturn, isPressed); break;
case VK_ANSI_Minus: _amstradCPC->set_key_state(AmstradCPC::Key::KeyMinus, isPressed); break;
case VK_RightArrow: _amstradCPC->set_key_state(AmstradCPC::Key::KeyRight, isPressed); break;
case VK_LeftArrow: _amstradCPC->set_key_state(AmstradCPC::Key::KeyLeft, isPressed); break;
case VK_DownArrow: _amstradCPC->set_key_state(AmstradCPC::Key::KeyDown, isPressed); break;
case VK_UpArrow: _amstradCPC->set_key_state(AmstradCPC::Key::KeyUp, isPressed); break;
case VK_Delete: _amstradCPC->set_key_state(AmstradCPC::Key::KeyDelete, isPressed); break;
case VK_Escape: _amstradCPC->set_key_state(AmstradCPC::Key::KeyEscape, isPressed); break;
case VK_ANSI_Comma: _amstradCPC->set_key_state(AmstradCPC::Key::KeyComma, isPressed); break;
case VK_ANSI_Period: _amstradCPC->set_key_state(AmstradCPC::Key::KeyFullStop, isPressed); break;
case VK_ANSI_Semicolon:
_amstradCPC->set_key_state(AmstradCPC::Key::KeySemicolon, isPressed); break;
case VK_ANSI_Quote: _amstradCPC->set_key_state(AmstradCPC::Key::KeyColon, isPressed); break;
case VK_ANSI_Slash: _amstradCPC->set_key_state(AmstradCPC::Key::KeyForwardSlash, isPressed); break;
case VK_ANSI_Backslash: _amstradCPC->set_key_state(AmstradCPC::Key::KeyBackSlash, isPressed); break;
case VK_Shift: _amstradCPC->set_key_state(AmstradCPC::Key::KeyShift, isPressed); break;
case VK_Control: _amstradCPC->set_key_state(AmstradCPC::Key::KeyControl, isPressed); break;
case VK_F1: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF1, isPressed); break;
case VK_F2: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF2, isPressed); break;
case VK_F3: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF3, isPressed); break;
case VK_F4: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF4, isPressed); break;
case VK_F5: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF5, isPressed); break;
case VK_F6: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF6, isPressed); break;
case VK_F7: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF7, isPressed); break;
case VK_F8: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF8, isPressed); break;
case VK_F9: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF9, isPressed); break;
case VK_F10: _amstradCPC->set_key_state(AmstradCPC::Key::KeyF0, isPressed); break;
case VK_F12: _amstradCPC->set_key_state(AmstradCPC::Key::KeyFDot, isPressed); break;
default:
// printf("%02x\n", key);
break;
}
}
}
@end

View File

@ -57,94 +57,6 @@
}
}
#pragma mark - Keyboard Mapping
- (void)clearAllKeys {
@synchronized(self) {
_electron->clear_all_keys();
}
}
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
@synchronized(self) {
switch(key)
{
case VK_ANSI_0: _electron->set_key_state(Electron::Key::Key0, isPressed); break;
case VK_ANSI_1: _electron->set_key_state(Electron::Key::Key1, isPressed); break;
case VK_ANSI_2: _electron->set_key_state(Electron::Key::Key2, isPressed); break;
case VK_ANSI_3: _electron->set_key_state(Electron::Key::Key3, isPressed); break;
case VK_ANSI_4: _electron->set_key_state(Electron::Key::Key4, isPressed); break;
case VK_ANSI_5: _electron->set_key_state(Electron::Key::Key5, isPressed); break;
case VK_ANSI_6: _electron->set_key_state(Electron::Key::Key6, isPressed); break;
case VK_ANSI_7: _electron->set_key_state(Electron::Key::Key7, isPressed); break;
case VK_ANSI_8: _electron->set_key_state(Electron::Key::Key8, isPressed); break;
case VK_ANSI_9: _electron->set_key_state(Electron::Key::Key9, isPressed); break;
case VK_ANSI_Q: _electron->set_key_state(Electron::Key::KeyQ, isPressed); break;
case VK_ANSI_W: _electron->set_key_state(Electron::Key::KeyW, isPressed); break;
case VK_ANSI_E: _electron->set_key_state(Electron::Key::KeyE, isPressed); break;
case VK_ANSI_R: _electron->set_key_state(Electron::Key::KeyR, isPressed); break;
case VK_ANSI_T: _electron->set_key_state(Electron::Key::KeyT, isPressed); break;
case VK_ANSI_Y: _electron->set_key_state(Electron::Key::KeyY, isPressed); break;
case VK_ANSI_U: _electron->set_key_state(Electron::Key::KeyU, isPressed); break;
case VK_ANSI_I: _electron->set_key_state(Electron::Key::KeyI, isPressed); break;
case VK_ANSI_O: _electron->set_key_state(Electron::Key::KeyO, isPressed); break;
case VK_ANSI_P: _electron->set_key_state(Electron::Key::KeyP, isPressed); break;
case VK_ANSI_A: _electron->set_key_state(Electron::Key::KeyA, isPressed); break;
case VK_ANSI_S: _electron->set_key_state(Electron::Key::KeyS, isPressed); break;
case VK_ANSI_D: _electron->set_key_state(Electron::Key::KeyD, isPressed); break;
case VK_ANSI_F: _electron->set_key_state(Electron::Key::KeyF, isPressed); break;
case VK_ANSI_G: _electron->set_key_state(Electron::Key::KeyG, isPressed); break;
case VK_ANSI_H: _electron->set_key_state(Electron::Key::KeyH, isPressed); break;
case VK_ANSI_J: _electron->set_key_state(Electron::Key::KeyJ, isPressed); break;
case VK_ANSI_K: _electron->set_key_state(Electron::Key::KeyK, isPressed); break;
case VK_ANSI_L: _electron->set_key_state(Electron::Key::KeyL, isPressed); break;
case VK_ANSI_Z: _electron->set_key_state(Electron::Key::KeyZ, isPressed); break;
case VK_ANSI_X: _electron->set_key_state(Electron::Key::KeyX, isPressed); break;
case VK_ANSI_C: _electron->set_key_state(Electron::Key::KeyC, isPressed); break;
case VK_ANSI_V: _electron->set_key_state(Electron::Key::KeyV, isPressed); break;
case VK_ANSI_B: _electron->set_key_state(Electron::Key::KeyB, isPressed); break;
case VK_ANSI_N: _electron->set_key_state(Electron::Key::KeyN, isPressed); break;
case VK_ANSI_M: _electron->set_key_state(Electron::Key::KeyM, isPressed); break;
case VK_Space: _electron->set_key_state(Electron::Key::KeySpace, isPressed); break;
case VK_ANSI_Grave:
case VK_ANSI_Backslash:
_electron->set_key_state(Electron::Key::KeyCopy, isPressed); break;
case VK_Return: _electron->set_key_state(Electron::Key::KeyReturn, isPressed); break;
case VK_ANSI_Minus: _electron->set_key_state(Electron::Key::KeyMinus, isPressed); break;
case VK_RightArrow: _electron->set_key_state(Electron::Key::KeyRight, isPressed); break;
case VK_LeftArrow: _electron->set_key_state(Electron::Key::KeyLeft, isPressed); break;
case VK_DownArrow: _electron->set_key_state(Electron::Key::KeyDown, isPressed); break;
case VK_UpArrow: _electron->set_key_state(Electron::Key::KeyUp, isPressed); break;
case VK_Delete: _electron->set_key_state(Electron::Key::KeyDelete, isPressed); break;
case VK_Escape: _electron->set_key_state(Electron::Key::KeyEscape, isPressed); break;
case VK_ANSI_Comma: _electron->set_key_state(Electron::Key::KeyComma, isPressed); break;
case VK_ANSI_Period: _electron->set_key_state(Electron::Key::KeyFullStop, isPressed); break;
case VK_ANSI_Semicolon:
_electron->set_key_state(Electron::Key::KeySemiColon, isPressed); break;
case VK_ANSI_Quote: _electron->set_key_state(Electron::Key::KeyColon, isPressed); break;
case VK_ANSI_Slash: _electron->set_key_state(Electron::Key::KeySlash, isPressed); break;
case VK_Shift: _electron->set_key_state(Electron::Key::KeyShift, isPressed); break;
case VK_Control: _electron->set_key_state(Electron::Key::KeyControl, isPressed); break;
case VK_Command:
case VK_Option: _electron->set_key_state(Electron::Key::KeyFunc, isPressed); break;
case VK_F12: _electron->set_key_state(Electron::Key::KeyBreak, isPressed); break;
default:
// printf("%02x\n", key);
break;
}
}
}
- (NSString *)userDefaultsPrefix { return @"electron"; }
#pragma mark - Options

View File

@ -43,99 +43,6 @@
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/Oric"];
}
#pragma mark - CSKeyboardMachine
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
@synchronized(self) {
switch(key) {
case VK_ANSI_0: _oric->set_key_state(Oric::Key::Key0, isPressed); break;
case VK_ANSI_1: _oric->set_key_state(Oric::Key::Key1, isPressed); break;
case VK_ANSI_2: _oric->set_key_state(Oric::Key::Key2, isPressed); break;
case VK_ANSI_3: _oric->set_key_state(Oric::Key::Key3, isPressed); break;
case VK_ANSI_4: _oric->set_key_state(Oric::Key::Key4, isPressed); break;
case VK_ANSI_5: _oric->set_key_state(Oric::Key::Key5, isPressed); break;
case VK_ANSI_6: _oric->set_key_state(Oric::Key::Key6, isPressed); break;
case VK_ANSI_7: _oric->set_key_state(Oric::Key::Key7, isPressed); break;
case VK_ANSI_8: _oric->set_key_state(Oric::Key::Key8, isPressed); break;
case VK_ANSI_9: _oric->set_key_state(Oric::Key::Key9, isPressed); break;
case VK_ANSI_Q: _oric->set_key_state(Oric::Key::KeyQ, isPressed); break;
case VK_ANSI_W: _oric->set_key_state(Oric::Key::KeyW, isPressed); break;
case VK_ANSI_E: _oric->set_key_state(Oric::Key::KeyE, isPressed); break;
case VK_ANSI_R: _oric->set_key_state(Oric::Key::KeyR, isPressed); break;
case VK_ANSI_T: _oric->set_key_state(Oric::Key::KeyT, isPressed); break;
case VK_ANSI_Y: _oric->set_key_state(Oric::Key::KeyY, isPressed); break;
case VK_ANSI_U: _oric->set_key_state(Oric::Key::KeyU, isPressed); break;
case VK_ANSI_I: _oric->set_key_state(Oric::Key::KeyI, isPressed); break;
case VK_ANSI_O: _oric->set_key_state(Oric::Key::KeyO, isPressed); break;
case VK_ANSI_P: _oric->set_key_state(Oric::Key::KeyP, isPressed); break;
case VK_ANSI_A: _oric->set_key_state(Oric::Key::KeyA, isPressed); break;
case VK_ANSI_S: _oric->set_key_state(Oric::Key::KeyS, isPressed); break;
case VK_ANSI_D: _oric->set_key_state(Oric::Key::KeyD, isPressed); break;
case VK_ANSI_F: _oric->set_key_state(Oric::Key::KeyF, isPressed); break;
case VK_ANSI_G: _oric->set_key_state(Oric::Key::KeyG, isPressed); break;
case VK_ANSI_H: _oric->set_key_state(Oric::Key::KeyH, isPressed); break;
case VK_ANSI_J: _oric->set_key_state(Oric::Key::KeyJ, isPressed); break;
case VK_ANSI_K: _oric->set_key_state(Oric::Key::KeyK, isPressed); break;
case VK_ANSI_L: _oric->set_key_state(Oric::Key::KeyL, isPressed); break;
case VK_ANSI_Z: _oric->set_key_state(Oric::Key::KeyZ, isPressed); break;
case VK_ANSI_X: _oric->set_key_state(Oric::Key::KeyX, isPressed); break;
case VK_ANSI_C: _oric->set_key_state(Oric::Key::KeyC, isPressed); break;
case VK_ANSI_V: _oric->set_key_state(Oric::Key::KeyV, isPressed); break;
case VK_ANSI_B: _oric->set_key_state(Oric::Key::KeyB, isPressed); break;
case VK_ANSI_N: _oric->set_key_state(Oric::Key::KeyN, isPressed); break;
case VK_ANSI_M: _oric->set_key_state(Oric::Key::KeyM, isPressed); break;
case VK_Space: _oric->set_key_state(Oric::Key::KeySpace, isPressed); break;
case VK_Return: _oric->set_key_state(Oric::Key::KeyReturn, isPressed); break;
case VK_ANSI_Minus: _oric->set_key_state(Oric::Key::KeyMinus, isPressed); break;
case VK_ANSI_Equal: _oric->set_key_state(Oric::Key::KeyEquals, isPressed); break;
case VK_ANSI_Backslash:
_oric->set_key_state(Oric::Key::KeyBackSlash, isPressed); break;
case VK_ANSI_Slash: _oric->set_key_state(Oric::Key::KeyForwardSlash, isPressed); break;
case VK_ANSI_LeftBracket:
_oric->set_key_state(Oric::Key::KeyOpenSquare, isPressed); break;
case VK_ANSI_RightBracket:
_oric->set_key_state(Oric::Key::KeyCloseSquare, isPressed); break;
case VK_ANSI_Quote: _oric->set_key_state(Oric::Key::KeyQuote, isPressed); break;
case VK_RightArrow: _oric->set_key_state(Oric::Key::KeyRight, isPressed); break;
case VK_LeftArrow: _oric->set_key_state(Oric::Key::KeyLeft, isPressed); break;
case VK_DownArrow: _oric->set_key_state(Oric::Key::KeyDown, isPressed); break;
case VK_UpArrow: _oric->set_key_state(Oric::Key::KeyUp, isPressed); break;
case VK_Delete: _oric->set_key_state(Oric::Key::KeyDelete, isPressed); break;
case VK_Escape: _oric->set_key_state(Oric::Key::KeyEscape, isPressed); break;
case VK_ANSI_Comma: _oric->set_key_state(Oric::Key::KeyComma, isPressed); break;
case VK_ANSI_Period: _oric->set_key_state(Oric::Key::KeyFullStop, isPressed); break;
case VK_ANSI_Semicolon: _oric->set_key_state(Oric::Key::KeySemiColon, isPressed); break;
case VK_Shift:
_oric->set_key_state(Oric::Key::KeyLeftShift, isPressed);
_oric->set_key_state(Oric::Key::KeyRightShift, isPressed);
break;
case VK_RightShift: _oric->set_key_state(Oric::Key::KeyRightShift, isPressed); break;
case VK_Control: _oric->set_key_state(Oric::Key::KeyControl, isPressed); break;
case VK_ANSI_Grave:
case VK_F12: _oric->set_key_state(Oric::Key::KeyNMI, isPressed); break;
default:
printf("%02x\n", key);
break;
}
}
}
- (void)clearAllKeys {
@synchronized(self) {
_oric->clear_all_keys();
}
}
#pragma mark - Options
- (void)setUseFastLoadingHack:(BOOL)useFastLoadingHack {

View File

@ -68,28 +68,8 @@ using namespace Commodore::Vic20;
#pragma mark - Keyboard map
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
/*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
static NSDictionary<NSNumber *, NSNumber *> *vicKeysByKeys = @{
@(VK_ANSI_1): @(Key::Key1), @(VK_ANSI_2): @(Key::Key2),
@(VK_ANSI_3): @(Key::Key3), @(VK_ANSI_4): @(Key::Key4),
@(VK_ANSI_5): @(Key::Key5), @(VK_ANSI_6): @(Key::Key6),
@(VK_ANSI_7): @(Key::Key7), @(VK_ANSI_8): @(Key::Key8),
@(VK_ANSI_9): @(Key::Key9), @(VK_ANSI_0): @(Key::Key0),
@(VK_ANSI_Q): @(Key::KeyQ), @(VK_ANSI_W): @(Key::KeyW),
@(VK_ANSI_E): @(Key::KeyE), @(VK_ANSI_R): @(Key::KeyR),
@(VK_ANSI_T): @(Key::KeyT), @(VK_ANSI_Y): @(Key::KeyY),
@(VK_ANSI_U): @(Key::KeyU), @(VK_ANSI_I): @(Key::KeyI),
@(VK_ANSI_O): @(Key::KeyO), @(VK_ANSI_P): @(Key::KeyP),
@(VK_ANSI_A): @(Key::KeyA), @(VK_ANSI_S): @(Key::KeyS),
@(VK_ANSI_D): @(Key::KeyD), @(VK_ANSI_F): @(Key::KeyF),
@(VK_ANSI_G): @(Key::KeyG), @(VK_ANSI_H): @(Key::KeyH),
@(VK_ANSI_J): @(Key::KeyJ), @(VK_ANSI_K): @(Key::KeyK),
@(VK_ANSI_L): @(Key::KeyL), @(VK_ANSI_Z): @(Key::KeyZ),
@(VK_ANSI_X): @(Key::KeyX), @(VK_ANSI_C): @(Key::KeyC),
@(VK_ANSI_V): @(Key::KeyV), @(VK_ANSI_B): @(Key::KeyB),
@(VK_ANSI_N): @(Key::KeyN), @(VK_ANSI_M): @(Key::KeyM),
@(VK_Space): @(Key::KeySpace),
@(VK_Return): @(Key::KeyReturn),
@(VK_Delete): @(Key::KeyDelete),
@ -156,13 +136,7 @@ using namespace Commodore::Vic20;
}
}
}
}
- (void)clearAllKeys {
@synchronized(self) {
_vic20->clear_all_keys();
}
}
}*/
#pragma mark - Public configuration options

View File

@ -34,69 +34,6 @@
return [[NSBundle mainBundle] dataForResource:name withExtension:@"rom" subdirectory:@"ROMImages/ZX8081"];
}
#pragma mark - Keyboard Mapping
- (void)clearAllKeys {
@synchronized(self) {
_zx8081->clear_all_keys();
}
}
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
@synchronized(self) {
switch(key) {
case VK_ANSI_0: _zx8081->set_key_state(ZX8081::Key::Key0, isPressed); break;
case VK_ANSI_1: _zx8081->set_key_state(ZX8081::Key::Key1, isPressed); break;
case VK_ANSI_2: _zx8081->set_key_state(ZX8081::Key::Key2, isPressed); break;
case VK_ANSI_3: _zx8081->set_key_state(ZX8081::Key::Key3, isPressed); break;
case VK_ANSI_4: _zx8081->set_key_state(ZX8081::Key::Key4, isPressed); break;
case VK_ANSI_5: _zx8081->set_key_state(ZX8081::Key::Key5, isPressed); break;
case VK_ANSI_6: _zx8081->set_key_state(ZX8081::Key::Key6, isPressed); break;
case VK_ANSI_7: _zx8081->set_key_state(ZX8081::Key::Key7, isPressed); break;
case VK_ANSI_8: _zx8081->set_key_state(ZX8081::Key::Key8, isPressed); break;
case VK_ANSI_9: _zx8081->set_key_state(ZX8081::Key::Key9, isPressed); break;
case VK_ANSI_Q: _zx8081->set_key_state(ZX8081::Key::KeyQ, isPressed); break;
case VK_ANSI_W: _zx8081->set_key_state(ZX8081::Key::KeyW, isPressed); break;
case VK_ANSI_E: _zx8081->set_key_state(ZX8081::Key::KeyE, isPressed); break;
case VK_ANSI_R: _zx8081->set_key_state(ZX8081::Key::KeyR, isPressed); break;
case VK_ANSI_T: _zx8081->set_key_state(ZX8081::Key::KeyT, isPressed); break;
case VK_ANSI_Y: _zx8081->set_key_state(ZX8081::Key::KeyY, isPressed); break;
case VK_ANSI_U: _zx8081->set_key_state(ZX8081::Key::KeyU, isPressed); break;
case VK_ANSI_I: _zx8081->set_key_state(ZX8081::Key::KeyI, isPressed); break;
case VK_ANSI_O: _zx8081->set_key_state(ZX8081::Key::KeyO, isPressed); break;
case VK_ANSI_P: _zx8081->set_key_state(ZX8081::Key::KeyP, isPressed); break;
case VK_ANSI_A: _zx8081->set_key_state(ZX8081::Key::KeyA, isPressed); break;
case VK_ANSI_S: _zx8081->set_key_state(ZX8081::Key::KeyS, isPressed); break;
case VK_ANSI_D: _zx8081->set_key_state(ZX8081::Key::KeyD, isPressed); break;
case VK_ANSI_F: _zx8081->set_key_state(ZX8081::Key::KeyF, isPressed); break;
case VK_ANSI_G: _zx8081->set_key_state(ZX8081::Key::KeyG, isPressed); break;
case VK_ANSI_H: _zx8081->set_key_state(ZX8081::Key::KeyH, isPressed); break;
case VK_ANSI_J: _zx8081->set_key_state(ZX8081::Key::KeyJ, isPressed); break;
case VK_ANSI_K: _zx8081->set_key_state(ZX8081::Key::KeyK, isPressed); break;
case VK_ANSI_L: _zx8081->set_key_state(ZX8081::Key::KeyL, isPressed); break;
case VK_ANSI_Z: _zx8081->set_key_state(ZX8081::Key::KeyZ, isPressed); break;
case VK_ANSI_X: _zx8081->set_key_state(ZX8081::Key::KeyX, isPressed); break;
case VK_ANSI_C: _zx8081->set_key_state(ZX8081::Key::KeyC, isPressed); break;
case VK_ANSI_V: _zx8081->set_key_state(ZX8081::Key::KeyV, isPressed); break;
case VK_ANSI_B: _zx8081->set_key_state(ZX8081::Key::KeyB, isPressed); break;
case VK_ANSI_N: _zx8081->set_key_state(ZX8081::Key::KeyN, isPressed); break;
case VK_ANSI_M: _zx8081->set_key_state(ZX8081::Key::KeyM, isPressed); break;
case VK_Shift:
case VK_RightShift:
_zx8081->set_key_state(ZX8081::Key::KeyShift, isPressed); break;
break;
case VK_ANSI_Period:_zx8081->set_key_state(ZX8081::Key::KeyDot, isPressed); break;
case VK_Return: _zx8081->set_key_state(ZX8081::Key::KeyEnter, isPressed); break;
case VK_Space: _zx8081->set_key_state(ZX8081::Key::KeySpace, isPressed); break;
}
}
}
- (NSString *)userDefaultsPrefix { return @"zx8081"; }
#pragma mark - Options