blob: ceb669067f7eaa88625b69f23840c8831556b949 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#include "nes/app/input/input-manager.hh"
namespace nes::app
{
namespace
{
class input_device_dummy final : public input_device
{
public:
explicit input_device_dummy() = default;
static auto get_instance() -> input_device_dummy&
{
static auto res = input_device_dummy{};
return res;
}
auto read_buttons() -> sys::button_mask override { return sys::button_mask{}; }
};
} // namespace
input_manager::input_manager(input_device_keyboard& keyboard)
: keyboard_{ &keyboard }
{
fill_unassigned_inputs();
}
auto input_manager::add_controller(input_device_controller& controller) -> void
{
controllers_.append(controller);
if (controller.is_reliable())
{
auto const index = controller.get_index();
if (index != input_device_controller::index::unused)
{
// 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 (inputs_[i].controller)
{
inputs_[i].controller->set_index(input_device_controller::index::unused);
}
inputs_[i].controller = &controller;
inputs_[i].device = &controller;
}
// There may be another free controller now.
fill_unassigned_inputs();
}
}
auto input_manager::remove_controller(input_device_controller& controller) -> void
{
controllers_.remove(controller);
fill_unassigned_inputs();
}
auto input_manager::fill_unassigned_inputs() -> void
{
auto it = controllers_.begin();
input_device* fallback = keyboard_;
for (auto i = u32{ 0 }; i < input_count; ++i)
{
if (inputs_[i].controller != nullptr) { continue; }
// This input is not assigned -> use the next available controller if available.
while (it != controllers_.end())
{
if (it->is_reliable() && it->get_index() == input_device_controller::index::unused)
{
break;
}
++it;
}
if (it != controllers_.end())
{
// We've found an unused controller -> assign it.
inputs_[i].controller = &*it;
inputs_[i].controller->set_index(static_cast<input_device_controller::index>(i));
inputs_[i].device = &*it;
}
else
{
// We're all out of controllers -> fall back to the keyboard (if this is the first missing controller)
// or nothing.
inputs_[i].device = fallback;
fallback = &input_device_dummy::get_instance(); // Only use the keyboard as a fallback once.
}
}
}
} // namespace nes::app
|