16static constexpr int THRESHOLD = 2;
17static constexpr int SCALE = 2;
18static constexpr int PHASE_XHIGH = 0;
19static constexpr int PHASE_XLOW = 1;
20static constexpr int PHASE_YHIGH = 2;
21static constexpr int PHASE_YLOW = 3;
22static constexpr int STROBE = 0x04;
29 MouseState(EmuTime::param time_,
int deltaX_,
int deltaY_,
30 uint8_t press_, uint8_t release_)
32 , deltaX(deltaX_), deltaY(deltaY_)
33 , press(press_), release(release_) {}
34 [[nodiscard]]
int getDeltaX()
const {
return deltaX; }
35 [[nodiscard]]
int getDeltaY()
const {
return deltaY; }
36 [[nodiscard]] uint8_t
getPress()
const {
return press; }
37 [[nodiscard]] uint8_t
getRelease()
const {
return release; }
38 template<
typename Archive>
void serialize(Archive& ar,
unsigned version)
40 ar.template serializeBase<StateChange>(*
this);
41 ar.serialize(
"deltaX", deltaX,
45 if (ar.versionBelow(version, 2)) {
46 assert(Archive::IS_LOADER);
59 deltaX = newMsxX - oldMsxX;
60 deltaY = newMsxY - oldMsxY;
65 uint8_t press, release;
75 : eventDistributor(eventDistributor_)
76 , stateChangeDistributor(stateChangeDistributor_)
84 Mouse::unplugHelper(EmuTime::dummy());
90std::string_view Mouse::getName()
const
95std::string_view Mouse::getDescription()
const
100void Mouse::plugHelper(Connector& , EmuTime::param time)
102 if (SDL_GetMouseState(
nullptr,
nullptr) & SDL_BUTTON(SDL_BUTTON_LEFT)) {
113void Mouse::plugHelper2()
119void Mouse::unplugHelper(EmuTime::param )
127uint8_t Mouse::read(EmuTime::param )
132 return ((xRel >> 4) & 0x0F) | status;
134 return (xRel & 0x0F) | status;
136 return ((yRel >> 4) & 0x0F) | status;
138 return (yRel & 0x0F) | status;
148void Mouse::emulateJoystick()
152 int deltaX = curXRel; curXRel = 0;
153 int deltaY = curYRel; curYRel = 0;
154 int absX = (deltaX > 0) ? deltaX : -deltaX;
155 int absY = (deltaY > 0) ? deltaY : -deltaY;
157 if ((absX < THRESHOLD) && (absY < THRESHOLD)) {
164 if ((12 * absX) > (5 * absY)) {
167 if ((12 * absY) > (5 * absX)) {
171 if ((12 * absX) > (5 * absY)) {
174 if ((12 * absY) > (5 * absX)) {
180 if ((12 * absX) > (5 * absY)) {
183 if ((12 * absY) > (5 * absX)) {
187 if ((12 * absX) > (5 * absY)) {
190 if ((12 * absY) > (5 * absX)) {
197void Mouse::write(uint8_t value, EmuTime::param time)
221 if ((value & STROBE) == 0) phase = PHASE_XLOW;
224 if ((value & STROBE) != 0) phase = PHASE_YHIGH;
227 if ((value & STROBE) == 0) phase = PHASE_YLOW;
230 if ((value & STROBE) != 0) {
235 xrel = curxrel; yrel = curyrel;
236 curxrel = 0; curyrel = 0;
242 xRel = std::clamp(curXRel, -127, 127);
243 yRel = std::clamp(curYRel, -127, 127);
257void Mouse::signalMSXEvent(
const Event& event, EmuTime::param time)
noexcept
260 [&](
const MouseMotionEvent&
e) {
261 if (
e.getX() ||
e.getY()) {
268 fractionalX = qrX.remainder;
269 fractionalY = qrY.remainder;
272 createMouseStateChange(time, -qrX.quotient, -qrY.quotient, 0, 0);
275 [&](
const MouseButtonDownEvent&
e) {
276 switch (
e.getButton()) {
277 case SDL_BUTTON_LEFT:
278 createMouseStateChange(time, 0, 0, JOY_BUTTONA, 0);
280 case SDL_BUTTON_RIGHT:
281 createMouseStateChange(time, 0, 0, JOY_BUTTONB, 0);
288 [&](
const MouseButtonUpEvent&
e) {
289 switch (
e.getButton()) {
290 case SDL_BUTTON_LEFT:
291 createMouseStateChange(time, 0, 0, 0, JOY_BUTTONA);
293 case SDL_BUTTON_RIGHT:
294 createMouseStateChange(time, 0, 0, 0, JOY_BUTTONB);
301 [](
const EventBase&) { }
305void Mouse::createMouseStateChange(
306 EmuTime::param time,
int deltaX,
int deltaY, uint8_t press, uint8_t release)
309 time, deltaX, deltaY, press, release);
312void Mouse::signalStateChange(
const StateChange& event)
314 const auto* ms =
dynamic_cast<const MouseState*
>(&event);
319 curXRel += ms->getDeltaX();
320 curYRel += ms->getDeltaY();
321 status = (status & ~ms->getPress()) | ms->getRelease();
324void Mouse::stopReplay(EmuTime::param time)
noexcept
327 int dx = 0 - curXRel;
328 int dy = 0 - curYRel;
329 uint8_t release = (JOY_BUTTONA | JOY_BUTTONB) & ~status;
330 if ((dx != 0) || (dy != 0) || (release != 0)) {
331 createMouseStateChange(time, dx, dy, 0, release);
341template<
typename Archive>
347 if constexpr (Archive::IS_LOADER) {
356 if (ar.versionBelow(version, 4)) {
357 assert(Archive::IS_LOADER);
359 ar.serialize(
"lastTime", tmp);
362 ar.serialize(
"lastTime", lastTime);
364 ar.serialize(
"faze", phase,
368 "mouseMode", mouseMode);
369 if (ar.versionAtLeast(version, 2)) {
370 ar.serialize(
"curxrel", curXRel,
374 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 uint8_t JOY_RIGHT
static constexpr uint8_t JOY_LEFT
static constexpr uint8_t JOY_DOWN
static constexpr uint8_t JOY_UP
void registerEventListener(MSXEventListener &listener)
Registers a given object to receive certain events.
void unregisterEventListener(MSXEventListener &listener)
Unregisters a previously registered event listener.
uint8_t getRelease() const
void serialize(Archive &ar, unsigned version)
MouseState(EmuTime::param time_, int deltaX_, int deltaY_, uint8_t press_, uint8_t 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 QuotientRemainder div_mod_floor(int dividend, int divisor)
This file implemented 3 utility functions:
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
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)