1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-01 06:41:36 +00:00

Adds use of joystick input in the Apple II.

This commit is contained in:
Thomas Harte 2018-06-12 22:21:43 -04:00
parent f1b430338e
commit f26e4734b3
2 changed files with 40 additions and 12 deletions

View File

@ -138,16 +138,16 @@ class Joystick {
class ConcreteJoystick: public Joystick {
public:
ConcreteJoystick(const std::vector<Input> &inputs) : inputs_(inputs) {
// Size and populate axis_types_, which is used for digital <-> analogue conversion.
// Size and populate stick_types_, which is used for digital <-> analogue conversion.
for(const auto &input: inputs_) {
const bool is_digital_axis = input.is_digital_axis();
const bool is_analogue_axis = input.is_analogue_axis();
if(is_digital_axis || is_analogue_axis) {
const size_t required_size = static_cast<size_t>(input.info.control.index+1);
if(axis_types_.size() < required_size) {
axis_types_.resize(required_size);
if(stick_types_.size() < required_size) {
stick_types_.resize(required_size);
}
axis_types_[static_cast<size_t>(input.info.control.index)] = is_digital_axis ? AxisType::Digital : AxisType::Analogue;
stick_types_[static_cast<size_t>(input.info.control.index)] = is_digital_axis ? StickType::Digital : StickType::Analogue;
}
}
}
@ -158,7 +158,7 @@ class ConcreteJoystick: public Joystick {
void set_input(const Input &input, bool is_active) override final {
// If this is a digital setting to a digital property, just pass it along.
if(input.is_button() || axis_types_[input.info.control.index] == AxisType::Digital) {
if(input.is_button() || stick_types_[input.info.control.index] == StickType::Digital) {
did_set_input(input, is_active);
return;
}
@ -178,7 +178,7 @@ class ConcreteJoystick: public Joystick {
void set_input(const Input &input, float value) override final {
// If this is an analogue setting to an analogue property, just pass it along.
if(!input.is_button() && axis_types_[input.info.control.index] == AxisType::Analogue) {
if(!input.is_button() && stick_types_[input.info.control.index] == StickType::Analogue) {
did_set_input(input, value);
return;
}
@ -209,11 +209,11 @@ class ConcreteJoystick: public Joystick {
private:
std::vector<Input> inputs_;
enum class AxisType {
enum class StickType {
Digital,
Analogue
};
std::vector<AxisType> axis_types_;
std::vector<StickType> stick_types_;
};
}

View File

@ -176,7 +176,6 @@ class ConcreteMachine:
bool should_load_quickly_ = false;
// MARK - joysticks
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
class Joystick: public Inputs::ConcreteJoystick {
public:
Joystick() :
@ -191,7 +190,20 @@ class ConcreteMachine:
Input(Input::Fire, 1),
Input(Input::Fire, 2),
}) {}
void did_set_input(const Input &input, float value) override {
axes[(input.type == Input::Type::Horizontal) ? 1 : 0] = value;
}
void did_set_input(const Input &input, bool value) override {
buttons[input.info.control.index] = value;
}
bool buttons[3] = {false, false, false};
float axes[2] = {0.5f, 0.5f};
};
float analogue_charge_ = 0.0f;
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
public:
ConcreteMachine():
@ -401,17 +413,28 @@ class ConcreteMachine:
break;
case 0xc061: // Switch input 0.
if(!static_cast<Joystick *>(joysticks_[0].get())->buttons[0] || !static_cast<Joystick *>(joysticks_[1].get())->buttons[2])
*value &= 0x7f;
break;
case 0xc062: // Switch input 1.
if(!static_cast<Joystick *>(joysticks_[0].get())->buttons[1] || !static_cast<Joystick *>(joysticks_[1].get())->buttons[1])
*value &= 0x7f;
break;
case 0xc063: // Switch input 2.
*value &= 0x7f;
if(!static_cast<Joystick *>(joysticks_[0].get())->buttons[2] || !static_cast<Joystick *>(joysticks_[1].get())->buttons[0])
*value &= 0x7f;
break;
case 0xc064: // Analogue input 0.
case 0xc065: // Analogue input 1.
case 0xc066: // Analogue input 2.
case 0xc067: // Analogue input 3.
case 0xc067: { // Analogue input 3.
const size_t input = address - 0xc064;
*value &= 0x7f;
break;
if(static_cast<Joystick *>(joysticks_[input >> 1].get())->axes[input & 1] < analogue_charge_) {
*value |= 0x80;
}
} break;
}
} else {
// Write-only switches.
@ -429,6 +452,7 @@ class ConcreteMachine:
case 0xc057: update_video(); video_->set_high_resolution(); break;
case 0xc070: // Reset analogue inputs.
analogue_charge_ = 0.0f;
break;
case 0xc010:
@ -528,6 +552,9 @@ class ConcreteMachine:
}
}
// Update analogue charge level.
analogue_charge_ = std::min(analogue_charge_ + 1.0f / 2820.0f, 1.0f);
return Cycles(1);
}
@ -669,3 +696,4 @@ Machine *Machine::AppleII() {
}
Machine::~Machine() {}