31 ArkanoidState(EmuTime::param time_,
int delta_,
bool press_,
bool release_)
33 , delta(delta_), press(press_), release(release_) {}
34 [[nodiscard]]
int getDelta()
const {
return delta; }
35 [[nodiscard]]
bool getPress()
const {
return press; }
36 [[nodiscard]]
bool getRelease()
const {
return release; }
38 template<
typename Archive>
void serialize(Archive& ar,
unsigned )
40 ar.template serializeBase<StateChange>(*
this);
41 ar.serialize(
"delta", delta,
53 : eventDistributor(eventDistributor_)
54 , stateChangeDistributor(stateChangeDistributor_)
65 ArkanoidPad::unplugHelper(EmuTime::dummy());
71 std::string_view ArkanoidPad::getName()
const
76 std::string_view ArkanoidPad::getDescription()
const
78 return "Arkanoid pad";
81 void ArkanoidPad::plugHelper(
Connector& , EmuTime::param )
87 void ArkanoidPad::unplugHelper(EmuTime::param )
94 byte ArkanoidPad::read(EmuTime::param )
96 return buttonStatus | ((shiftreg & 0x100) >> 8);
99 void ArkanoidPad::write(
byte value, EmuTime::param )
101 byte diff = lastValue ^ value;
104 if (diff & value & 0x4) {
108 if (diff & value & 0x1) {
110 shiftreg = (shiftreg << 1) | (shiftreg & 1);
115 void ArkanoidPad::signalMSXEvent(
const Event& event,
116 EmuTime::param time) noexcept
119 [&](
const MouseMotionEvent&
e) {
122 dialpos +
e.getX() /
SCALE));
123 int delta = newPos - dialpos;
125 stateChangeDistributor.distributeNew<ArkanoidState>(
126 time, delta,
false,
false);
129 [&](
const MouseButtonDownEvent& ) {
131 if (buttonStatus & 2) {
132 stateChangeDistributor.distributeNew<ArkanoidState>(
133 time, 0,
true,
false);
136 [&](
const MouseButtonUpEvent& ) {
138 if (!(buttonStatus & 2)) {
139 stateChangeDistributor.distributeNew<ArkanoidState>(
140 time, 0,
false,
true);
143 [](
const EventBase&) { }
148 void ArkanoidPad::signalStateChange(
const StateChange& event)
150 const auto* as =
dynamic_cast<const ArkanoidState*
>(&event);
153 dialpos += as->getDelta();
154 if (as->getPress()) buttonStatus &= ~2;
155 if (as->getRelease()) buttonStatus |= 2;
158 void ArkanoidPad::stopReplay(EmuTime::param time) noexcept
162 bool release = (buttonStatus & 2) == 0;
163 if ((delta != 0) || release) {
164 stateChangeDistributor.distributeNew<ArkanoidState>(
165 time, delta,
false, release);
174 template<
typename Archive>
177 ar.serialize(
"shiftreg", shiftreg,
178 "lastValue", lastValue);
179 if (ar.versionAtLeast(version, 2)) {
180 ar.serialize(
"dialpos", dialpos,
181 "buttonStatus", buttonStatus);
183 if constexpr (Archive::IS_LOADER) {
void serialize(Archive &ar, unsigned version)
ArkanoidPad(MSXEventDistributor &eventDistributor, StateChangeDistributor &stateChangeDistributor)
ArkanoidState(EmuTime::param time_, int delta_, bool press_, bool release_)
void serialize(Archive &ar, unsigned)
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.
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
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)