16 default:
return "unknown-keyjoystick";
25 uint8_t press_, uint8_t release_)
27 ,
id(id_), press(press_), release(release_) {}
28 [[nodiscard]]
auto getId()
const {
return id; }
29 [[nodiscard]] uint8_t
getPress()
const {
return press; }
30 [[nodiscard]] uint8_t
getRelease()
const {
return release; }
31 template<
typename Archive>
void serialize(Archive& ar,
unsigned )
33 ar.template serializeBase<StateChange>(*
this);
35 std::string name = Archive::IS_LOADER ?
"" : std::string(nameForId(
id));
36 ar.serialize(
"name", name,
39 if constexpr (Archive::IS_LOADER) {
48 uint8_t press, release;
56 : eventDistributor(eventDistributor_)
57 , stateChangeDistributor(stateChangeDistributor_)
58 , up (commandController,
tmpStrCat(nameForId(id_),
".up"),
59 "key for direction up", Keys::
K_UP)
60 , down (commandController,
tmpStrCat(nameForId(id_),
".down"),
61 "key for direction down", Keys::
K_DOWN)
62 , left (commandController,
tmpStrCat(nameForId(id_),
".left"),
63 "key for direction left", Keys::
K_LEFT)
64 , right(commandController,
tmpStrCat(nameForId(id_),
".right"),
65 "key for direction right", Keys::
K_RIGHT)
66 , trigA(commandController,
tmpStrCat(nameForId(id_),
".triga"),
67 "key for trigger A", Keys::
K_SPACE)
68 , trigB(commandController,
tmpStrCat(nameForId(id_),
".trigb"),
69 "key for trigger B", Keys::
K_M)
71 , status(JOY_UP | JOY_DOWN | JOY_LEFT | JOY_RIGHT |
72 JOY_BUTTONA | JOY_BUTTONB)
79 KeyJoystick::unplugHelper(EmuTime::dummy());
85std::string_view KeyJoystick::getName()
const
90std::string_view KeyJoystick::getDescription()
const
92 return "Key-Joystick, use your keyboard to emulate an MSX joystick. "
93 "See manual for information on how to configure this.";
96void KeyJoystick::plugHelper(
Connector& , EmuTime::param )
102void KeyJoystick::unplugHelper(EmuTime::param )
110uint8_t KeyJoystick::read(EmuTime::param )
112 return pin8 ? 0x3F : status;
115void KeyJoystick::write(uint8_t value, EmuTime::param )
117 pin8 = (value & 0x04) != 0;
122void KeyJoystick::signalMSXEvent(
const Event& event,
123 EmuTime::param time)
noexcept
127 auto getKey = [&](
const KeyEvent&
e) {
130 if (key == up .getKey())
return JOY_UP;
131 else if (key == down .getKey())
return JOY_DOWN;
132 else if (key == left .getKey())
return JOY_LEFT;
133 else if (key == right.getKey())
return JOY_RIGHT;
134 else if (key == trigA.getKey())
return JOY_BUTTONA;
135 else if (key == trigB.getKey())
return JOY_BUTTONB;
136 else return uint8_t(0);
139 [&](
const KeyDownEvent&
e) { press = getKey(
e); },
140 [&](
const KeyUpEvent&
e) { release = getKey(
e); },
141 [](
const EventBase&) { }
144 if (((status & ~press) | release) != status) {
145 stateChangeDistributor.distributeNew<KeyJoyState>(
146 time,
id, press, release);
151void KeyJoystick::signalStateChange(
const StateChange& event)
153 const auto* kjs =
dynamic_cast<const KeyJoyState*
>(&event);
155 if (kjs->getId() !=
id)
return;
157 status = (status & ~kjs->getPress()) | kjs->getRelease();
160void KeyJoystick::stopReplay(EmuTime::param time)
noexcept
163 uint8_t newStatus = JOY_UP | JOY_DOWN | JOY_LEFT | JOY_RIGHT |
164 JOY_BUTTONA | JOY_BUTTONB;
165 if (newStatus != status) {
166 uint8_t release = newStatus & ~status;
167 stateChangeDistributor.distributeNew<KeyJoyState>(
168 time,
id, uint8_t(0), release);
176template<
typename Archive>
179 if (ar.versionAtLeast(version, 2)) {
180 ar.serialize(
"status", status);
182 if constexpr (Archive::IS_LOADER) {
KeyJoyState(EmuTime::param time_, KeyJoystick::ID id_, uint8_t press_, uint8_t release_)
void serialize(Archive &ar, unsigned)
uint8_t getRelease() const
KeyJoystick(CommandController &commandController, MSXEventDistributor &eventDistributor, StateChangeDistributor &stateChangeDistributor, ID id)
void serialize(Archive &ar, unsigned version)
void registerEventListener(MSXEventListener &listener)
Registers a given object to receive certain events.
void unregisterEventListener(MSXEventListener &listener)
Unregisters a previously registered event listener.
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 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.
KeyCode
Constants that identify keys and key modifiers.
This file implemented 3 utility functions:
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
auto visit(Visitor &&visitor, const Event &event)
REGISTER_POLYMORPHIC_CLASS(StateChange, AutofireStateChange, "AutofireStateChange")
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
TemporaryString tmpStrCat(Ts &&... ts)