mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 18:30:21 +00:00
Merge pull request #671 from TomHarte/STJoystick
Makes joysticks a little more const correct
This commit is contained in:
commit
e4c77614c1
@ -81,6 +81,6 @@ MultiJoystickMachine::MultiJoystickMachine(const std::vector<std::unique_ptr<::M
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &MultiJoystickMachine::get_joysticks() {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &MultiJoystickMachine::get_joysticks() {
|
||||
return joysticks_;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class MultiJoystickMachine: public JoystickMachine::Machine {
|
||||
MultiJoystickMachine(const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &machines);
|
||||
|
||||
// Below is the standard JoystickMachine::Machine interface; see there for documentation.
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override;
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
|
||||
|
@ -25,7 +25,6 @@ uint8_t ACIA::read(int address) {
|
||||
received_data_ |= NoValueMask;
|
||||
return uint8_t(received_data_);
|
||||
} else {
|
||||
clear_interrupt_cause(StatusNeedsRead);
|
||||
return
|
||||
((received_data_ & NoValueMask) ? 0x00 : 0x01) |
|
||||
((next_transmission_ == NoValueMask) ? 0x02 : 0x00) |
|
||||
@ -176,7 +175,7 @@ void ACIA::set_interrupt_delegate(InterruptDelegate *delegate) {
|
||||
|
||||
void ACIA::add_interrupt_cause(int cause) {
|
||||
const bool is_changing_state = !interrupt_causes_;
|
||||
interrupt_causes_ |= cause | StatusNeedsRead;
|
||||
interrupt_causes_ |= cause;
|
||||
if(interrupt_delegate_ && is_changing_state)
|
||||
interrupt_delegate_->acia6850_did_change_interrupt_status(this);
|
||||
}
|
||||
|
@ -604,7 +604,7 @@ class KeyboardState: public GI::AY38910::PortHandler {
|
||||
memset(rows_, 0xff, sizeof(rows_));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
@ -1093,7 +1093,7 @@ template <bool has_fdc> class ConcreteMachine:
|
||||
}
|
||||
|
||||
// MARK: - Joysticks
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
return key_state_.get_joysticks();
|
||||
}
|
||||
|
||||
|
@ -893,7 +893,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
}
|
||||
|
||||
// MARK: JoystickMachine
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
return joysticks_;
|
||||
}
|
||||
};
|
||||
|
@ -124,7 +124,7 @@ class ConcreteMachine:
|
||||
joysticks_.emplace_back(new Joystick(bus_.get(), 4, 1));
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "AtariST.hpp"
|
||||
|
||||
#include "../../CRTMachine.hpp"
|
||||
#include "../../JoystickMachine.hpp"
|
||||
#include "../../KeyboardMachine.hpp"
|
||||
#include "../../MouseMachine.hpp"
|
||||
#include "../../MediaTarget.hpp"
|
||||
@ -49,6 +50,7 @@ class ConcreteMachine:
|
||||
public Motorola::MFP68901::MFP68901::InterruptDelegate,
|
||||
public DMAController::Delegate,
|
||||
public MouseMachine::Machine,
|
||||
public JoystickMachine::Machine,
|
||||
public KeyboardMachine::MappedMachine,
|
||||
public Activity::Source,
|
||||
public MediaTarget::Machine,
|
||||
@ -527,6 +529,11 @@ class ConcreteMachine:
|
||||
return &keyboard_mapper_;
|
||||
}
|
||||
|
||||
// MARK: - JoystickMachine
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() final {
|
||||
return ikbd_.get_joysticks();
|
||||
}
|
||||
|
||||
// MARK: - AYPortHandler
|
||||
void set_port_output(bool port_b, uint8_t value) final {
|
||||
if(port_b) {
|
||||
|
@ -14,6 +14,10 @@ IntelligentKeyboard::IntelligentKeyboard(Serial::Line &input, Serial::Line &outp
|
||||
input.set_read_delegate(this, Storage::Time(2, 15625));
|
||||
output_line_.set_writer_clock_rate(15625);
|
||||
|
||||
// Add two joysticks into the mix.
|
||||
joysticks_.emplace_back(new Joystick);
|
||||
joysticks_.emplace_back(new Joystick);
|
||||
|
||||
mouse_button_state_ = 0;
|
||||
mouse_movement_[0] = 0;
|
||||
mouse_movement_[1] = 0;
|
||||
@ -40,7 +44,7 @@ ClockingHint::Preference IntelligentKeyboard::preferred_clocking() {
|
||||
}
|
||||
|
||||
void IntelligentKeyboard::run_for(HalfCycles duration) {
|
||||
// Take this opportunity to check for mouse and keyboard events,
|
||||
// Take this opportunity to check for joystick, mouse and keyboard events,
|
||||
// which will have been received asynchronously.
|
||||
if(mouse_mode_ == MouseMode::Relative) {
|
||||
const int captured_movement[2] = { mouse_movement_[0].load(), mouse_movement_[1].load() };
|
||||
@ -55,7 +59,7 @@ void IntelligentKeyboard::run_for(HalfCycles duration) {
|
||||
post_relative_mouse_event(captured_movement[0], captured_movement[1]);
|
||||
}
|
||||
} else {
|
||||
|
||||
// TODO: absolute-mode mouse updates.
|
||||
}
|
||||
|
||||
// Forward key changes; implicit assumption here: mutexs are cheap while there's
|
||||
@ -68,6 +72,17 @@ void IntelligentKeyboard::run_for(HalfCycles duration) {
|
||||
key_queue_.clear();
|
||||
}
|
||||
|
||||
// Check for joystick changes.
|
||||
for(size_t c = 0; c < 2; ++c) {
|
||||
const auto joystick = static_cast<Joystick *>(joysticks_[c].get());
|
||||
if(joystick->has_event()) {
|
||||
output_bytes({
|
||||
uint8_t(0xfe | c),
|
||||
joystick->get_state()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
output_line_.advance_writer(duration);
|
||||
}
|
||||
|
||||
@ -152,10 +167,30 @@ void IntelligentKeyboard::dispatch_command(uint8_t command) {
|
||||
case 0x12: disable_mouse(); break;
|
||||
case 0x13: pause(); break;
|
||||
|
||||
case 0x14: set_joystick_event_mode(); break;
|
||||
case 0x15: set_joystick_interrogation_mode(); break;
|
||||
case 0x16: interrogate_joysticks(); break;
|
||||
case 0x1a: disable_joysticks(); break;
|
||||
/* Joystick commands. */
|
||||
case 0x14: set_joystick_event_mode(); break;
|
||||
case 0x15: set_joystick_interrogation_mode(); break;
|
||||
case 0x16: interrogate_joysticks(); break;
|
||||
case 0x17:
|
||||
if(command_sequence_.size() != 2) return;
|
||||
set_joystick_monitoring_mode(command_sequence_[1]);
|
||||
break;
|
||||
case 0x18: set_joystick_fire_button_monitoring_mode(); break;
|
||||
case 0x19: {
|
||||
if(command_sequence_.size() != 7) return;
|
||||
|
||||
VelocityThreshold horizontal, vertical;
|
||||
horizontal.threshold = command_sequence_[1];
|
||||
horizontal.prior_rate = command_sequence_[3];
|
||||
horizontal.post_rate = command_sequence_[5];
|
||||
|
||||
vertical.threshold = command_sequence_[2];
|
||||
vertical.prior_rate = command_sequence_[4];
|
||||
vertical.post_rate = command_sequence_[6];
|
||||
|
||||
set_joystick_keycode_mode(horizontal, vertical);
|
||||
} break;
|
||||
case 0x1a: disable_joysticks(); break;
|
||||
}
|
||||
|
||||
// There was no premature exit, so a complete command sequence must have been satisfied.
|
||||
@ -346,9 +381,21 @@ void IntelligentKeyboard::set_joystick_interrogation_mode() {
|
||||
}
|
||||
|
||||
void IntelligentKeyboard::interrogate_joysticks() {
|
||||
const auto joystick1 = static_cast<Joystick *>(joysticks_[0].get());
|
||||
const auto joystick2 = static_cast<Joystick *>(joysticks_[1].get());
|
||||
|
||||
output_bytes({
|
||||
0xfd,
|
||||
0x00,
|
||||
0x00
|
||||
joystick1->get_state(),
|
||||
joystick2->get_state()
|
||||
});
|
||||
}
|
||||
|
||||
void IntelligentKeyboard::set_joystick_monitoring_mode(uint8_t rate) {
|
||||
}
|
||||
|
||||
void IntelligentKeyboard::set_joystick_fire_button_monitoring_mode() {
|
||||
}
|
||||
|
||||
void IntelligentKeyboard::set_joystick_keycode_mode(VelocityThreshold horizontal, VelocityThreshold vertical) {
|
||||
}
|
||||
|
@ -13,10 +13,13 @@
|
||||
#include "../../../Components/Serial/Line.hpp"
|
||||
#include "../../KeyboardMachine.hpp"
|
||||
|
||||
#include "../../../Inputs/Joystick.hpp"
|
||||
#include "../../../Inputs/Mouse.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Atari {
|
||||
namespace ST {
|
||||
@ -61,6 +64,10 @@ class IntelligentKeyboard:
|
||||
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) final;
|
||||
};
|
||||
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
private:
|
||||
// MARK: - Key queue.
|
||||
std::mutex key_queue_mutex_;
|
||||
@ -123,11 +130,59 @@ class IntelligentKeyboard:
|
||||
void disable_joysticks();
|
||||
void set_joystick_event_mode();
|
||||
void set_joystick_interrogation_mode();
|
||||
void set_joystick_monitoring_mode(uint8_t rate);
|
||||
void set_joystick_fire_button_monitoring_mode();
|
||||
struct VelocityThreshold {
|
||||
uint8_t threshold;
|
||||
uint8_t prior_rate;
|
||||
uint8_t post_rate;
|
||||
};
|
||||
void set_joystick_keycode_mode(VelocityThreshold horizontal, VelocityThreshold vertical);
|
||||
void interrogate_joysticks();
|
||||
|
||||
enum class JoystickMode {
|
||||
Disabled, Event, Interrogation
|
||||
} joystick_mode_ = JoystickMode::Event;
|
||||
|
||||
class Joystick: public Inputs::ConcreteJoystick {
|
||||
public:
|
||||
Joystick() :
|
||||
ConcreteJoystick({
|
||||
Input(Input::Up),
|
||||
Input(Input::Down),
|
||||
Input(Input::Left),
|
||||
Input(Input::Right),
|
||||
Input(Input::Fire, 0),
|
||||
}) {}
|
||||
|
||||
void did_set_input(const Input &input, bool is_active) override {
|
||||
uint8_t mask = 0;
|
||||
switch(input.type) {
|
||||
default: return;
|
||||
case Input::Up: mask = 0x01; break;
|
||||
case Input::Down: mask = 0x02; break;
|
||||
case Input::Left: mask = 0x04; break;
|
||||
case Input::Right: mask = 0x08; break;
|
||||
case Input::Fire: mask = 0x80; break;
|
||||
}
|
||||
|
||||
if(is_active) state_ |= mask; else state_ &= ~mask;
|
||||
}
|
||||
|
||||
uint8_t get_state() {
|
||||
returned_state_ = state_;
|
||||
return state_;
|
||||
}
|
||||
|
||||
bool has_event() {
|
||||
return returned_state_ != state_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t state_ = 0x00;
|
||||
uint8_t returned_state_ = 0x00;
|
||||
};
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ class ConcreteMachine:
|
||||
audio_queue_.flush();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,7 @@ class ConcreteMachine:
|
||||
keyboard_via_port_handler_->clear_all_keys();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace JoystickMachine {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() = 0;
|
||||
virtual const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class AYPortHandler: public GI::AY38910::PortHandler {
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
@ -686,7 +686,7 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
// MARK: - Joysticks
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
return ay_port_handler_.get_joysticks();
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ class ConcreteMachine:
|
||||
audio_queue_.perform();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
|
||||
return joysticks_;
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
// Until then, apply a default mapping.
|
||||
|
||||
size_t c = 0;
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &machine_joysticks = _joystickMachine->get_joysticks();
|
||||
auto &machine_joysticks = _joystickMachine->get_joysticks();
|
||||
for(CSJoystick *joystick in _joystickManager.joysticks) {
|
||||
size_t target = c % machine_joysticks.size();
|
||||
++c;
|
||||
@ -373,7 +373,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
@synchronized(self) {
|
||||
_joystickManager = joystickManager;
|
||||
if(_joystickMachine) {
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &machine_joysticks = _joystickMachine->get_joysticks();
|
||||
auto &machine_joysticks = _joystickMachine->get_joysticks();
|
||||
for(const auto &joystick: machine_joysticks) {
|
||||
joystick->reset_all_inputs();
|
||||
}
|
||||
@ -467,7 +467,7 @@ struct ActivityObserver: public Activity::Observer {
|
||||
auto joystick_machine = _machine->joystick_machine();
|
||||
if(self.inputMode == CSMachineKeyboardInputModeJoystick && joystick_machine) {
|
||||
@synchronized(self) {
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &joysticks = joystick_machine->get_joysticks();
|
||||
auto &joysticks = joystick_machine->get_joysticks();
|
||||
if(!joysticks.empty()) {
|
||||
// Convert to a C++ bool so that the following calls are resolved correctly even if overloaded.
|
||||
bool is_pressed = !!isPressed;
|
||||
|
@ -741,7 +741,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
JoystickMachine::Machine *const joystick_machine = machine->joystick_machine();
|
||||
if(joystick_machine) {
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &joysticks = joystick_machine->get_joysticks();
|
||||
auto &joysticks = joystick_machine->get_joysticks();
|
||||
if(!joysticks.empty()) {
|
||||
switch(event.key.keysym.scancode) {
|
||||
case SDL_SCANCODE_LEFT: joysticks[0]->set_input(Inputs::Joystick::Input::Left, is_pressed); break;
|
||||
@ -791,7 +791,7 @@ int main(int argc, char *argv[]) {
|
||||
// Push new joystick state, if any.
|
||||
JoystickMachine::Machine *const joystick_machine = machine->joystick_machine();
|
||||
if(joystick_machine) {
|
||||
std::vector<std::unique_ptr<Inputs::Joystick>> &machine_joysticks = joystick_machine->get_joysticks();
|
||||
auto &machine_joysticks = joystick_machine->get_joysticks();
|
||||
for(size_t c = 0; c < joysticks.size(); ++c) {
|
||||
size_t target = c % machine_joysticks.size();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user