diff --git a/Inputs/Joystick.hpp b/Inputs/Joystick.hpp index fc9f32213..57ee46824 100644 --- a/Inputs/Joystick.hpp +++ b/Inputs/Joystick.hpp @@ -36,7 +36,10 @@ class Joystick { // Fire buttons. Fire, // Other labelled keys. - Key + Key, + + // The maximum value this enum can contain. + Max = Key }; const Type type; diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 0e28b27d2..1b2216c86 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -1270,7 +1270,7 @@ void Chipset::Mouse::set_button_pressed(int button, bool is_set) { } } -uint8_t Chipset::Mouse::get_cia_button() { +uint8_t Chipset::Mouse::get_cia_button() const { return cia_state_; } @@ -1319,5 +1319,46 @@ uint16_t Chipset::Mouse::get_position() { ); } +// MARK: - Joystick. + +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() { } diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index aba4e3d25..558c66aa2 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -19,6 +19,7 @@ #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" @@ -336,7 +337,7 @@ class Chipset: private ClockingHint::Observer { class Mouse: public Inputs::Mouse { public: uint16_t get_position(); - uint8_t get_cia_button(); + uint8_t get_cia_button() const; private: int get_number_of_buttons() final; @@ -352,6 +353,22 @@ class Chipset: private ClockingHint::Observer { public: Inputs::Mouse &get_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; + }; + // MARK: - CIAs. private: class DiskController;