This commit is contained in:
thrust26 2019-04-18 22:16:14 +02:00
commit 18babfc7a5
7 changed files with 292 additions and 293 deletions

View File

@ -42,105 +42,67 @@ MouseControl::MouseControl(Console& console, const string& mode)
m_mode[0] >= '0' && m_mode[0] <= '8' && m_mode[0] >= '0' && m_mode[0] <= '8' &&
m_mode[1] >= '0' && m_mode[1] <= '8') m_mode[1] >= '0' && m_mode[1] <= '8')
{ {
Axis xaxis = Axis(int(m_mode[0]) - '0'); MouseControl::Type xaxis = MouseControl::Type(int(m_mode[0]) - '0');
Axis yaxis = Axis(int(m_mode[1]) - '0'); MouseControl::Type yaxis = MouseControl::Type(int(m_mode[1]) - '0');
ostringstream msg; ostringstream msg;
msg << "Mouse X-axis is ";
Controller::Type xtype = Controller::Type::Joystick, ytype = Controller::Type::Joystick; Controller::Type xtype = Controller::Type::Joystick, ytype = Controller::Type::Joystick;
int xid = -1, yid = -1; int xid = -1, yid = -1;
switch(xaxis)
{ auto MControlToController = [&msg](MouseControl::Type axis,
case NoControl: Controller::Type& type, int& id) {
msg << "not used"; switch(axis)
break; {
case Paddle0: case MouseControl::Type::NoControl:
xtype = Controller::Type::Paddles; msg << "not used";
xid = 0; break;
msg << "Paddle 0"; case MouseControl::Type::Paddle0:
break; type = Controller::Type::Paddles;
case Paddle1: id = 0;
xtype = Controller::Type::Paddles; msg << "Paddle 0";
xid = 1; break;
msg << "Paddle 1"; case MouseControl::Type::Paddle1:
break; type = Controller::Type::Paddles;
case Paddle2: id = 1;
xtype = Controller::Type::Paddles; msg << "Paddle 1";
xid = 2; break;
msg << "Paddle 2"; case MouseControl::Type::Paddle2:
break; type = Controller::Type::Paddles;
case Paddle3: id = 2;
xtype = Controller::Type::Paddles; msg << "Paddle 2";
xid = 3; break;
msg << "Paddle 3"; case MouseControl::Type::Paddle3:
break; type = Controller::Type::Paddles;
case Driving0: id = 3;
xtype = Controller::Type::Driving; msg << "Paddle 3";
xid = 0; break;
msg << "Driving 0"; case MouseControl::Type::Driving0:
break; type = Controller::Type::Driving;
case Driving1: id = 0;
xtype = Controller::Type::Driving; msg << "Driving 0";
xid = 1; break;
msg << "Driving 1"; case MouseControl::Type::Driving1:
break; type = Controller::Type::Driving;
case MindLink0: id = 1;
xtype = Controller::Type::MindLink; msg << "Driving 1";
xid = 0; break;
msg << "MindLink 0"; case MouseControl::Type::MindLink0:
break; type = Controller::Type::MindLink;
case MindLink1: id = 0;
xtype = Controller::Type::MindLink; msg << "MindLink 0";
xid = 1; break;
msg << "MindLink 1"; case MouseControl::Type::MindLink1:
break; type = Controller::Type::MindLink;
} id = 1;
msg << "MindLink 1";
break;
}
};
msg << "Mouse X-axis is ";
MControlToController(xaxis, xtype, xid);
msg << ", Y-axis is "; msg << ", Y-axis is ";
switch(yaxis) MControlToController(yaxis, ytype, yid);
{
case NoControl:
msg << "not used";
break;
case Paddle0:
ytype = Controller::Type::Paddles;
yid = 0;
msg << "Paddle 0";
break;
case Paddle1:
ytype = Controller::Type::Paddles;
yid = 1;
msg << "Paddle 1";
break;
case Paddle2:
ytype = Controller::Type::Paddles;
yid = 2;
msg << "Paddle 2";
break;
case Paddle3:
ytype = Controller::Type::Paddles;
yid = 3;
msg << "Paddle 3";
break;
case Driving0:
ytype = Controller::Type::Driving;
yid = 0;
msg << "Driving 0";
break;
case Driving1:
ytype = Controller::Type::Driving;
yid = 1;
msg << "Driving 1";
break;
case MindLink0:
ytype = Controller::Type::MindLink;
yid = 0;
msg << "MindLink 0";
break;
case MindLink1:
ytype = Controller::Type::MindLink;
yid = 1;
msg << "MindLink 1";
break;
}
myModeList.push_back(MouseMode(xtype, xid, ytype, yid, msg.str())); myModeList.push_back(MouseMode(xtype, xid, ytype, yid, msg.str()));
} }

View File

@ -41,7 +41,7 @@ class MouseControl
/** /**
Enumeration of mouse axis control types Enumeration of mouse axis control types
*/ */
enum Axis enum class Type
{ {
Paddle0 = 0, Paddle1, Paddle2, Paddle3, Paddle0 = 0, Paddle1, Paddle2, Paddle3,
Driving0, Driving1, MindLink0, MindLink1, Driving0, Driving1, MindLink0, MindLink1,

View File

@ -82,60 +82,9 @@ class Ball : public Serializable
bool save(Serializer& out) const override; bool save(Serializer& out) const override;
bool load(Serializer& in) override; bool load(Serializer& in) override;
void movementTick(uInt32 clock, bool hblank) inline void movementTick(uInt32 clock, bool hblank);
{
myLastMovementTick = myCounter;
if (clock == myHmmClocks) inline void tick(bool isReceivingMclock = true);
isMoving = false;
if(isMoving)
{
if (hblank) tick(false);
myInvertedPhaseClock = !hblank;
}
}
void tick(bool isReceivingMclock = true)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible = myIsRendering && myRenderCounter >= 0;
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
bool starfieldEffect = isMoving && isReceivingMclock;
if (myCounter == 156) {
myIsRendering = true;
myRenderCounter = renderCounterOffset;
uInt8 starfieldDelta = (myCounter + TIAConstants::H_PIXEL - myLastMovementTick) % 4;
if (starfieldEffect && starfieldDelta == 3 && myWidth < 4) ++myRenderCounter;
switch (starfieldDelta) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else if (myIsRendering && ++myRenderCounter >= (starfieldEffect ? myEffectiveWidth : myWidth))
myIsRendering = false;
if (++myCounter >= TIAConstants::H_PIXEL)
myCounter = 0;
}
public: public:
@ -191,4 +140,65 @@ class Ball : public Serializable
Ball& operator=(Ball&&); Ball& operator=(Ball&&);
}; };
// ############################################################################
// Implementation
// ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Ball::movementTick(uInt32 clock, bool hblank)
{
myLastMovementTick = myCounter;
if (clock == myHmmClocks)
isMoving = false;
if(isMoving)
{
if (hblank) tick(false);
myInvertedPhaseClock = !hblank;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Ball::tick(bool isReceivingMclock)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible = myIsRendering && myRenderCounter >= 0;
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
bool starfieldEffect = isMoving && isReceivingMclock;
if (myCounter == 156) {
myIsRendering = true;
myRenderCounter = renderCounterOffset;
uInt8 starfieldDelta = (myCounter + TIAConstants::H_PIXEL - myLastMovementTick) % 4;
if (starfieldEffect && starfieldDelta == 3 && myWidth < 4) ++myRenderCounter;
switch (starfieldDelta) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else if (myIsRendering && ++myRenderCounter >= (starfieldEffect ? myEffectiveWidth : myWidth))
myIsRendering = false;
if (++myCounter >= TIAConstants::H_PIXEL)
myCounter = 0;
}
#endif // TIA_BALL #endif // TIA_BALL

View File

@ -76,62 +76,9 @@ class Missile : public Serializable
bool save(Serializer& out) const override; bool save(Serializer& out) const override;
bool load(Serializer& in) override; bool load(Serializer& in) override;
void movementTick(uInt8 clock, uInt8 hclock, bool hblank) inline void movementTick(uInt8 clock, uInt8 hclock, bool hblank);
{
if(clock == myHmmClocks) isMoving = false;
if (isMoving) inline void tick(uInt8 hclock, bool isReceivingMclock = true);
{
if (hblank) tick(hclock, false);
myInvertedPhaseClock = !hblank;
}
}
void tick(uInt8 hclock, bool isReceivingMclock = true)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible =
myIsRendering &&
(myRenderCounter >= 0 || (isMoving && isReceivingMclock && myRenderCounter == -1 && myWidth < 4 && ((hclock + 1) % 4 == 3)));
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter] && !myResmp) {
myIsRendering = true;
myRenderCounter = renderCounterOffset;
} else if (myIsRendering) {
if (myRenderCounter == -1) {
if (isMoving && isReceivingMclock) {
switch ((hclock + 1) % 4) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
if (myWidth < 4) ++myRenderCounter;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else {
myEffectiveWidth = myWidth;
}
}
if (++myRenderCounter >= (isMoving ? myEffectiveWidth : myWidth)) myIsRendering = false;
}
if (++myCounter >= TIAConstants::H_PIXEL) myCounter = 0;
}
public: public:
@ -188,4 +135,67 @@ class Missile : public Serializable
Missile& operator=(Missile&&) = delete; Missile& operator=(Missile&&) = delete;
}; };
// ############################################################################
// Implementation
// ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::movementTick(uInt8 clock, uInt8 hclock, bool hblank)
{
if(clock == myHmmClocks) isMoving = false;
if (isMoving)
{
if (hblank) tick(hclock, false);
myInvertedPhaseClock = !hblank;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::tick(uInt8 hclock, bool isReceivingMclock)
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
myIsVisible =
myIsRendering &&
(myRenderCounter >= 0 || (isMoving && isReceivingMclock && myRenderCounter == -1 && myWidth < 4 && ((hclock + 1) % 4 == 3)));
collision = (myIsVisible && myIsEnabled) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter] && !myResmp) {
myIsRendering = true;
myRenderCounter = renderCounterOffset;
} else if (myIsRendering) {
if (myRenderCounter == -1) {
if (isMoving && isReceivingMclock) {
switch ((hclock + 1) % 4) {
case 3:
myEffectiveWidth = myWidth == 1 ? 2 : myWidth;
if (myWidth < 4) ++myRenderCounter;
break;
case 2:
myEffectiveWidth = 0;
break;
default:
myEffectiveWidth = myWidth;
break;
}
} else {
myEffectiveWidth = myWidth;
}
}
if (++myRenderCounter >= (isMoving ? myEffectiveWidth : myWidth)) myIsRendering = false;
}
if (++myCounter >= TIAConstants::H_PIXEL) myCounter = 0;
}
#endif // TIA_MISSILE #endif // TIA_MISSILE

View File

@ -87,63 +87,9 @@ class Player : public Serializable
bool save(Serializer& out) const override; bool save(Serializer& out) const override;
bool load(Serializer& in) override; bool load(Serializer& in) override;
void movementTick(uInt32 clock, bool hblank) inline void movementTick(uInt32 clock, bool hblank);
{
if (clock == myHmmClocks)
isMoving = false;
if(isMoving) inline void tick();
{
if (hblank) tick();
myInvertedPhaseClock = !hblank;
}
}
void tick()
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
if (!myIsRendering || myRenderCounter < myRenderCounterTripPoint)
collision = myCollisionMaskDisabled;
else
collision = (myPattern & (1 << mySampleCounter)) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter]) {
myIsRendering = true;
mySampleCounter = 0;
myRenderCounter = renderCounterOffset;
} else if (myIsRendering) {
++myRenderCounter;
switch (myDivider) {
case 1:
if (myRenderCounter > 0)
++mySampleCounter;
if (myRenderCounter >= 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
default:
if (myRenderCounter > 1 && (((myRenderCounter - 1) % myDivider) == 0))
++mySampleCounter;
if (myRenderCounter > 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
}
if (mySampleCounter > 7) myIsRendering = false;
}
if (++myCounter >= TIAConstants::H_PIXEL) myCounter = 0;
}
public: public:
@ -205,4 +151,68 @@ class Player : public Serializable
Player& operator=(Player&&) = delete; Player& operator=(Player&&) = delete;
}; };
// ############################################################################
// Implementation
// ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::movementTick(uInt32 clock, bool hblank)
{
if (clock == myHmmClocks)
isMoving = false;
if(isMoving)
{
if (hblank) tick();
myInvertedPhaseClock = !hblank;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::tick()
{
if(myUseInvertedPhaseClock && myInvertedPhaseClock)
{
myInvertedPhaseClock = false;
return;
}
if (!myIsRendering || myRenderCounter < myRenderCounterTripPoint)
collision = myCollisionMaskDisabled;
else
collision = (myPattern & (1 << mySampleCounter)) ? myCollisionMaskEnabled : myCollisionMaskDisabled;
if (myDecodes[myCounter]) {
myIsRendering = true;
mySampleCounter = 0;
myRenderCounter = renderCounterOffset;
} else if (myIsRendering) {
++myRenderCounter;
switch (myDivider) {
case 1:
if (myRenderCounter > 0)
++mySampleCounter;
if (myRenderCounter >= 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
default:
if (myRenderCounter > 1 && (((myRenderCounter - 1) % myDivider) == 0))
++mySampleCounter;
if (myRenderCounter > 0 && myDividerChangeCounter >= 0 && myDividerChangeCounter-- == 0)
setDivider(myDividerPending);
break;
}
if (mySampleCounter > 7) myIsRendering = false;
}
if (++myCounter >= TIAConstants::H_PIXEL) myCounter = 0;
}
#endif // TIA_PLAYER #endif // TIA_PLAYER

View File

@ -127,31 +127,9 @@ class Playfield : public Serializable
bool load(Serializer& in) override; bool load(Serializer& in) override;
/** /**
Tick one color clock. Inline for performance. Tick one color clock. Inline for performance (implementation below).
*/ */
void tick(uInt32 x) inline void tick(uInt32 x);
{
myX = x;
// Reflected flag is updated only at x = 0 or x = 79
if (myX == TIAConstants::H_PIXEL / 2 || myX == 0) myRefp = myReflected;
if (x & 0x03) return;
uInt32 currentPixel;
if (myEffectivePattern == 0) {
currentPixel = 0;
} else if (x < TIAConstants::H_PIXEL / 2) {
currentPixel = myEffectivePattern & (1 << (x >> 2));
} else if (myRefp) {
currentPixel = myEffectivePattern & (1 << (39 - (x >> 2)));
} else {
currentPixel = myEffectivePattern & (1 << ((x >> 2) - 20));
}
collision = currentPixel ? myCollisionMaskEnabled : myCollisionMaskDisabled;
}
public: public:
@ -268,4 +246,33 @@ class Playfield : public Serializable
Playfield& operator=(Playfield&&) = delete; Playfield& operator=(Playfield&&) = delete;
}; };
// ############################################################################
// Implementation
// ############################################################################
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::tick(uInt32 x)
{
myX = x;
// Reflected flag is updated only at x = 0 or x = 79
if (myX == TIAConstants::H_PIXEL / 2 || myX == 0) myRefp = myReflected;
if (x & 0x03) return;
uInt32 currentPixel;
if (myEffectivePattern == 0) {
currentPixel = 0;
} else if (x < TIAConstants::H_PIXEL / 2) {
currentPixel = myEffectivePattern & (1 << (x >> 2));
} else if (myRefp) {
currentPixel = myEffectivePattern & (1 << (39 - (x >> 2)));
} else {
currentPixel = myEffectivePattern & (1 << ((x >> 2) - 20));
}
collision = currentPixel ? myCollisionMaskEnabled : myCollisionMaskDisabled;
}
#endif // TIA_PLAYFIELD #endif // TIA_PLAYFIELD

View File

@ -247,15 +247,15 @@ GameInfoDialog::GameInfoDialog(
// Mouse controller specific axis // Mouse controller specific axis
pwidth = font.getStringWidth("MindLink 0"); pwidth = font.getStringWidth("MindLink 0");
items.clear(); items.clear();
VarList::push_back(items, "None", MouseControl::NoControl); VarList::push_back(items, "None", static_cast<uInt32>(MouseControl::Type::NoControl));
VarList::push_back(items, "Paddle 0", MouseControl::Paddle0); VarList::push_back(items, "Paddle 0", static_cast<uInt32>(MouseControl::Type::Paddle0));
VarList::push_back(items, "Paddle 1", MouseControl::Paddle1); VarList::push_back(items, "Paddle 1", static_cast<uInt32>(MouseControl::Type::Paddle1));
VarList::push_back(items, "Paddle 2", MouseControl::Paddle2); VarList::push_back(items, "Paddle 2", static_cast<uInt32>(MouseControl::Type::Paddle2));
VarList::push_back(items, "Paddle 3", MouseControl::Paddle3); VarList::push_back(items, "Paddle 3", static_cast<uInt32>(MouseControl::Type::Paddle3));
VarList::push_back(items, "Driving 0", MouseControl::Driving0); VarList::push_back(items, "Driving 0", static_cast<uInt32>(MouseControl::Type::Driving0));
VarList::push_back(items, "Driving 1", MouseControl::Driving1); VarList::push_back(items, "Driving 1", static_cast<uInt32>(MouseControl::Type::Driving1));
VarList::push_back(items, "MindLink 0", MouseControl::MindLink0); VarList::push_back(items, "MindLink 0", static_cast<uInt32>(MouseControl::Type::MindLink0));
VarList::push_back(items, "MindLink 1", MouseControl::MindLink1); VarList::push_back(items, "MindLink 1", static_cast<uInt32>(MouseControl::Type::MindLink1));
xpos += 20; xpos += 20;
ypos += lineHeight + VGAP; ypos += lineHeight + VGAP;