summaryrefslogtreecommitdiff
path: root/lib/nes/app/input
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nes/app/input')
-rw-r--r--lib/nes/app/input/input-device-controller.hh4
-rw-r--r--lib/nes/app/input/input-device-keyboard.hh2
-rw-r--r--lib/nes/app/input/input-device.hh5
-rw-r--r--lib/nes/app/input/input-manager.cc43
-rw-r--r--lib/nes/app/input/input-manager.hh5
5 files changed, 55 insertions, 4 deletions
diff --git a/lib/nes/app/input/input-device-controller.hh b/lib/nes/app/input/input-device-controller.hh
index 69dd2a8..93147cd 100644
--- a/lib/nes/app/input/input-device-controller.hh
+++ b/lib/nes/app/input/input-device-controller.hh
@@ -2,7 +2,6 @@
#include "nes/app/input/input-device.hh"
#include "nes/common/containers/list.hh"
-#include <string_view>
namespace nes::app
{
@@ -23,9 +22,6 @@ namespace nes::app
/// controller already selected.
virtual auto is_reliable() const -> bool = 0;
- /// Human-readable name for the controller.
- virtual auto get_name() const -> std::string_view = 0;
-
/// Get the (persistent) player index for the controller, if already set before.
virtual auto get_index() const -> index = 0;
diff --git a/lib/nes/app/input/input-device-keyboard.hh b/lib/nes/app/input/input-device-keyboard.hh
index 23ee65c..ef89c59 100644
--- a/lib/nes/app/input/input-device-keyboard.hh
+++ b/lib/nes/app/input/input-device-keyboard.hh
@@ -43,6 +43,8 @@ namespace nes::app
return res;
}
+ auto get_name() const -> std::string_view final { return "Keyboard"; }
+
protected:
explicit input_device_keyboard() = default;
};
diff --git a/lib/nes/app/input/input-device.hh b/lib/nes/app/input/input-device.hh
index cc03057..008825d 100644
--- a/lib/nes/app/input/input-device.hh
+++ b/lib/nes/app/input/input-device.hh
@@ -1,6 +1,7 @@
#pragma once
#include "nes/sys/types/button-mask.hh"
+#include <string_view>
namespace nes::app
{
@@ -15,8 +16,12 @@ namespace nes::app
auto operator=(input_device const&) -> input_device& = delete;
auto operator=(input_device&&) -> input_device& = delete;
+ /// Read the controller button state.
virtual auto read_buttons() -> sys::button_mask = 0;
+ /// Human-readable name for the device.
+ virtual auto get_name() const -> std::string_view = 0;
+
protected:
explicit input_device() = default;
};
diff --git a/lib/nes/app/input/input-manager.cc b/lib/nes/app/input/input-manager.cc
index ceb6690..e88ac84 100644
--- a/lib/nes/app/input/input-manager.cc
+++ b/lib/nes/app/input/input-manager.cc
@@ -15,6 +15,7 @@ namespace nes::app
return res;
}
+ auto get_name() const -> std::string_view override { return "(None)"; }
auto read_buttons() -> sys::button_mask override { return sys::button_mask{}; }
};
} // namespace
@@ -36,6 +37,10 @@ namespace nes::app
// This controller was previously used and assigned an index -> replace the current device with this
// (known) controller.
auto const i = static_cast<u32>(index);
+ if (keyboard_index_ == index)
+ {
+ keyboard_index_ = input_device_controller::index::unused;
+ }
if (inputs_[i].controller)
{
inputs_[i].controller->set_index(input_device_controller::index::unused);
@@ -56,6 +61,43 @@ namespace nes::app
fill_unassigned_inputs();
}
+ auto input_manager::toggle_input(u32 const i) -> void
+ {
+ // If currently none/keyboard, use the first available controller.
+ auto curr_was_prev = inputs_[i].controller == nullptr;
+ if (curr_was_prev && keyboard_index_ == input_device_controller::index::unused)
+ {
+ // If currently none and keyboard is available, switch to keyboard.
+ keyboard_index_ = static_cast<input_device_controller::index>(i);
+ inputs_[i].controller = nullptr;
+ inputs_[i].device = keyboard_;
+ return;
+ }
+
+ // Reset old controller index
+ if (inputs_[i].controller) { inputs_[i].controller->set_index(input_device_controller::index::unused); }
+ if (keyboard_index_ == static_cast<input_device_controller::index>(i)) { keyboard_index_ = input_device_controller::index::unused; }
+
+ for (auto& controller : controllers_)
+ {
+ if (&controller == inputs_[i].controller)
+ {
+ curr_was_prev = true;
+ }
+ else if (curr_was_prev && controller.get_index() == input_device_controller::index::unused)
+ {
+ inputs_[i].controller = &controller;
+ inputs_[i].controller->set_index(static_cast<input_device_controller::index>(i));
+ inputs_[i].device = &controller;
+ return;
+ }
+ }
+
+ // No successor found, switch to none.
+ inputs_[i].controller = nullptr;
+ inputs_[i].device = &input_device_dummy::get_instance();
+ }
+
auto input_manager::fill_unassigned_inputs() -> void
{
auto it = controllers_.begin();
@@ -87,6 +129,7 @@ namespace nes::app
// We're all out of controllers -> fall back to the keyboard (if this is the first missing controller)
// or nothing.
inputs_[i].device = fallback;
+ if (fallback == keyboard_) { keyboard_index_ = static_cast<input_device_controller::index>(i); }
fallback = &input_device_dummy::get_instance(); // Only use the keyboard as a fallback once.
}
}
diff --git a/lib/nes/app/input/input-manager.hh b/lib/nes/app/input/input-manager.hh
index b0b60e8..7a63326 100644
--- a/lib/nes/app/input/input-manager.hh
+++ b/lib/nes/app/input/input-manager.hh
@@ -16,6 +16,7 @@ namespace nes::app
static constexpr auto input_count = u32{ 2 };
input_device_keyboard* keyboard_;
+ input_device_controller::index keyboard_index_{ input_device_controller::index::unused };
list<input_device_controller> controllers_;
struct
{
@@ -34,6 +35,9 @@ namespace nes::app
auto get_input_1() const -> input_device& { return *inputs_[0].device; }
auto get_input_2() const -> input_device& { return *inputs_[1].device; }
+ auto toggle_input_1() -> void { toggle_input(0); }
+ auto toggle_input_2() -> void { toggle_input(1); }
+
auto get_keyboard() const -> input_device_keyboard& { return *keyboard_; }
auto get_controllers() const -> list<input_device_controller> const& { return controllers_; }
@@ -41,6 +45,7 @@ namespace nes::app
auto remove_controller(input_device_controller&) -> void;
private:
+ auto toggle_input(u32) -> void;
auto fill_unassigned_inputs() -> void;
};
} // namespace nes::app \ No newline at end of file