1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-26 15:32:04 +00:00

Adds joystick events to the Atari ST.

This commit is contained in:
Thomas Harte 2019-11-09 18:39:22 -05:00
parent 2c25135d8a
commit 8e9428623e
2 changed files with 61 additions and 4 deletions

View File

@ -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);
}
@ -346,9 +361,12 @@ 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()
});
}

View File

@ -135,6 +135,45 @@ class IntelligentKeyboard:
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_ = 0x8f;
uint8_t returned_state_ = 0x8f;
};
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
};