16 constexpr
int SCALE = 2;
28 MouseState(EmuTime::param time_,
int deltaX_,
int deltaY_,
29 byte press_,
byte release_)
31 , deltaX(deltaX_), deltaY(deltaY_)
32 , press(press_), release(release_) {}
33 [[nodiscard]]
int getDeltaX()
const {
return deltaX; }
34 [[nodiscard]]
int getDeltaY()
const {
return deltaY; }
35 [[nodiscard]]
byte getPress()
const {
return press; }
36 [[nodiscard]]
byte getRelease()
const {
return release; }
37 template<
typename Archive>
void serialize(Archive& ar,
unsigned )
39 ar.template serializeBase<StateChange>(*
this);
40 ar.serialize(
"deltaX", deltaX,
54 : eventDistributor(eventDistributor_)
55 , stateChangeDistributor(stateChangeDistributor_)
56 , lastTime(EmuTime::zero())
64 , status(JOY_BUTTONA | JOY_BUTTONB)
72 Mouse::unplugHelper(EmuTime::dummy());
78 std::string_view Mouse::getName()
const
83 std::string_view Mouse::getDescription()
const
88 void Mouse::plugHelper(
Connector& , EmuTime::param time)
90 if (SDL_GetMouseState(
nullptr,
nullptr) & SDL_BUTTON(SDL_BUTTON_LEFT)) {
101 void Mouse::plugHelper2()
107 void Mouse::unplugHelper(EmuTime::param )
115 byte Mouse::read(EmuTime::param )
120 return ((xrel >> 4) & 0x0F) | status;
122 return (xrel & 0x0F) | status;
124 return ((yrel >> 4) & 0x0F) | status;
126 return (yrel & 0x0F) | status;
136 void Mouse::emulateJoystick()
140 int deltaX = curxrel; curxrel = 0;
141 int deltaY = curyrel; curyrel = 0;
142 int absX = (deltaX > 0) ? deltaX : -deltaX;
143 int absY = (deltaY > 0) ? deltaY : -deltaY;
152 if ((12 * absX) > (5 * absY)) {
155 if ((12 * absY) > (5 * absX)) {
159 if ((12 * absX) > (5 * absY)) {
162 if ((12 * absY) > (5 * absX)) {
168 if ((12 * absX) > (5 * absY)) {
171 if ((12 * absY) > (5 * absX)) {
175 if ((12 * absX) > (5 * absY)) {
178 if ((12 * absY) > (5 * absX)) {
185 void Mouse::write(
byte value, EmuTime::param time)
218 if ((value &
STROBE) != 0) {
223 xrel = curxrel; yrel = curyrel;
224 curxrel = 0; curyrel = 0;
245 void Mouse::signalMSXEvent(
const Event& event, EmuTime::param time) noexcept
248 [&](
const MouseMotionEvent&
e) {
249 if (
e.getX() ||
e.getY()) {
254 createMouseStateChange(time, -
e.getX(), -
e.getY(), 0, 0);
257 [&](
const MouseButtonDownEvent&
e) {
258 switch (
e.getButton()) {
260 createMouseStateChange(time, 0, 0, JOY_BUTTONA, 0);
263 createMouseStateChange(time, 0, 0, JOY_BUTTONB, 0);
270 [&](
const MouseButtonUpEvent&
e) {
271 switch (
e.getButton()) {
273 createMouseStateChange(time, 0, 0, 0, JOY_BUTTONA);
276 createMouseStateChange(time, 0, 0, 0, JOY_BUTTONB);
283 [](
const EventBase&) { }
287 void Mouse::createMouseStateChange(
288 EmuTime::param time,
int deltaX,
int deltaY,
byte press,
byte release)
291 time, deltaX, deltaY, press, release);
294 void Mouse::signalStateChange(
const StateChange& event)
296 const auto* ms =
dynamic_cast<const MouseState*
>(&event);
302 int oldMsxX = absHostX /
SCALE;
303 int oldMsxY = absHostY /
SCALE;
304 absHostX += ms->getDeltaX();
305 absHostY += ms->getDeltaY();
306 int newMsxX = absHostX /
SCALE;
307 int newMsxY = absHostY /
SCALE;
308 int relMsxX = newMsxX - oldMsxX;
309 int relMsxY = newMsxY - oldMsxY;
315 status = (status & ~ms->getPress()) | ms->getRelease();
318 void Mouse::stopReplay(EmuTime::param time) noexcept
321 int dx = 0 - curxrel;
322 int dy = 0 - curyrel;
323 byte release = (JOY_BUTTONA | JOY_BUTTONB) & ~status;
324 if ((dx != 0) || (dy != 0) || (release != 0)) {
325 createMouseStateChange(time, dx, dy, 0, release);
335 template<
typename Archive>
338 if constexpr (Archive::IS_LOADER) {
347 if (ar.versionBelow(version, 4)) {
348 assert(Archive::IS_LOADER);
350 ar.serialize(
"lastTime", tmp);
353 ar.serialize(
"lastTime", lastTime);
355 ar.serialize(
"faze", phase,
359 "mouseMode", mouseMode);
360 if (ar.versionAtLeast(version, 2)) {
361 ar.serialize(
"curxrel", curxrel,
365 if (ar.versionBelow(version, 3)) {
Represents a clock with a fixed frequency.
constexpr EmuTime::param getTime() const
Gets the time at which the last clock tick occurred.
static constexpr EmuDuration usec(unsigned x)
static constexpr int JOY_RIGHT
static constexpr int JOY_LEFT
static constexpr int JOY_DOWN
static constexpr int JOY_UP
void registerEventListener(MSXEventListener &listener)
Registers a given object to receive certain events.
void unregisterEventListener(MSXEventListener &listener)
Unregisters a previously registered event listener.
void serialize(Archive &ar, unsigned)
MouseState(EmuTime::param time_, int deltaX_, int deltaY_, byte press_, byte release_)
Mouse(MSXEventDistributor &eventDistributor, StateChangeDistributor &stateChangeDistributor)
void serialize(Archive &ar, unsigned version)
bool isPluggedIn() const
Returns true if this pluggable is currently plugged into a connector.
void registerListener(StateChangeListener &listener)
(Un)registers the given object to receive state change events.
void distributeNew(EmuTime::param time, Args &&...args)
Deliver the event to all registered listeners MSX input devices should call the distributeNew() versi...
void unregisterListener(StateChangeListener &listener)
Base class for all external MSX state changing events.
constexpr vecN< N, T > clamp(const vecN< N, T > &x, const vecN< N, T > &minVal, const vecN< N, T > &maxVal)
This file implemented 3 utility functions:
constexpr int PHASE_XHIGH
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
auto visit(Visitor &&visitor, const Event &event)
REGISTER_POLYMORPHIC_CLASS(StateChange, AutofireStateChange, "AutofireStateChange")
constexpr int PHASE_YHIGH
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)