mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Introduces a joystick analogue to the shared keyboard interface, and implements it for the Vic-20.
This commit is contained in:
parent
3a05ce36de
commit
ee179aa7bd
9
Inputs/Joystick.cpp
Normal file
9
Inputs/Joystick.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// Joystick.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 14/10/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Joystick.hpp"
|
35
Inputs/Joystick.hpp
Normal file
35
Inputs/Joystick.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Joystick.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 14/10/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Joystick_hpp
|
||||
#define Joystick_hpp
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Inputs {
|
||||
|
||||
/*!
|
||||
Provides an intermediate idealised model of a simple joystick, allowing a host
|
||||
machine to toggle states, while an interested party either observes or polls.
|
||||
*/
|
||||
class Joystick {
|
||||
public:
|
||||
virtual ~Joystick() {}
|
||||
|
||||
enum class DigitalInput {
|
||||
Up, Down, Left, Right, Fire
|
||||
};
|
||||
|
||||
// Host interface.
|
||||
virtual void set_digital_input(DigitalInput digital_input, bool is_active) = 0;
|
||||
virtual void reset_all_inputs() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* Joystick_hpp */
|
@ -30,6 +30,14 @@
|
||||
namespace Commodore {
|
||||
namespace Vic20 {
|
||||
|
||||
enum JoystickInput {
|
||||
Up = 0x04,
|
||||
Down = 0x08,
|
||||
Left = 0x10,
|
||||
Right = 0x80,
|
||||
Fire = 0x20
|
||||
};
|
||||
|
||||
/*!
|
||||
Models the user-port VIA, which is the Vic's connection point for controlling its tape recorder —
|
||||
sensing the presence or absence of a tape and controlling the tape motor — and reading the current
|
||||
@ -214,6 +222,38 @@ class Vic6560: public MOS::MOS6560<Vic6560> {
|
||||
uint8_t *colour_memory; // Colour memory must be contiguous.
|
||||
};
|
||||
|
||||
/*!
|
||||
Interfaces a joystick to the two VIAs.
|
||||
*/
|
||||
class Joystick: public Inputs::Joystick {
|
||||
public:
|
||||
Joystick(UserPortVIA &user_port_via_port_handler, KeyboardVIA &keyboard_via_port_handler) :
|
||||
user_port_via_port_handler_(user_port_via_port_handler),
|
||||
keyboard_via_port_handler_(keyboard_via_port_handler) {}
|
||||
|
||||
void set_digital_input(DigitalInput digital_input, bool is_active) override {
|
||||
JoystickInput mapped_input;
|
||||
switch (digital_input) {
|
||||
default: return;
|
||||
case DigitalInput::Up: mapped_input = Up; break;
|
||||
case DigitalInput::Down: mapped_input = Down; break;
|
||||
case DigitalInput::Left: mapped_input = Left; break;
|
||||
case DigitalInput::Right: mapped_input = Right; break;
|
||||
case DigitalInput::Fire: mapped_input = Fire; break;
|
||||
}
|
||||
|
||||
user_port_via_port_handler_.set_joystick_state(mapped_input, is_active);
|
||||
keyboard_via_port_handler_.set_joystick_state(mapped_input, is_active);
|
||||
}
|
||||
|
||||
void reset_all_inputs() override {
|
||||
}
|
||||
|
||||
private:
|
||||
UserPortVIA &user_port_via_port_handler_;
|
||||
KeyboardVIA &keyboard_via_port_handler_;
|
||||
};
|
||||
|
||||
class ConcreteMachine:
|
||||
public CPU::MOS6502::BusHandler,
|
||||
public MOS::MOS6522::IRQDelegatePortHandler::Delegate,
|
||||
@ -253,6 +293,9 @@ class ConcreteMachine:
|
||||
|
||||
// set the NTSC clock rate
|
||||
set_region(NTSC);
|
||||
|
||||
// install a joystick
|
||||
joysticks_.push_back(new Joystick(*user_port_via_port_handler_, *keyboard_via_port_handler_));
|
||||
}
|
||||
|
||||
~ConcreteMachine() {
|
||||
@ -340,9 +383,8 @@ class ConcreteMachine:
|
||||
keyboard_via_port_handler_->clear_all_keys();
|
||||
}
|
||||
|
||||
void set_joystick_state(JoystickInput input, bool isPressed) override final {
|
||||
user_port_via_port_handler_->set_joystick_state(input, isPressed);
|
||||
keyboard_via_port_handler_->set_joystick_state(input, isPressed);
|
||||
std::vector<Inputs::Joystick *> &get_joysticks() override {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
void set_memory_size(MemorySize size) override final {
|
||||
@ -580,6 +622,7 @@ class ConcreteMachine:
|
||||
|
||||
Region region_;
|
||||
Commodore::Vic20::KeyboardMapper keyboard_mapper_;
|
||||
std::vector<Inputs::Joystick *> joysticks_;
|
||||
|
||||
std::unique_ptr<Vic6560> mos6560_;
|
||||
std::shared_ptr<UserPortVIA> user_port_via_port_handler_;
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "../../ConfigurationTarget.hpp"
|
||||
#include "../../CRTMachine.hpp"
|
||||
#include "../../KeyboardMachine.hpp"
|
||||
#include "../../JoystickMachine.hpp"
|
||||
#include "../../Typer.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
@ -59,18 +61,11 @@ enum Key: uint16_t {
|
||||
#undef key
|
||||
};
|
||||
|
||||
enum JoystickInput {
|
||||
Up = 0x04,
|
||||
Down = 0x08,
|
||||
Left = 0x10,
|
||||
Right = 0x80,
|
||||
Fire = 0x20
|
||||
};
|
||||
|
||||
class Machine:
|
||||
public CRTMachine::Machine,
|
||||
public ConfigurationTarget::Machine,
|
||||
public KeyboardMachine::Machine {
|
||||
public KeyboardMachine::Machine,
|
||||
public JoystickMachine::Machine {
|
||||
public:
|
||||
virtual ~Machine();
|
||||
|
||||
@ -81,9 +76,6 @@ class Machine:
|
||||
virtual void set_rom(ROMSlot slot, size_t length, const uint8_t *data) = 0;
|
||||
// TODO: take a std::vector<uint8_t> to collapse length and data.
|
||||
|
||||
/// Sets the state of joystick input @c input.
|
||||
virtual void set_joystick_state(JoystickInput input, bool isPressed) = 0;
|
||||
|
||||
/// Sets the memory size of this Vic-20.
|
||||
virtual void set_memory_size(MemorySize size) = 0;
|
||||
|
||||
|
24
Machines/JoystickMachine.hpp
Normal file
24
Machines/JoystickMachine.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// JoystickMachine.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 14/10/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef JoystickMachine_hpp
|
||||
#define JoystickMachine_hpp
|
||||
|
||||
#include "../Inputs/Joystick.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace JoystickMachine {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual std::vector<Inputs::Joystick *> &get_joysticks() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* JoystickMachine_hpp */
|
@ -100,6 +100,7 @@
|
||||
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */; };
|
||||
4B69FB461C4D950F00B5F0AA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; };
|
||||
4B6A4C991F58F09E00E3F787 /* 6502Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */; };
|
||||
4B70412B1F92C2A700735E45 /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7041291F92C2A700735E45 /* Joystick.cpp */; };
|
||||
4B7136861F78724F008B8ED9 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136841F78724F008B8ED9 /* Encoder.cpp */; };
|
||||
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136871F78725F008B8ED9 /* Shifter.cpp */; };
|
||||
4B71368E1F788112008B8ED9 /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B71368C1F788112008B8ED9 /* Parser.cpp */; };
|
||||
@ -672,6 +673,9 @@
|
||||
4B6A4C911F58F09E00E3F787 /* 6502AllRAM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 6502AllRAM.cpp; sourceTree = "<group>"; };
|
||||
4B6A4C921F58F09E00E3F787 /* 6502AllRAM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6502AllRAM.hpp; sourceTree = "<group>"; };
|
||||
4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 6502Base.cpp; sourceTree = "<group>"; };
|
||||
4B7041271F92C26900735E45 /* JoystickMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = JoystickMachine.hpp; sourceTree = "<group>"; };
|
||||
4B7041291F92C2A700735E45 /* Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = "<group>"; };
|
||||
4B70412A1F92C2A700735E45 /* Joystick.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Joystick.hpp; sourceTree = "<group>"; };
|
||||
4B7136841F78724F008B8ED9 /* Encoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Encoder.cpp; sourceTree = "<group>"; };
|
||||
4B7136851F78724F008B8ED9 /* Encoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Encoder.hpp; sourceTree = "<group>"; };
|
||||
4B7136871F78725F008B8ED9 /* Shifter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Shifter.cpp; sourceTree = "<group>"; };
|
||||
@ -1748,6 +1752,8 @@
|
||||
children = (
|
||||
4B86E2591F8C628F006FAA45 /* Keyboard.cpp */,
|
||||
4B86E25A1F8C628F006FAA45 /* Keyboard.hpp */,
|
||||
4B7041291F92C2A700735E45 /* Joystick.cpp */,
|
||||
4B70412A1F92C2A700735E45 /* Joystick.hpp */,
|
||||
);
|
||||
name = Inputs;
|
||||
path = ../../Inputs;
|
||||
@ -2203,6 +2209,7 @@
|
||||
4B1E85731D170228001EF87D /* Typer.cpp */,
|
||||
4BA9C3CF1D8164A9002DDB61 /* ConfigurationTarget.hpp */,
|
||||
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */,
|
||||
4B7041271F92C26900735E45 /* JoystickMachine.hpp */,
|
||||
4B8E4ECD1DCE483D003716C3 /* KeyboardMachine.hpp */,
|
||||
4B2A33291DB8544D002876E3 /* MemoryFuzzer.hpp */,
|
||||
4B1E85741D170228001EF87D /* Typer.hpp */,
|
||||
@ -2995,6 +3002,7 @@
|
||||
4BC5E4921D7ED365008CF980 /* StaticAnalyser.cpp in Sources */,
|
||||
4BC830D11D6E7C690000A26F /* Tape.cpp in Sources */,
|
||||
4B54C0C51F8D91D90050900F /* KeyboardMapper.cpp in Sources */,
|
||||
4B70412B1F92C2A700735E45 /* Joystick.cpp in Sources */,
|
||||
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */,
|
||||
4B86E25B1F8C628F006FAA45 /* Keyboard.cpp in Sources */,
|
||||
4B4518851F75E91A00926311 /* DiskController.cpp in Sources */,
|
||||
|
@ -69,44 +69,6 @@ using namespace Commodore::Vic20;
|
||||
#pragma mark - Keyboard map
|
||||
|
||||
/*- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
|
||||
static NSDictionary<NSNumber *, NSNumber *> *vicKeysByKeys = @{
|
||||
@(VK_Space): @(Key::KeySpace),
|
||||
@(VK_Return): @(Key::KeyReturn),
|
||||
@(VK_Delete): @(Key::KeyDelete),
|
||||
@(VK_ANSI_Comma): @(Key::KeyComma),
|
||||
@(VK_ANSI_Period): @(Key::KeyFullStop),
|
||||
@(VK_ANSI_Minus): @(Key::KeyDash),
|
||||
@(VK_ANSI_Equal): @(Key::KeyEquals),
|
||||
@(VK_ANSI_Semicolon): @(Key::KeyColon),
|
||||
@(VK_ANSI_Quote): @(Key::KeySemicolon),
|
||||
@(VK_ANSI_Slash): @(Key::KeySlash),
|
||||
@(VK_Option): @(Key::KeyCBM),
|
||||
@(VK_Control): @(Key::KeyControl),
|
||||
|
||||
@(VK_F1): @(Key::KeyF1), @(VK_F3): @(Key::KeyF3),
|
||||
@(VK_F5): @(Key::KeyF5), @(VK_F7): @(Key::KeyF7),
|
||||
|
||||
@(VK_ANSI_Grave): @(Key::KeyLeft),
|
||||
@(VK_Tab): @(Key::KeyRunStop),
|
||||
@(VK_ANSI_LeftBracket): @(Key::KeyAt),
|
||||
@(VK_ANSI_RightBracket): @(Key::KeyAsterisk),
|
||||
@(VK_ANSI_Backslash): @(Key::KeyUp),
|
||||
|
||||
@(VK_RightArrow): @(Key::KeyRight),
|
||||
@(VK_DownArrow): @(Key::KeyDown),
|
||||
};
|
||||
|
||||
// Not yet mapped:
|
||||
// KeyHome
|
||||
// KeyPlus
|
||||
// KeyGBP
|
||||
|
||||
if(key == VK_Tab && isPressed) {
|
||||
_joystickMode ^= YES;
|
||||
}
|
||||
|
||||
@synchronized(self) {
|
||||
if(_joystickMode) {
|
||||
switch(key) {
|
||||
case VK_UpArrow: _vic20->set_joystick_state(JoystickInput::Up, isPressed); break;
|
||||
case VK_DownArrow: _vic20->set_joystick_state(JoystickInput::Down, isPressed); break;
|
||||
@ -114,28 +76,6 @@ using namespace Commodore::Vic20;
|
||||
case VK_RightArrow: _vic20->set_joystick_state(JoystickInput::Right, isPressed); break;
|
||||
case VK_ANSI_A: _vic20->set_joystick_state(JoystickInput::Fire, isPressed); break;
|
||||
}
|
||||
} else {
|
||||
switch(key) {
|
||||
default: {
|
||||
NSNumber *targetKey = vicKeysByKeys[@(key)];
|
||||
if(targetKey)
|
||||
{
|
||||
_vic20->set_key_state((Key)targetKey.integerValue, isPressed);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Unmapped: %02x", key);
|
||||
}
|
||||
} break;
|
||||
|
||||
case VK_Shift:
|
||||
// Yuck
|
||||
_vic20->set_key_state(Key::KeyLShift, isPressed);
|
||||
_vic20->set_key_state(Key::KeyRShift, isPressed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
#pragma mark - Public configuration options
|
||||
|
Loading…
Reference in New Issue
Block a user