1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-03-25 06:30:38 +00:00

Move mouse and joystick into a separate file, give a common parent.

This commit is contained in:
Thomas Harte 2021-11-26 17:50:47 -05:00
parent eca80f1425
commit bea6cf2038
5 changed files with 192 additions and 147 deletions

View File

@ -1193,121 +1193,6 @@ void Chipset::set_component_prefers_clocking(ClockingHint::Source *, ClockingHin
disk_controller_is_sleeping_ = preference == ClockingHint::Preference::None;
}
// MARK: - Mouse.
int Chipset::Mouse::get_number_of_buttons() {
return 2;
}
void Chipset::Mouse::set_button_pressed(int button, bool is_set) {
switch(button) {
case 0:
cia_state_ = (cia_state_ &~ 0x40) | (is_set ? 0 : 0x40);
break;
default:
break;
}
}
uint8_t Chipset::Mouse::get_cia_button() const {
return cia_state_;
}
void Chipset::Mouse::reset_all_buttons() {
cia_state_ = 0xff;
}
void Chipset::Mouse::move(int x, int y) {
position_[0] += x;
position_[1] += y;
}
Inputs::Mouse &Chipset::get_mouse() {
return mouse_;
}
uint16_t Chipset::Mouse::get_position() {
// The Amiga hardware retains only eight bits of position
// for the mouse; its software polls frequently and maps
// changes into a larger space.
//
// On modern computers with 5k+ displays and trackpads, it
// proved empirically possible to overflow the hardware
// counters more quickly than software would poll.
//
// Therefore the approach taken for mapping mouse motion
// into the Amiga is to do it in steps of no greater than
// [-128, +127], as per the below.
const int pending[] = {
position_[0], position_[1]
};
const int8_t change[] = {
int8_t(std::clamp(pending[0], -128, 127)),
int8_t(std::clamp(pending[1], -128, 127))
};
position_[0] -= change[0];
position_[1] -= change[1];
declared_position_[0] += change[0];
declared_position_[1] += change[1];
return uint16_t(
(declared_position_[1] << 8) |
declared_position_[0]
);
}
// MARK: - Joystick.
// TODO: add second fire button.
Chipset::Joystick::Joystick() :
ConcreteJoystick({
Input(Input::Up),
Input(Input::Down),
Input(Input::Left),
Input(Input::Right),
Input(Input::Fire, 0),
}) {}
void Chipset::Joystick::did_set_input(const Input &input, bool is_active) {
// Accumulate state.
inputs_[input.type] = is_active;
// Determine what that does to the two position bits.
const auto low =
(inputs_[Input::Type::Down] ^ inputs_[Input::Type::Right]) |
(inputs_[Input::Type::Right] << 1);
const auto high =
(inputs_[Input::Type::Up] ^ inputs_[Input::Type::Left]) |
(inputs_[Input::Type::Left] << 1);
// Ripple upwards if that affects the mouse position counters.
const uint8_t previous_low = position_ & 3;
uint8_t low_upper = (position_ >> 2) & 0x3f;
const uint8_t previous_high = (position_ >> 8) & 3;
uint8_t high_upper = (position_ >> 10) & 0x3f;
if(!low && previous_low == 3) ++low_upper;
if(!previous_low && low == 3) --low_upper;
if(!high && previous_high == 3) ++high_upper;
if(!previous_high && high == 3) --high_upper;
position_ = uint16_t(
low | ((low_upper & 0x3f) << 2) |
(high << 8) | ((high_upper & 0x3f) << 10)
);
}
uint16_t Chipset::Joystick::get_position() const {
return position_;
}
uint8_t Chipset::Joystick::get_cia_button() const {
return inputs_[Input::Type::Fire] ? 0xbf : 0xff;
}
// MARK: - Synchronisation.
void Chipset::flush() {

View File

@ -19,8 +19,6 @@
#include "../../ClockReceiver/ClockingHintSource.hpp"
#include "../../ClockReceiver/JustInTime.hpp"
#include "../../Components/6526/6526.hpp"
#include "../../Inputs/Joystick.hpp"
#include "../../Inputs/Mouse.hpp"
#include "../../Outputs/CRT/CRT.hpp"
#include "../../Processors/68000/68000.hpp"
#include "../../Storage/Disk/Controller/DiskController.hpp"
@ -32,6 +30,7 @@
#include "DMADevice.hpp"
#include "Flags.hpp"
#include "Keyboard.hpp"
#include "MouseJoystick.hpp"
#include "MemoryMap.hpp"
#include "Sprites.hpp"
@ -284,41 +283,15 @@ class Chipset: private ClockingHint::Observer {
// MARK: - Mouse.
private:
class Mouse: public Inputs::Mouse {
public:
uint16_t get_position();
uint8_t get_cia_button() const;
private:
int get_number_of_buttons() final;
void set_button_pressed(int, bool) final;
void reset_all_buttons() final;
void move(int, int) final;
uint8_t declared_position_[2]{};
uint8_t cia_state_ = 0xff;
std::array<std::atomic<int>, 2> position_{};
} mouse_;
Mouse mouse_;
public:
Inputs::Mouse &get_mouse();
Inputs::Mouse &get_mouse() {
return mouse_;
}
// MARK: - Joystick.
private:
class Joystick: public Inputs::ConcreteJoystick {
public:
Joystick();
uint16_t get_position() const;
uint8_t get_cia_button() const;
private:
void did_set_input(const Input &input, bool is_active) final;
bool inputs_[Joystick::Input::Type::Max]{};
uint16_t position_ = 0;
};
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
Joystick &joystick(size_t index) const {
return *static_cast<Joystick *>(joysticks_[index].get());

View File

@ -0,0 +1,122 @@
//
// MouseJoystick.cpp
// Clock Signal
//
// Created by Thomas Harte on 26/11/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#include "MouseJoystick.hpp"
using namespace Amiga;
// MARK: - Mouse.
int Mouse::get_number_of_buttons() {
return 2;
}
void Mouse::set_button_pressed(int button, bool is_set) {
switch(button) {
case 0:
cia_state_ = (cia_state_ &~ 0x40) | (is_set ? 0 : 0x40);
break;
default:
break;
}
}
uint8_t Mouse::get_cia_button() const {
return cia_state_;
}
void Mouse::reset_all_buttons() {
cia_state_ = 0xff;
}
void Mouse::move(int x, int y) {
position_[0] += x;
position_[1] += y;
}
uint16_t Mouse::get_position() {
// The Amiga hardware retains only eight bits of position
// for the mouse; its software polls frequently and maps
// changes into a larger space.
//
// On modern computers with 5k+ displays and trackpads, it
// proved empirically possible to overflow the hardware
// counters more quickly than software would poll.
//
// Therefore the approach taken for mapping mouse motion
// into the Amiga is to do it in steps of no greater than
// [-128, +127], as per the below.
const int pending[] = {
position_[0], position_[1]
};
const int8_t change[] = {
int8_t(std::clamp(pending[0], -128, 127)),
int8_t(std::clamp(pending[1], -128, 127))
};
position_[0] -= change[0];
position_[1] -= change[1];
declared_position_[0] += change[0];
declared_position_[1] += change[1];
return uint16_t(
(declared_position_[1] << 8) |
declared_position_[0]
);
}
// MARK: - Joystick.
// TODO: add second fire button.
Joystick::Joystick() :
ConcreteJoystick({
Input(Input::Up),
Input(Input::Down),
Input(Input::Left),
Input(Input::Right),
Input(Input::Fire, 0),
}) {}
void Joystick::did_set_input(const Input &input, bool is_active) {
// Accumulate state.
inputs_[input.type] = is_active;
// Determine what that does to the two position bits.
const auto low =
(inputs_[Input::Type::Down] ^ inputs_[Input::Type::Right]) |
(inputs_[Input::Type::Right] << 1);
const auto high =
(inputs_[Input::Type::Up] ^ inputs_[Input::Type::Left]) |
(inputs_[Input::Type::Left] << 1);
// Ripple upwards if that affects the mouse position counters.
const uint8_t previous_low = position_ & 3;
uint8_t low_upper = (position_ >> 2) & 0x3f;
const uint8_t previous_high = (position_ >> 8) & 3;
uint8_t high_upper = (position_ >> 10) & 0x3f;
if(!low && previous_low == 3) ++low_upper;
if(!previous_low && low == 3) --low_upper;
if(!high && previous_high == 3) ++high_upper;
if(!previous_high && high == 3) --high_upper;
position_ = uint16_t(
low | ((low_upper & 0x3f) << 2) |
(high << 8) | ((high_upper & 0x3f) << 10)
);
}
uint16_t Joystick::get_position() {
return position_;
}
uint8_t Joystick::get_cia_button() const {
return inputs_[Input::Type::Fire] ? 0xbf : 0xff;
}

View File

@ -0,0 +1,57 @@
//
// MouseJoystick.hpp
// Clock Signal
//
// Created by Thomas Harte on 26/11/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef MouseJoystick_hpp
#define MouseJoystick_hpp
#include <array>
#include <atomic>
#include "../../Inputs/Joystick.hpp"
#include "../../Inputs/Mouse.hpp"
namespace Amiga {
struct MouseJoystickInput {
virtual uint16_t get_position() = 0;
virtual uint8_t get_cia_button() const = 0;
};
class Mouse: public Inputs::Mouse, public MouseJoystickInput {
public:
uint16_t get_position() final;
uint8_t get_cia_button() const final;
private:
int get_number_of_buttons() final;
void set_button_pressed(int, bool) final;
void reset_all_buttons() final;
void move(int, int) final;
uint8_t declared_position_[2]{};
uint8_t cia_state_ = 0xff;
std::array<std::atomic<int>, 2> position_{};
};
class Joystick: public Inputs::ConcreteJoystick, public MouseJoystickInput {
public:
Joystick();
uint16_t get_position() final;
uint8_t get_cia_button() const final;
private:
void did_set_input(const Input &input, bool is_active) final;
bool inputs_[Joystick::Input::Type::Max]{};
uint16_t position_ = 0;
};
}
#endif /* MouseJoystick_hpp */

View File

@ -435,6 +435,8 @@
4B7BC7F51F58F27800D1B1B4 /* 6502AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C911F58F09E00E3F787 /* 6502AllRAM.cpp */; };
4B7C681627517A59001671EC /* Sprites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C681427517A59001671EC /* Sprites.cpp */; };
4B7C681727517A59001671EC /* Sprites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C681427517A59001671EC /* Sprites.cpp */; };
4B7C681A275196E8001671EC /* MouseJoystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C6818275196E8001671EC /* MouseJoystick.cpp */; };
4B7C681B275196E8001671EC /* MouseJoystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7C6818275196E8001671EC /* MouseJoystick.cpp */; };
4B7F188E2154825E00388727 /* MasterSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7F188C2154825D00388727 /* MasterSystem.cpp */; };
4B7F188F2154825E00388727 /* MasterSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7F188C2154825D00388727 /* MasterSystem.cpp */; };
4B7F1897215486A200388727 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7F1896215486A100388727 /* StaticAnalyser.cpp */; };
@ -1429,6 +1431,8 @@
4B7BA03F23D55E7900B98D9E /* LFSR.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LFSR.hpp; sourceTree = "<group>"; };
4B7C681427517A59001671EC /* Sprites.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sprites.cpp; sourceTree = "<group>"; };
4B7C681527517A59001671EC /* Sprites.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sprites.hpp; sourceTree = "<group>"; };
4B7C6818275196E8001671EC /* MouseJoystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MouseJoystick.cpp; sourceTree = "<group>"; };
4B7C6819275196E8001671EC /* MouseJoystick.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MouseJoystick.hpp; sourceTree = "<group>"; };
4B7F188C2154825D00388727 /* MasterSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MasterSystem.cpp; sourceTree = "<group>"; };
4B7F188D2154825D00388727 /* MasterSystem.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MasterSystem.hpp; sourceTree = "<group>"; };
4B7F1895215486A100388727 /* StaticAnalyser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaticAnalyser.hpp; sourceTree = "<group>"; };
@ -4310,6 +4314,7 @@
4BC6236C26F4235400F83DFE /* Copper.cpp */,
4B1A1B1C27320FBB00119335 /* Disk.cpp */,
4B9EC0E826B384080060A31F /* Keyboard.cpp */,
4B7C6818275196E8001671EC /* MouseJoystick.cpp */,
4B7C681427517A59001671EC /* Sprites.cpp */,
4BC080D726A25ADA00D03FD8 /* Amiga.hpp */,
4B2130E1273A7A0A008A77B4 /* Audio.hpp */,
@ -4321,6 +4326,7 @@
4B9EC0E926B384080060A31F /* Keyboard.hpp */,
4BD1552E270B14AC00410C6E /* MemoryMap.hpp */,
4BC6237026F94A5B00F83DFE /* Minterms.hpp */,
4B7C6819275196E8001671EC /* MouseJoystick.hpp */,
4B7C681527517A59001671EC /* Sprites.hpp */,
);
path = Amiga;
@ -5445,6 +5451,7 @@
4B055AC91FAE9AFB0060FFFF /* Keyboard.cpp in Sources */,
4B055A991FAE85CB0060FFFF /* DiskController.cpp in Sources */,
4B25B5F925BD083C00362C84 /* DiskIIDrive.cpp in Sources */,
4B7C681B275196E8001671EC /* MouseJoystick.cpp in Sources */,
4B055ACC1FAE9B030060FFFF /* Electron.cpp in Sources */,
4B2E86B825D7490E0024F1E9 /* ReactiveDevice.cpp in Sources */,
4B74CF822312FA9C00500CE8 /* HFV.cpp in Sources */,
@ -5652,6 +5659,7 @@
4B74CF85231370BC00500CE8 /* MacintoshVolume.cpp in Sources */,
4B0F1C232605996900B85C66 /* ZXSpectrumTAP.cpp in Sources */,
4B4518A51F75FD1C00926311 /* SSD.cpp in Sources */,
4B7C681A275196E8001671EC /* MouseJoystick.cpp in Sources */,
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */,
4B1B58FF246E19FD009C171E /* State.cpp in Sources */,
4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */,