mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
Fixed flipper animation frame skip bug.
It is from original 3DPB, not present in FT.
This commit is contained in:
parent
7ee508118c
commit
48721e5811
@ -22,14 +22,14 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||||||
Smoothness = visual.Smoothness;
|
Smoothness = visual.Smoothness;
|
||||||
|
|
||||||
auto collMult = *loader::query_float_attribute(groupIndex, 0, 803);
|
auto collMult = *loader::query_float_attribute(groupIndex, 0, 803);
|
||||||
auto bmpCoef2 = *loader::query_float_attribute(groupIndex, 0, 805);
|
auto retractTime = *loader::query_float_attribute(groupIndex, 0, 805);
|
||||||
auto bmpCoef1 = *loader::query_float_attribute(groupIndex, 0, 804);
|
auto extendTime = *loader::query_float_attribute(groupIndex, 0, 804);
|
||||||
|
|
||||||
/*Full tilt hack: different flipper speed*/
|
/*Full tilt hack: different flipper speed*/
|
||||||
if (pb::FullTiltMode)
|
if (pb::FullTiltMode)
|
||||||
{
|
{
|
||||||
bmpCoef2 = 0.08f;
|
retractTime = 0.08f;
|
||||||
bmpCoef1 = 0.04f;
|
extendTime = 0.04f;
|
||||||
}
|
}
|
||||||
auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802));
|
auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802));
|
||||||
auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801));
|
auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801));
|
||||||
@ -42,8 +42,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||||||
origin,
|
origin,
|
||||||
vecT1,
|
vecT1,
|
||||||
vecT2,
|
vecT2,
|
||||||
bmpCoef1,
|
extendTime,
|
||||||
bmpCoef2,
|
retractTime,
|
||||||
collMult,
|
collMult,
|
||||||
Elasticity,
|
Elasticity,
|
||||||
Smoothness);
|
Smoothness);
|
||||||
@ -51,8 +51,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||||||
FlipperEdge = flipperEdge;
|
FlipperEdge = flipperEdge;
|
||||||
if (flipperEdge)
|
if (flipperEdge)
|
||||||
{
|
{
|
||||||
BmpCoef1 = flipperEdge->BmpCoef1 / static_cast<float>(ListBitmap->size() - 1);
|
ExtendAnimationFrameTime = flipperEdge->ExtendTime / static_cast<float>(ListBitmap->size() - 1);
|
||||||
BmpCoef2 = flipperEdge->BmpCoef2 / static_cast<float>(ListBitmap->size() - 1);
|
RetractAnimationFrameTime = flipperEdge->RetractTime / static_cast<float>(ListBitmap->size() - 1);
|
||||||
}
|
}
|
||||||
BmpIndex = 0;
|
BmpIndex = 0;
|
||||||
InputTime = 0.0;
|
InputTime = 0.0;
|
||||||
@ -68,35 +68,30 @@ int TFlipper::Message(int code, float value)
|
|||||||
if (code == 1 || code == 2 || code > 1008 && code <= 1011 || code == 1022)
|
if (code == 1 || code == 2 || code > 1008 && code <= 1011 || code == 1022)
|
||||||
{
|
{
|
||||||
float timerTime;
|
float timerTime;
|
||||||
int soundIndex = 0, code2 = code;
|
int command = code;
|
||||||
if (code == 1)
|
if (code == 1)
|
||||||
{
|
{
|
||||||
control::handler(1, this);
|
control::handler(1, this);
|
||||||
TimerTime = BmpCoef1;
|
TimerTime = ExtendAnimationFrameTime;
|
||||||
soundIndex = HardHitSoundId;
|
loader::play_sound(HardHitSoundId);
|
||||||
}
|
}
|
||||||
else if (code == 2)
|
else if (code == 2)
|
||||||
{
|
{
|
||||||
TimerTime = BmpCoef2;
|
TimerTime = RetractAnimationFrameTime;
|
||||||
soundIndex = SoftHitSoundId;
|
loader::play_sound(SoftHitSoundId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code2 = 2;
|
// Retract for all non-input messages
|
||||||
TimerTime = BmpCoef2;
|
command = 2;
|
||||||
|
TimerTime = RetractAnimationFrameTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (soundIndex)
|
|
||||||
loader::play_sound(soundIndex);
|
|
||||||
if (Timer)
|
|
||||||
{
|
|
||||||
timer::kill(Timer);
|
|
||||||
Timer = 0;
|
|
||||||
}
|
|
||||||
if (MessageField)
|
if (MessageField)
|
||||||
{
|
{
|
||||||
auto v10 = value - FlipperEdge->InputTime;
|
// Message arrived before animation is finished
|
||||||
timerTime = v10 - floor(v10 / TimerTime) * TimerTime;
|
auto inputDt = value - FlipperEdge->InputTime;
|
||||||
|
timerTime = inputDt - floor(inputDt / TimerTime) * TimerTime;
|
||||||
if (timerTime < 0.0f)
|
if (timerTime < 0.0f)
|
||||||
timerTime = 0.0;
|
timerTime = 0.0;
|
||||||
}
|
}
|
||||||
@ -104,10 +99,13 @@ int TFlipper::Message(int code, float value)
|
|||||||
{
|
{
|
||||||
timerTime = TimerTime;
|
timerTime = TimerTime;
|
||||||
}
|
}
|
||||||
MessageField = code2;
|
|
||||||
|
MessageField = command;
|
||||||
InputTime = value;
|
InputTime = value;
|
||||||
|
if (Timer)
|
||||||
|
timer::kill(Timer);
|
||||||
Timer = timer::set(timerTime, this, TimerExpired);
|
Timer = timer::set(timerTime, this, TimerExpired);
|
||||||
FlipperEdge->SetMotion(code2, value);
|
FlipperEdge->SetMotion(command, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == 1020 || code == 1024)
|
if (code == 1020 || code == 1024)
|
||||||
@ -137,49 +135,43 @@ void TFlipper::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
|
|||||||
void TFlipper::TimerExpired(int timerId, void* caller)
|
void TFlipper::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto flip = static_cast<TFlipper*>(caller);
|
auto flip = static_cast<TFlipper*>(caller);
|
||||||
int timer; // eax
|
int bmpCountSub1 = flip->ListBitmap->size() - 1;
|
||||||
|
|
||||||
|
auto newBmpIndex = static_cast<int>(floor((pb::time_now - flip->InputTime) / flip->TimerTime));
|
||||||
|
if (newBmpIndex > bmpCountSub1)
|
||||||
|
newBmpIndex = bmpCountSub1;
|
||||||
|
if (newBmpIndex < 0)
|
||||||
|
newBmpIndex = 0;
|
||||||
|
|
||||||
bool bmpIndexOutOfBounds = false;
|
bool bmpIndexOutOfBounds = false;
|
||||||
auto bmpIndexAdvance = static_cast<int>(floor((pb::time_now - flip->InputTime) / flip->TimerTime + 0.5f));
|
|
||||||
int bmpCount = flip->ListBitmap->size();
|
|
||||||
if (bmpIndexAdvance > bmpCount)
|
|
||||||
bmpIndexAdvance = bmpCount;
|
|
||||||
if (bmpIndexAdvance < 0)
|
|
||||||
bmpIndexAdvance = 0;
|
|
||||||
|
|
||||||
if (!bmpIndexAdvance)
|
|
||||||
bmpIndexAdvance = 1;
|
|
||||||
|
|
||||||
if (flip->MessageField == 1)
|
if (flip->MessageField == 1)
|
||||||
{
|
{
|
||||||
flip->BmpIndex += bmpIndexAdvance;
|
flip->BmpIndex = newBmpIndex;
|
||||||
int countSub1 = flip->ListBitmap->size() - 1;
|
if (flip->BmpIndex >= bmpCountSub1)
|
||||||
if (flip->BmpIndex >= countSub1)
|
|
||||||
{
|
{
|
||||||
flip->BmpIndex = countSub1;
|
flip->BmpIndex = bmpCountSub1;
|
||||||
bmpIndexOutOfBounds = true;
|
bmpIndexOutOfBounds = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flip->MessageField == 2)
|
if (flip->MessageField == 2)
|
||||||
{
|
{
|
||||||
flip->BmpIndex -= bmpIndexAdvance;
|
flip->BmpIndex = bmpCountSub1 - newBmpIndex;
|
||||||
timer = 0;
|
|
||||||
if (flip->BmpIndex <= 0)
|
if (flip->BmpIndex <= 0)
|
||||||
{
|
{
|
||||||
flip->BmpIndex = 0;
|
flip->BmpIndex = 0;
|
||||||
bmpIndexOutOfBounds = true;
|
bmpIndexOutOfBounds = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
timer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bmpIndexOutOfBounds)
|
if (bmpIndexOutOfBounds)
|
||||||
|
{
|
||||||
flip->MessageField = 0;
|
flip->MessageField = 0;
|
||||||
|
flip->Timer = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
timer = timer::set(flip->TimerTime, flip, TimerExpired);
|
{
|
||||||
flip->Timer = timer;
|
flip->Timer = timer::set(flip->TimerTime, flip, TimerExpired);
|
||||||
|
}
|
||||||
|
|
||||||
auto bmp = flip->ListBitmap->at(flip->BmpIndex);
|
auto bmp = flip->ListBitmap->at(flip->BmpIndex);
|
||||||
auto zMap = flip->ListZMap->at(flip->BmpIndex);
|
auto zMap = flip->ListZMap->at(flip->BmpIndex);
|
||||||
|
@ -19,8 +19,8 @@ public:
|
|||||||
int BmpIndex;
|
int BmpIndex;
|
||||||
TFlipperEdge* FlipperEdge;
|
TFlipperEdge* FlipperEdge;
|
||||||
int Timer;
|
int Timer;
|
||||||
float BmpCoef1{};
|
float ExtendAnimationFrameTime{};
|
||||||
float BmpCoef2{};
|
float RetractAnimationFrameTime{};
|
||||||
float TimerTime{};
|
float TimerTime{};
|
||||||
float InputTime;
|
float InputTime;
|
||||||
};
|
};
|
||||||
|
@ -12,15 +12,15 @@ line_type TFlipperEdge::lineA, TFlipperEdge::lineB;
|
|||||||
circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
|
circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
|
||||||
|
|
||||||
TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
||||||
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2,
|
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float extendTime, float retractTime,
|
||||||
float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup)
|
float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, activeFlag, collisionGroup)
|
||||||
{
|
{
|
||||||
vector_type crossProd{}, vecDir1{}, vecDir2{};
|
vector_type crossProd{}, vecDir1{}, vecDir2{};
|
||||||
|
|
||||||
Elasticity = elasticity;
|
Elasticity = elasticity;
|
||||||
Smoothness = smoothness;
|
Smoothness = smoothness;
|
||||||
BmpCoef1 = bmpCoef1;
|
ExtendTime = extendTime;
|
||||||
BmpCoef2 = bmpCoef2;
|
RetractTime = retractTime;
|
||||||
CollisionMult = collMult;
|
CollisionMult = collMult;
|
||||||
|
|
||||||
T1Src = *vecT1;
|
T1Src = *vecT1;
|
||||||
@ -78,9 +78,9 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||||||
auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z;
|
auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z;
|
||||||
DistanceDivSq = distance1 * distance1;
|
DistanceDivSq = distance1 * distance1;
|
||||||
|
|
||||||
float bmpCoef = std::min(BmpCoef1, BmpCoef2);
|
float minMoveTime = std::min(ExtendTime, RetractTime);
|
||||||
auto distance = maths::Distance(vecT1, vecT2);
|
auto distance = maths::Distance(vecT1, vecT2);
|
||||||
CollisionTimeAdvance = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius);
|
CollisionTimeAdvance = minMoveTime / (distance / CircleT1Radius + distance / CircleT1Radius);
|
||||||
|
|
||||||
TFlipperEdge::place_in_grid();
|
TFlipperEdge::place_in_grid();
|
||||||
EdgeCollisionFlag = 0;
|
EdgeCollisionFlag = 0;
|
||||||
@ -469,12 +469,12 @@ void TFlipperEdge::SetMotion(int code, float value)
|
|||||||
case 1:
|
case 1:
|
||||||
Angle2 = flipper_angle(value);
|
Angle2 = flipper_angle(value);
|
||||||
Angle1 = AngleMax;
|
Angle1 = AngleMax;
|
||||||
AngleMult = BmpCoef1;
|
AngleMult = ExtendTime;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
Angle2 = flipper_angle(value);
|
Angle2 = flipper_angle(value);
|
||||||
Angle1 = 0.0;
|
Angle1 = 0.0;
|
||||||
AngleMult = BmpCoef2;
|
AngleMult = RetractTime;
|
||||||
break;
|
break;
|
||||||
case 1024:
|
case 1024:
|
||||||
FlipperFlag = 0;
|
FlipperFlag = 0;
|
||||||
|
@ -8,7 +8,7 @@ class TFlipperEdge : public TEdgeSegment
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
||||||
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2, float collMult,
|
vector_type* origin, vector_type* vecT1, vector_type* vecT2, float extendTime, float retractTime, float collMult,
|
||||||
float elasticity, float smoothness);
|
float elasticity, float smoothness);
|
||||||
void port_draw() override;
|
void port_draw() override;
|
||||||
float FindCollisionDistance(ray_type* ray) override;
|
float FindCollisionDistance(ray_type* ray) override;
|
||||||
@ -50,8 +50,8 @@ public:
|
|||||||
float InputTime;
|
float InputTime;
|
||||||
float AngleStopTime;
|
float AngleStopTime;
|
||||||
float AngleMult;
|
float AngleMult;
|
||||||
float BmpCoef1;
|
float ExtendTime;
|
||||||
float BmpCoef2;
|
float RetractTime;
|
||||||
vector_type NextBallPosition{};
|
vector_type NextBallPosition{};
|
||||||
|
|
||||||
static float flipper_sin_angle, flipper_cos_angle;
|
static float flipper_sin_angle, flipper_cos_angle;
|
||||||
|
Loading…
Reference in New Issue
Block a user