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:
parent
eca80f1425
commit
bea6cf2038
@ -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() {
|
||||
|
@ -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());
|
||||
|
122
Machines/Amiga/MouseJoystick.cpp
Normal file
122
Machines/Amiga/MouseJoystick.cpp
Normal 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;
|
||||
}
|
57
Machines/Amiga/MouseJoystick.hpp
Normal file
57
Machines/Amiga/MouseJoystick.hpp
Normal 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 */
|
@ -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 */,
|
||||
|
Loading…
x
Reference in New Issue
Block a user