diff --git a/Inputs/Joystick.hpp b/Inputs/Joystick.hpp index 4b2223075..036d936a6 100644 --- a/Inputs/Joystick.hpp +++ b/Inputs/Joystick.hpp @@ -27,7 +27,13 @@ class Joystick { // Host interface. virtual void set_digital_input(DigitalInput digital_input, bool is_active) = 0; - virtual void reset_all_inputs() = 0; + virtual void reset_all_inputs() { + set_digital_input(DigitalInput::Up, false); + set_digital_input(DigitalInput::Down, false); + set_digital_input(DigitalInput::Left, false); + set_digital_input(DigitalInput::Right, false); + set_digital_input(DigitalInput::Fire, false); + } }; } diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index 85f867854..c68e4661a 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -30,6 +30,33 @@ namespace { namespace Atari2600 { +class Joystick: public Inputs::Joystick { + public: + Joystick(Bus *bus, size_t shift, size_t fire_tia_input) : + bus_(bus), shift_(shift), fire_tia_input_(fire_tia_input) {} + + void set_digital_input(DigitalInput digital_input, bool is_active) { + switch(digital_input) { + case DigitalInput::Up: bus_->mos6532_.update_port_input(0, 0x10 >> shift_, is_active); break; + case DigitalInput::Down: bus_->mos6532_.update_port_input(0, 0x20 >> shift_, is_active); break; + case DigitalInput::Left: bus_->mos6532_.update_port_input(0, 0x40 >> shift_, is_active); break; + case DigitalInput::Right: bus_->mos6532_.update_port_input(0, 0x80 >> shift_, is_active); break; + + // TODO: latching + case DigitalInput::Fire: + if(is_active) + bus_->tia_input_value_[fire_tia_input_] &= ~0x80; + else + bus_->tia_input_value_[fire_tia_input_] |= 0x80; + break; + } + } + + private: + size_t shift_, fire_tia_input_; + Bus *bus_; +}; + class ConcreteMachine: public Machine, public Outputs::CRT::Delegate { @@ -44,7 +71,7 @@ class ConcreteMachine: close_output(); } - void configure_as_target(const StaticAnalyser::Target &target) { + void configure_as_target(const StaticAnalyser::Target &target) override { const std::vector &rom = target.media.cartridges.front()->get_segments().front().data; switch(target.atari.paging_model) { case StaticAnalyser::Atari2600PagingModel::ActivisionStack: bus_.reset(new Cartridge::Cartridge(rom)); break; @@ -79,34 +106,20 @@ class ConcreteMachine: } break; } + + joysticks_.push_back(new Joystick(bus_.get(), 0, 0)); + joysticks_.push_back(new Joystick(bus_.get(), 4, 1)); } - bool insert_media(const StaticAnalyser::Media &media) { + bool insert_media(const StaticAnalyser::Media &media) override { return false; } - void set_digital_input(Atari2600DigitalInput input, bool state) { - switch (input) { - case Atari2600DigitalInputJoy1Up: bus_->mos6532_.update_port_input(0, 0x10, state); break; - case Atari2600DigitalInputJoy1Down: bus_->mos6532_.update_port_input(0, 0x20, state); break; - case Atari2600DigitalInputJoy1Left: bus_->mos6532_.update_port_input(0, 0x40, state); break; - case Atari2600DigitalInputJoy1Right: bus_->mos6532_.update_port_input(0, 0x80, state); break; - - case Atari2600DigitalInputJoy2Up: bus_->mos6532_.update_port_input(0, 0x01, state); break; - case Atari2600DigitalInputJoy2Down: bus_->mos6532_.update_port_input(0, 0x02, state); break; - case Atari2600DigitalInputJoy2Left: bus_->mos6532_.update_port_input(0, 0x04, state); break; - case Atari2600DigitalInputJoy2Right: bus_->mos6532_.update_port_input(0, 0x08, state); break; - - // TODO: latching - case Atari2600DigitalInputJoy1Fire: if(state) bus_->tia_input_value_[0] &= ~0x80; else bus_->tia_input_value_[0] |= 0x80; break; - case Atari2600DigitalInputJoy2Fire: if(state) bus_->tia_input_value_[1] &= ~0x80; else bus_->tia_input_value_[1] |= 0x80; break; - - default: break; - } + std::vector &get_joysticks() override { + return joysticks_; } - - void set_switch_is_enabled(Atari2600Switch input, bool state) { + void set_switch_is_enabled(Atari2600Switch input, bool state) override { switch(input) { case Atari2600SwitchReset: bus_->mos6532_.update_port_input(1, 0x01, state); break; case Atari2600SwitchSelect: bus_->mos6532_.update_port_input(1, 0x02, state); break; @@ -116,36 +129,36 @@ class ConcreteMachine: } } - void set_reset_switch(bool state) { + void set_reset_switch(bool state) override { bus_->set_reset_line(state); } // to satisfy CRTMachine::Machine - void setup_output(float aspect_ratio) { + void setup_output(float aspect_ratio) override { bus_->tia_.reset(new TIA); bus_->speaker_.reset(new Speaker); bus_->speaker_->set_input_rate((float)(get_clock_rate() / (double)CPUTicksPerAudioTick)); bus_->tia_->get_crt()->set_delegate(this); } - void close_output() { + void close_output() override { bus_.reset(); } - std::shared_ptr get_crt() { + std::shared_ptr get_crt() override { return bus_->tia_->get_crt(); } - std::shared_ptr get_speaker() { + std::shared_ptr get_speaker() override { return bus_->speaker_; } - void run_for(const Cycles cycles) { + void run_for(const Cycles cycles) override { bus_->run_for(cycles); } // to satisfy Outputs::CRT::Delegate - void crt_did_end_batch_of_frames(Outputs::CRT::CRT *crt, unsigned int number_of_frames, unsigned int number_of_unexpected_vertical_syncs) { + void crt_did_end_batch_of_frames(Outputs::CRT::CRT *crt, unsigned int number_of_frames, unsigned int number_of_unexpected_vertical_syncs) override { const size_t number_of_frame_records = sizeof(frame_records_) / sizeof(frame_records_[0]); frame_records_[frame_record_pointer_ % number_of_frame_records].number_of_frames = number_of_frames; frame_records_[frame_record_pointer_ % number_of_frame_records].number_of_unexpected_vertical_syncs = number_of_unexpected_vertical_syncs; @@ -182,7 +195,6 @@ class ConcreteMachine: } } - private: // the bus std::unique_ptr bus_; @@ -196,6 +208,7 @@ class ConcreteMachine: } frame_records_[4]; unsigned int frame_record_pointer_; bool is_ntsc_; + std::vector joysticks_; }; } diff --git a/Machines/Atari2600/Atari2600.hpp b/Machines/Atari2600/Atari2600.hpp index 860773d23..c4c2d5282 100644 --- a/Machines/Atari2600/Atari2600.hpp +++ b/Machines/Atari2600/Atari2600.hpp @@ -11,6 +11,7 @@ #include "../ConfigurationTarget.hpp" #include "../CRTMachine.hpp" +#include "../JoystickMachine.hpp" #include "Atari2600Inputs.h" @@ -21,16 +22,14 @@ namespace Atari2600 { */ class Machine: public CRTMachine::Machine, - public ConfigurationTarget::Machine { + public ConfigurationTarget::Machine, + public JoystickMachine::Machine { public: virtual ~Machine(); /// Creates and returns an Atari 2600 on the heap. static Machine *Atari2600(); - /// Sets @c input to @c state. - virtual void set_digital_input(Atari2600DigitalInput input, bool state) = 0; - /// Sets the switch @c input to @c state. virtual void set_switch_is_enabled(Atari2600Switch input, bool state) = 0; diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm index 327233c08..cad5044b2 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm @@ -25,23 +25,23 @@ } - (void)setDirection:(CSJoystickDirection)direction onPad:(NSUInteger)pad isPressed:(BOOL)isPressed { - Atari2600DigitalInput input; - switch(direction) - { - case CSJoystickDirectionUp: input = pad ? Atari2600DigitalInputJoy2Up : Atari2600DigitalInputJoy1Up; break; - case CSJoystickDirectionDown: input = pad ? Atari2600DigitalInputJoy2Down : Atari2600DigitalInputJoy1Down; break; - case CSJoystickDirectionLeft: input = pad ? Atari2600DigitalInputJoy2Left : Atari2600DigitalInputJoy1Left; break; - case CSJoystickDirectionRight: input = pad ? Atari2600DigitalInputJoy2Right : Atari2600DigitalInputJoy1Right; break; - } - @synchronized(self) { - _atari2600->set_digital_input(input, isPressed ? true : false); - } +// Atari2600DigitalInput input; +// switch(direction) +// { +// case CSJoystickDirectionUp: input = pad ? Atari2600DigitalInputJoy2Up : Atari2600DigitalInputJoy1Up; break; +// case CSJoystickDirectionDown: input = pad ? Atari2600DigitalInputJoy2Down : Atari2600DigitalInputJoy1Down; break; +// case CSJoystickDirectionLeft: input = pad ? Atari2600DigitalInputJoy2Left : Atari2600DigitalInputJoy1Left; break; +// case CSJoystickDirectionRight: input = pad ? Atari2600DigitalInputJoy2Right : Atari2600DigitalInputJoy1Right; break; +// } +// @synchronized(self) { +// _atari2600->set_digital_input(input, isPressed ? true : false); +// } } - (void)setButtonAtIndex:(NSUInteger)button onPad:(NSUInteger)pad isPressed:(BOOL)isPressed { - @synchronized(self) { - _atari2600->set_digital_input(pad ? Atari2600DigitalInputJoy2Fire : Atari2600DigitalInputJoy1Fire, isPressed ? true : false); - } +// @synchronized(self) { +// _atari2600->set_digital_input(pad ? Atari2600DigitalInputJoy2Fire : Atari2600DigitalInputJoy1Fire, isPressed ? true : false); +// } } - (void)setResetLineEnabled:(BOOL)enabled {