From bae38497bbfa6736f46f7c4b24d3601dc928d168 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 22 Mar 2018 11:07:52 -0400 Subject: [PATCH 1/2] Implements multitarget joysticks. --- .../Implementation/MultiJoystickMachine.cpp | 56 ++++++++++++++++++- .../Implementation/MultiJoystickMachine.hpp | 1 - 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.cpp index 3959090bc..268771989 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.cpp @@ -10,11 +10,65 @@ using namespace Analyser::Dynamic; +namespace { + +class MultiJoystick: public Inputs::Joystick { + public: + MultiJoystick(std::vector &machines, std::size_t index) { + for(const auto &machine: machines) { + const auto &joysticks = machine->get_joysticks(); + if(joysticks.size() >= index) { + joysticks_.push_back(joysticks[index].get()); + } + } + } + + std::vector get_inputs() override { + std::vector inputs; + + for(const auto &joystick: joysticks_) { + std::vector joystick_inputs = joystick->get_inputs(); + for(const auto &input: joystick_inputs) { + if(std::find(inputs.begin(), inputs.end(), input) != inputs.end()) { + inputs.push_back(input); + } + } + } + + return inputs; + } + + void set_digital_input(const DigitalInput &digital_input, bool is_active) override { + for(const auto &joystick: joysticks_) { + joystick->set_digital_input(digital_input, is_active); + } + } + void reset_all_inputs() override { + for(const auto &joystick: joysticks_) { + joystick->reset_all_inputs(); + } + } + + private: + std::vector joysticks_; +}; + +} + MultiJoystickMachine::MultiJoystickMachine(const std::vector> &machines) { + std::size_t total_joysticks = 0; + std::vector joystick_machines; for(const auto &machine: machines) { JoystickMachine::Machine *joystick_machine = machine->joystick_machine(); - if(joystick_machine) machines_.push_back(joystick_machine); + if(joystick_machine) { + joystick_machines.push_back(joystick_machine); + total_joysticks = std::max(total_joysticks, joystick_machine->get_joysticks().size()); + } } + + for(std::size_t index = 0; index < total_joysticks; ++index) { + joysticks_.emplace_back(new MultiJoystick(joystick_machines, index)); + } } std::vector> &MultiJoystickMachine::get_joysticks() { diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp index 137c96e95..5e64dad75 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp @@ -31,7 +31,6 @@ class MultiJoystickMachine: public JoystickMachine::Machine { std::vector> &get_joysticks() override; private: - std::vector machines_; std::vector> joysticks_; }; From cd0fb7624ba9d4aa04fce5f729da2c59554ebb7f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 22 Mar 2018 11:08:07 -0400 Subject: [PATCH 2/2] Pulls delegate messages out of the critical sections. --- .../Implementation/MultiSpeaker.cpp | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp index 0e5d246c0..104ec1cca 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.cpp @@ -48,22 +48,28 @@ void MultiSpeaker::set_delegate(Outputs::Speaker::Speaker::Delegate *delegate) { } void MultiSpeaker::speaker_did_complete_samples(Speaker *speaker, const std::vector &buffer) { - std::lock_guard lock_guard(front_speaker_mutex_); - if(delegate_ && speaker == front_speaker_) { - delegate_->speaker_did_complete_samples(this, buffer); + if(!delegate_) return; + { + std::lock_guard lock_guard(front_speaker_mutex_); + if(speaker != front_speaker_) return; } + delegate_->speaker_did_complete_samples(this, buffer); } void MultiSpeaker::speaker_did_change_input_clock(Speaker *speaker) { - std::lock_guard lock_guard(front_speaker_mutex_); - if(delegate_ && speaker == front_speaker_) { - delegate_->speaker_did_change_input_clock(this); + if(!delegate_) return; + { + std::lock_guard lock_guard(front_speaker_mutex_); + if(speaker != front_speaker_) return; } + delegate_->speaker_did_change_input_clock(this); } void MultiSpeaker::set_new_front_machine(::Machine::DynamicMachine *machine) { - std::lock_guard lock_guard(front_speaker_mutex_); - front_speaker_ = machine->crt_machine()->get_speaker(); + { + std::lock_guard lock_guard(front_speaker_mutex_); + front_speaker_ = machine->crt_machine()->get_speaker(); + } if(delegate_) { delegate_->speaker_did_change_input_clock(this); }