1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +00:00

Switched the Objective-C code to using dynamic_cast alone to decide whether to post keyboard or joystick events.

This commit is contained in:
Thomas Harte 2017-10-15 21:25:56 -04:00
parent 18798c9886
commit 542ec4312f
13 changed files with 99 additions and 161 deletions

View File

@ -3,7 +3,6 @@
//
#import "CSMachine.h"
#import "CSKeyboardMachine.h"
#import "CSFastLoading.h"
#import "CSAtari2600.h"
@ -17,3 +16,5 @@
#import "CSOpenGLView.h"
#import "CSAudioQueue.h"
#import "CSBestEffortUpdater.h"
#include "KeyCodes.h"

View File

@ -187,48 +187,22 @@ class MachineDocument:
}
// MARK: Input management
fileprivate func withKeyboardMachine(_ action: (CSKeyboardMachine) -> ()) {
if let keyboardMachine = self.machine as? CSKeyboardMachine {
action(keyboardMachine)
}
}
fileprivate func withJoystickMachine(_ action: (CSJoystickMachine) -> ()) {
if let joystickMachine = self.machine as? CSJoystickMachine {
action(joystickMachine)
}
}
fileprivate func sendJoystickEvent(_ machine: CSJoystickMachine, keyCode: UInt16, isPressed: Bool) {
switch keyCode {
case 123: machine.setDirection(.left, onPad: 0, isPressed: isPressed)
case 126: machine.setDirection(.up, onPad: 0, isPressed: isPressed)
case 124: machine.setDirection(.right, onPad: 0, isPressed: isPressed)
case 125: machine.setDirection(.down, onPad: 0, isPressed: isPressed)
default: machine.setButtonAt(0, onPad: 0, isPressed: isPressed)
}
}
func windowDidResignKey(_ notification: Notification) {
self.withKeyboardMachine { $0.clearAllKeys() }
self.machine.clearAllKeys()
}
func keyDown(_ event: NSEvent) {
self.withKeyboardMachine { $0.setKey(event.keyCode, isPressed: true) }
self.withJoystickMachine { sendJoystickEvent($0, keyCode: event.keyCode, isPressed: true) }
self.machine.setKey(event.keyCode, isPressed: true)
}
func keyUp(_ event: NSEvent) {
self.withKeyboardMachine { $0.setKey(event.keyCode, isPressed: false) }
self.withJoystickMachine { sendJoystickEvent($0, keyCode: event.keyCode, isPressed: false) }
self.machine.setKey(event.keyCode, isPressed: false)
}
func flagsChanged(_ newModifiers: NSEvent) {
self.withKeyboardMachine {
$0.setKey(VK_Shift, isPressed: newModifiers.modifierFlags.contains(.shift))
$0.setKey(VK_Control, isPressed: newModifiers.modifierFlags.contains(.control))
$0.setKey(VK_Command, isPressed: newModifiers.modifierFlags.contains(.command))
$0.setKey(VK_Option, isPressed: newModifiers.modifierFlags.contains(.option))
}
self.machine.setKey(VK_Shift, isPressed: newModifiers.modifierFlags.contains(.shift))
self.machine.setKey(VK_Control, isPressed: newModifiers.modifierFlags.contains(.control))
self.machine.setKey(VK_Command, isPressed: newModifiers.modifierFlags.contains(.command))
self.machine.setKey(VK_Option, isPressed: newModifiers.modifierFlags.contains(.option))
}
}

View File

@ -1,22 +0,0 @@
//
// CSJoystickMachine.h
// Clock Signal
//
// Created by Thomas Harte on 03/10/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
typedef NS_ENUM(NSInteger, CSJoystickDirection)
{
CSJoystickDirectionUp,
CSJoystickDirectionDown,
CSJoystickDirectionLeft,
CSJoystickDirectionRight
};
@protocol CSJoystickMachine <NSObject>
- (void)setButtonAtIndex:(NSUInteger)button onPad:(NSUInteger)pad isPressed:(BOOL)isPressed;
- (void)setDirection:(CSJoystickDirection)direction onPad:(NSUInteger)pad isPressed:(BOOL)isPressed;
@end

View File

@ -1,16 +0,0 @@
//
// CSKeyboardMachine.h
// Clock Signal
//
// Created by Thomas Harte on 05/06/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#import "KeyCodes.h"
@protocol CSKeyboardMachine <NSObject>
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed;
- (void)clearAllKeys;
@end

View File

@ -35,6 +35,9 @@
- (void)setView:(CSOpenGLView *)view aspectRatio:(float)aspectRatio;
- (void)drawViewForPixelSize:(CGSize)pixelSize onlyIfDirty:(BOOL)onlyIfDirty;
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed;
- (void)clearAllKeys;
@property (nonatomic, strong) CSAudioQueue *audioQueue;
@property (nonatomic, readonly) CSOpenGLView *view;
@property (nonatomic, weak) id<CSMachineDelegate> delegate;
@ -46,9 +49,4 @@
- (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,10 +10,11 @@
#import "CSMachine+Subclassing.h"
#import "CSMachine+Target.h"
#import "CSKeyboardMachine.h"
#include "KeyCodes.h"
#include "Typer.hpp"
#include "ConfigurationTarget.hpp"
#include "JoystickMachine.hpp"
#include "KeyboardMachine.hpp"
@interface CSMachine()
- (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
@ -187,75 +188,103 @@ 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;
if(keyboard_machine) {
@synchronized(self) {
Inputs::Keyboard &keyboard = keyboard_machine->get_keyboard();
@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.
// 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);
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_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_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_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_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_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_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_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_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_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);
}
BIND(VK_LeftArrow, Left); BIND(VK_RightArrow, Right);
BIND(VK_DownArrow, Down); BIND(VK_UpArrow, Up);
}
#undef BIND
}
return;
}
auto joystick_machine = dynamic_cast<JoystickMachine::Machine *>(_machine);
if(joystick_machine) {
@synchronized(self) {
std::vector<std::unique_ptr<Inputs::Joystick>> &joysticks = joystick_machine->get_joysticks();
if(!joysticks.empty()) {
switch(key) {
case VK_LeftArrow: joysticks[0]->set_digital_input(Inputs::Joystick::DigitalInput::Left, isPressed); break;
case VK_RightArrow: joysticks[0]->set_digital_input(Inputs::Joystick::DigitalInput::Right, isPressed); break;
case VK_UpArrow: joysticks[0]->set_digital_input(Inputs::Joystick::DigitalInput::Up, isPressed); break;
case VK_DownArrow: joysticks[0]->set_digital_input(Inputs::Joystick::DigitalInput::Down, isPressed); break;
default:
joysticks[0]->set_digital_input(Inputs::Joystick::DigitalInput::Fire, isPressed); break;
break;
}
}
}
}
}
- (void)clearAllKeys {
auto keyboard_machine = dynamic_cast<KeyboardMachine::Machine *>(_machine);
if(!keyboard_machine) return;
if(keyboard_machine) {
@synchronized(self) {
keyboard_machine->get_keyboard().reset_all_keys();
}
}
@synchronized(self) {
keyboard_machine->get_keyboard().reset_all_keys();
auto joystick_machine = dynamic_cast<JoystickMachine::Machine *>(_machine);
if(joystick_machine) {
@synchronized(self) {
for(auto &joystick : joystick_machine->get_joysticks()) {
joystick->reset_all_inputs();
}
}
}
}

View File

@ -7,9 +7,8 @@
//
#import "CSMachine.h"
#import "CSKeyboardMachine.h"
@interface CSAmstradCPC : CSMachine <CSKeyboardMachine>
@interface CSAmstradCPC : CSMachine
- (instancetype)init;

View File

@ -8,9 +8,8 @@
#include "CSMachine.h"
#include "Atari2600Inputs.h"
#import "CSJoystickMachine.h"
@interface CSAtari2600 : CSMachine <CSJoystickMachine>
@interface CSAtari2600 : CSMachine
- (instancetype)init;

View File

@ -24,26 +24,6 @@
return self;
}
- (void)setDirection:(CSJoystickDirection)direction onPad:(NSUInteger)pad isPressed:(BOOL)isPressed {
// Atari2600DigitalInput input;
// switch(direction)
// {
// case CSJoystickDirectionUp: input = pad ? Atari2600DigitalInputJoy2Up : Atari2600DigitalInputJoy1Up; break;
// case CSJoystickDirectionDown: input = pad ? Atari2600DigitalInputJoy2Down : Atari2600DigitalInputJoy1Down; break;
// case CSJoystickDirectionLeft: input = pad ? Atari2600DigitalInputJoy2Left : Atari2600DigitalInputJoy1Left; break;
// case CSJoystickDirectionRight: input = pad ? Atari2600DigitalInputJoy2Right : Atari2600DigitalInputJoy1Right; break;
// }
// @synchronized(self) {
// _atari2600->set_digital_input(input, isPressed ? true : false);
// }
}
- (void)setButtonAtIndex:(NSUInteger)button onPad:(NSUInteger)pad isPressed:(BOOL)isPressed {
// @synchronized(self) {
// _atari2600->set_digital_input(pad ? Atari2600DigitalInputJoy2Fire : Atari2600DigitalInputJoy1Fire, isPressed ? true : false);
// }
}
- (void)setResetLineEnabled:(BOOL)enabled {
@synchronized(self) {
_atari2600->set_reset_switch(enabled ? true : false);

View File

@ -7,10 +7,9 @@
//
#import "CSMachine.h"
#import "CSKeyboardMachine.h"
#import "CSFastLoading.h"
@interface CSElectron : CSMachine <CSKeyboardMachine, CSFastLoading>
@interface CSElectron : CSMachine <CSFastLoading>
- (instancetype)init;

View File

@ -7,10 +7,9 @@
//
#import "CSMachine.h"
#import "CSKeyboardMachine.h"
#import "CSFastLoading.h"
@interface CSOric : CSMachine <CSKeyboardMachine, CSFastLoading>
@interface CSOric : CSMachine <CSFastLoading>
- (instancetype)init;

View File

@ -7,7 +7,6 @@
//
#import "CSMachine.h"
#import "CSKeyboardMachine.h"
#import "CSFastLoading.h"
typedef NS_ENUM(NSInteger, CSVic20Country)
@ -26,7 +25,7 @@ typedef NS_ENUM(NSInteger, CSVic20MemorySize)
CSVic20MemorySize32Kb,
};
@interface CSVic20 : CSMachine <CSKeyboardMachine, CSFastLoading>
@interface CSVic20 : CSMachine <CSFastLoading>
- (instancetype)init;

View File

@ -7,10 +7,9 @@
//
#import "CSMachine.h"
#import "CSKeyboardMachine.h"
#import "CSFastLoading.h"
@interface CSZX8081 : CSMachine <CSKeyboardMachine, CSFastLoading>
@interface CSZX8081 : CSMachine <CSFastLoading>
@property (nonatomic, assign) BOOL useFastLoadingHack;