26 uint8_t press_, uint8_t release_)
28 , press(press_), release(release_) {}
30 [[nodiscard]]
auto getId()
const {
return id; }
31 [[nodiscard]]
auto getPress()
const {
return press; }
32 [[nodiscard]]
auto getRelease()
const {
return release; }
34 template<
typename Archive>
void serialize(Archive& ar,
unsigned ) {
35 ar.template serializeBase<StateChange>(*
this);
36 ar.serialize(
"id",
id,
42 uint8_t id, press, release;
49 if (!buttons)
return {};
52 auto joy = joyId.
str();
53 for (
auto b :
xrange(*buttons)) {
54 ((b & 1) ? listB : listA).addListElement(
tmpStrCat(joy,
" button", b));
70 : commandController(commandController_)
71 , eventDistributor(eventDistributor_)
72 , stateChangeDistributor(stateChangeDistributor_)
73 , joystickManager(joystickManager_)
74 , configSetting(commandController,
tmpStrCat(
"msxjoystick", id_,
"_config"),
75 "msxjoystick mapping configuration", getDefaultConfig(
JoystickId(id_ - 1), joystickManager).getString())
76 , description(
strCat(
"MSX joystick ", id_,
". Mapping is fully configurable."))
80 this->checkJoystickConfig(newValue); });
82 checkJoystickConfig(configSetting.
getValue());
88 MSXJoystick::unplugHelper(EmuTime::dummy());
92void MSXJoystick::checkJoystickConfig(
const TclObject& newValue)
94 std::array<std::vector<BooleanInput>, 6> newBindings;
101 for (
unsigned i = 0; i < n; i += 2) {
102 static constexpr std::array<std::string_view, 6> keys = {
104 "UP",
"DOWN",
"LEFT",
"RIGHT",
"A",
"B"
108 if (it ==
keys.end()) {
109 throw CommandException(
110 "Invalid key: must be one of ",
join(keys,
", "));
112 auto idx = std::distance(
keys.begin(), it);
115 for (
auto j :
xrange(value.getListLength(interp))) {
119 throw CommandException(
"Invalid binding: ", val);
121 newBindings[idx].push_back(*bind);
130std::string_view MSXJoystick::getName()
const
133 case 1:
return "msxjoystick1";
134 case 2:
return "msxjoystick2";
139std::string_view MSXJoystick::getDescription()
const
144void MSXJoystick::plugHelper(Connector& , EmuTime::param )
150void MSXJoystick::unplugHelper(EmuTime::param )
158uint8_t MSXJoystick::read(EmuTime::param )
160 return pin8 ? 0x3F : status;
163void MSXJoystick::write(uint8_t value, EmuTime::param )
165 pin8 = (value & 0x04) != 0;
170void MSXJoystick::signalMSXEvent(
const Event& event,
171 EmuTime::param time)
noexcept
176 auto getJoyDeadZone = [&](JoystickId joyId) {
177 const auto*
setting = joystickManager.getJoyDeadZoneSetting(joyId);
181 for (
const auto& binding : bindings[i]) {
182 if (
auto onOff =
match(binding, event, getJoyDeadZone)) {
183 (*onOff ? press : release) |= 1 << i;
188 if (((status & ~press) | release) != status) {
189 stateChangeDistributor.distributeNew<MSXJoyState>(
190 time,
id, press, release);
195void MSXJoystick::signalStateChange(
const StateChange& event)
197 const auto* kjs =
dynamic_cast<const MSXJoyState*
>(&event);
199 if (kjs->getId() != id)
return;
201 status = (status & ~kjs->getPress()) | kjs->getRelease();
204void MSXJoystick::stopReplay(EmuTime::param time)
noexcept
206 uint8_t newStatus = JOY_UP | JOY_DOWN | JOY_LEFT | JOY_RIGHT |
207 JOY_BUTTONA | JOY_BUTTONB;
208 if (newStatus != status) {
209 uint8_t release = newStatus & ~status;
210 stateChangeDistributor.distributeNew<MSXJoyState>(
211 time,
id, uint8_t(0), release);
216template<
typename Archive>
219 ar.serialize(
"status", status);
220 if constexpr (Archive::IS_LOADER) {
virtual Interpreter & getInterpreter()=0
std::optional< unsigned > getNumButtons(JoystickId joyId) const
void registerEventListener(MSXEventListener &listener)
Registers a given object to receive certain events.
void unregisterEventListener(MSXEventListener &listener)
Unregisters a previously registered event listener.
MSXJoyState(EmuTime::param time_, uint8_t id_, uint8_t press_, uint8_t release_)
void serialize(Archive &ar, unsigned)
static TclObject getDefaultConfig(JoystickId joyId, const JoystickManager &joystickManager)
MSXJoystick(CommandController &commandController, MSXEventDistributor &eventDistributor, StateChangeDistributor &stateChangeDistributor, JoystickManager &joystickManager, uint8_t id)
void serialize(Archive &ar, unsigned version)
bool isPluggedIn() const
Returns true if this pluggable is currently plugged into a connector.
Connector * getConnector() const
Get the connector this Pluggable is plugged into.
void setChecker(std::function< void(TclObject &)> checkFunc_)
Set value-check-callback.
const TclObject & getValue() const final
Gets the current value of this setting as a TclObject.
void registerListener(StateChangeListener &listener)
(Un)registers the given object to receive state change events.
void unregisterListener(StateChangeListener &listener)
Base class for all external MSX state changing events.
unsigned getListLength(Interpreter &interp) const
TclObject getListIndex(Interpreter &interp, unsigned index) const
zstring_view getString() const
detail::Joiner< Collection, Separator > join(Collection &&col, Separator &&sep)
This file implemented 3 utility functions:
std::optional< bool > match(const BooleanInput &binding, const Event &event, function_ref< int(JoystickId)> getJoyDeadZone)
std::optional< BooleanInput > parseBooleanInput(std::string_view text)
std::variant< KeyUpEvent, KeyDownEvent, MouseMotionEvent, MouseButtonUpEvent, MouseButtonDownEvent, MouseWheelEvent, JoystickAxisMotionEvent, JoystickHatEvent, JoystickButtonUpEvent, JoystickButtonDownEvent, OsdControlReleaseEvent, OsdControlPressEvent, WindowEvent, TextEvent, FileDropEvent, QuitEvent, FinishFrameEvent, CliCommandEvent, GroupEvent, BootEvent, FrameDrawnEvent, BreakEvent, SwitchRendererEvent, TakeReverseSnapshotEvent, AfterTimedEvent, MachineLoadedEvent, MachineActivatedEvent, MachineDeactivatedEvent, MidiInReaderEvent, MidiInWindowsEvent, MidiInCoreMidiEvent, MidiInCoreMidiVirtualEvent, MidiInALSAEvent, Rs232TesterEvent, Rs232NetEvent, ImGuiDelayedActionEvent, ImGuiActiveEvent > Event
TclObject makeTclList(Args &&... args)
auto find(InputRange &&range, const T &value)
constexpr auto copy(InputRange &&range, OutputIter out)
constexpr auto keys(Map &&map)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
TemporaryString tmpStrCat(Ts &&... ts)
constexpr auto xrange(T e)