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:
parent
2c25135d8a
commit
8e9428623e
@ -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()
|
||||
});
|
||||
}
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user