midi ready, TCollision cleanup.

This commit is contained in:
oz 2021-01-23 13:33:30 +03:00
parent 683e823193
commit 7d15427dd9
28 changed files with 215 additions and 185 deletions

Binary file not shown.

View File

@ -17,7 +17,7 @@ TBlocker::TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(t
SoundIndex3 = visual.SoundIndex3; SoundIndex3 = visual.SoundIndex3;
TurnOnMsgValue = 55; TurnOnMsgValue = 55;
TurnOffMsgValue = 5; TurnOffMsgValue = 5;
MaxCollisionSpeed = 1000000000.0f; Threshold = 1000000000.0f;
Timer = 0; Timer = 0;
MessageField = 0; MessageField = 0;
UnknownBaseFlag2 = 0; UnknownBaseFlag2 = 0;

View File

@ -19,7 +19,7 @@ TBumper::TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(tab
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
SoundIndex4 = visual.SoundIndex4; SoundIndex4 = visual.SoundIndex4;
SoundIndex3 = visual.SoundIndex3; SoundIndex3 = visual.SoundIndex3;
MaxCollisionSpeed2 = MaxCollisionSpeed; OriginalThreshold = Threshold;
} }
int TBumper::Message(int code, float value) int TBumper::Message(int code, float value)
@ -133,7 +133,7 @@ void TBumper::TimerExpired(int timerId, void* caller)
zMap, zMap,
bmp->XPosition - bump->PinballTable->XOffset, bmp->XPosition - bump->PinballTable->XOffset,
bmp->YPosition - bump->PinballTable->YOffset); bmp->YPosition - bump->PinballTable->YOffset);
bump->MaxCollisionSpeed = bump->MaxCollisionSpeed2; bump->Threshold = bump->OriginalThreshold;
} }
void TBumper::Fire() void TBumper::Fire()
@ -148,5 +148,5 @@ void TBumper::Fire()
bmp->XPosition - PinballTable->XOffset, bmp->XPosition - PinballTable->XOffset,
bmp->YPosition - PinballTable->YOffset); bmp->YPosition - PinballTable->YOffset);
Timer = timer::set(TimerTime, this, TimerExpired); Timer = timer::set(TimerTime, this, TimerExpired);
MaxCollisionSpeed = 1000000000.0; Threshold = 1000000000.0;
} }

View File

@ -25,7 +25,7 @@ public:
int BmpIndex; int BmpIndex;
int Timer; int Timer;
float TimerTime; float TimerTime;
float MaxCollisionSpeed2; float OriginalThreshold;
int SoundIndex4; int SoundIndex4;
int SoundIndex3; int SoundIndex3;
int Scores[4]; int Scores[4];

View File

@ -31,12 +31,12 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b
} }
} }
MaxCollisionSpeed = visual.Kicker.Unknown1F; Threshold = visual.Kicker.Threshold;
UnknownC4F = visual.Unknown2F; Elasticity = visual.Elasticity;
UnknownC5F = visual.Unknown1F; Smoothness = visual.Smoothness;
CollisionMultiplier = visual.Kicker.Unknown2F; Boost = visual.Kicker.Boost;
SoundIndex1 = visual.Kicker.SoundIndex; HardHitSoundId = visual.Kicker.HardHitSoundId;
SoundIndex2 = visual.SoundIndex2; SoftHitSoundId = visual.SoftHitSoundId;
GroupIndex = groupIndex; GroupIndex = groupIndex;
} }
@ -64,23 +64,21 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* nextPosition
{ {
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
return 0; return 0;
} }
auto projSpeed = maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost);
MaxCollisionSpeed, if (projSpeed <= Threshold)
CollisionMultiplier);
if (projSpeed <= MaxCollisionSpeed)
{ {
if (projSpeed > 0.2) if (projSpeed > 0.2)
{ {
if (SoundIndex2) if (SoftHitSoundId)
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
} }
return 0; return 0;
} }
if (SoundIndex1) if (HardHitSoundId)
loader::play_sound(SoundIndex1); loader::play_sound(HardHitSoundId);
return 1; return 1;
} }
@ -91,26 +89,26 @@ void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vect
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
return; return;
} }
double projSpeed = maths::basic_collision( double projSpeed = maths::basic_collision(
ball, ball,
nextPosition, nextPosition,
direction, direction,
UnknownC4F, Elasticity,
UnknownC5F, Smoothness,
MaxCollisionSpeed, Threshold,
CollisionMultiplier); Boost);
if (projSpeed <= MaxCollisionSpeed) if (projSpeed <= Threshold)
{ {
if (projSpeed <= 0.2) if (projSpeed <= 0.2)
return; return;
soundIndex = SoundIndex2; soundIndex = SoftHitSoundId;
} }
else else
{ {
soundIndex = SoundIndex1; soundIndex = HardHitSoundId;
} }
if (soundIndex) if (soundIndex)
loader::play_sound(soundIndex); loader::play_sound(soundIndex);

View File

@ -10,14 +10,12 @@ class TCollisionComponent : public TPinballComponent
{ {
public: public:
objlist_class* EdgeList; objlist_class* EdgeList;
__int16 UnknownC2; float Elasticity;
__int16 UnknownC3; float Smoothness;
float UnknownC4F; float Boost;
float UnknownC5F; float Threshold;
float CollisionMultiplier; int SoftHitSoundId;
float MaxCollisionSpeed; int HardHitSoundId;
int SoundIndex2;
int SoundIndex1;
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall); TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
~TCollisionComponent() override; ~TCollisionComponent() override;

View File

@ -118,8 +118,8 @@ void TFlagSpinner::NextFrame()
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {
control::handler(63, this); control::handler(63, this);
if (SoundIndex2) if (SoftHitSoundId)
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
if (!BmpIndex) if (!BmpIndex)
control::handler(62, this); control::handler(62, this);
} }

View File

@ -15,11 +15,11 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
visualStruct visual{}; visualStruct visual{};
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
SoundIndex1 = visual.SoundIndex4; HardHitSoundId = visual.SoundIndex4;
SoundIndex2 = visual.SoundIndex3; SoftHitSoundId = visual.SoundIndex3;
UnknownC4F = visual.Unknown2F; Elasticity = visual.Elasticity;
Timer = 0; Timer = 0;
UnknownC5F = visual.Unknown1F; Smoothness = visual.Smoothness;
auto floatArr = loader::query_float_attribute(groupIndex, 0, 803); auto floatArr = loader::query_float_attribute(groupIndex, 0, 803);
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 805); auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 805);
@ -41,8 +41,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
bmpCoef1, bmpCoef1,
bmpCoef2, bmpCoef2,
collMult, collMult,
UnknownC4F, Elasticity,
UnknownC5F); Smoothness);
FlipperEdge = flipperEdge; FlipperEdge = flipperEdge;
if (flipperEdge) if (flipperEdge)
@ -69,12 +69,12 @@ int TFlipper::Message(int code, float value)
{ {
control::handler(1, this); control::handler(1, this);
TimerTime = BmpCoef1; TimerTime = BmpCoef1;
soundIndex = SoundIndex1; soundIndex = HardHitSoundId;
} }
else if (code == 2) else if (code == 2)
{ {
TimerTime = BmpCoef2; TimerTime = BmpCoef2;
soundIndex = SoundIndex2; soundIndex = SoftHitSoundId;
} }
else else
{ {

View File

@ -13,12 +13,12 @@ circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, TPinballTable* table, TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, 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 bmpCoef1, float bmpCoef2,
float collMult, float c4F, float c5F): TEdgeSegment(collComp, someFlag, visualFlag) float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, someFlag, visualFlag)
{ {
vector_type crossProd{}, vecDir1{}, vecDir2{}; vector_type crossProd{}, vecDir1{}, vecDir2{};
CollisionC4F = c4F; Elasticity = elasticity;
CollisionC5F = c5F; Smoothness = smoothness;
BmpCoef1 = bmpCoef1; BmpCoef1 = bmpCoef1;
BmpCoef2 = bmpCoef2; BmpCoef2 = bmpCoef2;
CollisionMult = collMult; CollisionMult = collMult;
@ -304,7 +304,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
EdgeCollisionFlag = 1; EdgeCollisionFlag = 1;
if (!FlipperFlag || !CollisionFlag2 || CollisionFlag1) if (!FlipperFlag || !CollisionFlag2 || CollisionFlag1)
{ {
float collMult = 0.0; float boost = 0.0;
if (CollisionFlag1) if (CollisionFlag1)
{ {
float dx = NextBallPosition.X - RotOrigin.X; float dx = NextBallPosition.X - RotOrigin.X;
@ -319,31 +319,31 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef)
v11 = dot1 * v20; v11 = dot1 * v20;
else else
v11 = 0.0; v11 = 0.0;
collMult = v11 * CollisionMult; boost = v11 * CollisionMult;
} }
} }
float maxSpeed = collMult <= 0.0 ? 1000000000.0f : -1.0f; float threshold = boost <= 0.0 ? 1000000000.0f : -1.0f;
maths::basic_collision( maths::basic_collision(
ball, ball,
&NextBallPosition, &NextBallPosition,
&CollisionDirection, &CollisionDirection,
CollisionC4F, Elasticity,
CollisionC5F, Smoothness,
maxSpeed, threshold,
collMult); boost);
return; return;
} }
float c4F; float elasticity;
float dx = NextBallPosition.X - RotOrigin.X; float dx = NextBallPosition.X - RotOrigin.X;
float dy = NextBallPosition.Y - RotOrigin.Y; float dy = NextBallPosition.Y - RotOrigin.Y;
float distance = dy * dy + dx * dx; float distance = dy * dy + dx * dx;
if (circlebase.RadiusSq * 1.01 < distance) if (circlebase.RadiusSq * 1.01 < distance)
c4F = (1.0f - sqrt(distance / DistanceDivSq)) * CollisionC4F; elasticity = (1.0f - sqrt(distance / DistanceDivSq)) * Elasticity;
else else
c4F = CollisionC4F; elasticity = Elasticity;
maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, c4F, CollisionC5F, 1000000000.0, 0.0); maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, elasticity, Smoothness, 1000000000.0, 0.0);
} }
void TFlipperEdge::place_in_grid() void TFlipperEdge::place_in_grid()

View File

@ -9,7 +9,7 @@ class TFlipperEdge : public TEdgeSegment
public: public:
TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, TPinballTable* table, TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, 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 bmpCoef1, float bmpCoef2, float collMult,
float c4F, float c5F); float elasticity, float smoothness);
void port_draw() override; void port_draw() override;
float FindCollisionDistance(ray_type* ray) override; float FindCollisionDistance(ray_type* ray) override;
void EdgeCollision(TBall* ball, float coef) override; void EdgeCollision(TBall* ball, float coef) override;
@ -21,8 +21,8 @@ public:
void SetMotion(int code, float value); void SetMotion(int code, float value);
int FlipperFlag; int FlipperFlag;
float CollisionC4F; float Elasticity;
float CollisionC5F; float Smoothness;
vector_type RotOrigin; vector_type RotOrigin;
float CirclebaseRadius; float CirclebaseRadius;
float CircleT1Radius; float CircleT1Radius;

View File

@ -78,7 +78,7 @@ void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
if (!BallCapturedFlag) if (!BallCapturedFlag)
{ {
BallCapturedSecondStage = 0; BallCapturedSecondStage = 0;
MaxCollisionSpeed = 1000000000.0; Threshold = 1000000000.0;
BallCapturedFlag = 1; BallCapturedFlag = 1;
ball->CollisionComp = this; ball->CollisionComp = this;
ball->Position.X = Circle.Center.X; ball->Position.X = Circle.Center.X;
@ -87,7 +87,7 @@ void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
Timer = timer::set(0.5f, this, TimerExpired); Timer = timer::set(0.5f, this, TimerExpired);
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {
loader::play_sound(SoundIndex1); loader::play_sound(HardHitSoundId);
control::handler(57, this); control::handler(57, this);
} }
} }
@ -115,7 +115,7 @@ int THole::FieldEffect(TBall* ball, vector_type* vecDst)
ball->CollisionComp = nullptr; ball->CollisionComp = nullptr;
ball->Acceleration.X = 0.0; ball->Acceleration.X = 0.0;
ball->Speed = 0.0; ball->Speed = 0.0;
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
control::handler(58, this); control::handler(58, this);
} }
} }

View File

@ -17,7 +17,7 @@ TKickback::TKickback(TPinballTable* table, int groupIndex): TCollisionComponent(
ActiveFlag = 0; ActiveFlag = 0;
TimerTime = 0.69999999f; TimerTime = 0.69999999f;
TimerTime2 = 0.1f; TimerTime2 = 0.1f;
MaxCollisionSpeed = 1000000000.0f; Threshold = 1000000000.0f;
} }
int TKickback::Message(int code, float value) int TKickback::Message(int code, float value)
@ -29,7 +29,7 @@ int TKickback::Message(int code, float value)
render::sprite_set_bitmap(RenderSprite, nullptr); render::sprite_set_bitmap(RenderSprite, nullptr);
Timer = 0; Timer = 0;
ActiveFlag = 0; ActiveFlag = 0;
MaxCollisionSpeed = 1000000000.0; Threshold = 1000000000.0;
} }
return 0; return 0;
} }
@ -39,14 +39,14 @@ void TKickback::Collision(TBall* ball, vector_type* nextPosition, vector_type* d
{ {
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 0.0, maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 0.0,
CollisionMultiplier); Boost);
} }
else else
{ {
if (!ActiveFlag) if (!ActiveFlag)
{ {
MaxCollisionSpeed = 1000000000.0; Threshold = 1000000000.0;
ActiveFlag = 1; ActiveFlag = 1;
Timer = timer::set(TimerTime, this, TimerExpired); Timer = timer::set(TimerTime, this, TimerExpired);
} }
@ -61,9 +61,9 @@ void TKickback::TimerExpired(int timerId, void* caller)
if (kick->ActiveFlag) if (kick->ActiveFlag)
{ {
kick->MaxCollisionSpeed = 0.0; kick->Threshold = 0.0;
kick->Timer = timer::set(kick->TimerTime2, kick, TimerExpired); kick->Timer = timer::set(kick->TimerTime2, kick, TimerExpired);
loader::play_sound(kick->SoundIndex1); loader::play_sound(kick->HardHitSoundId);
if (kick->ListBitmap) if (kick->ListBitmap)
{ {
auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(1)); auto bmp = static_cast<gdrv_bitmap8*>(kick->ListBitmap->Get(1));

View File

@ -27,8 +27,8 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
KickFlag1 = 0; KickFlag1 = 0;
FieldMult = *loader::query_float_attribute(groupIndex, 0, 305); FieldMult = *loader::query_float_attribute(groupIndex, 0, 305);
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
SoundIndex2 = visual.SoundIndex2; SoftHitSoundId = visual.SoftHitSoundId;
SoundIndex1 = visual.Kicker.SoundIndex; HardHitSoundId = visual.Kicker.HardHitSoundId;
Circle.Center.X = *visual.FloatArr; Circle.Center.X = *visual.FloatArr;
Circle.Center.Y = visual.FloatArr[1]; Circle.Center.Y = visual.FloatArr[1];
@ -45,12 +45,10 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2]; Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
CollisionBallSetZ = loader::query_float_attribute(groupIndex, 0, 408)[2]; CollisionBallSetZ = loader::query_float_attribute(groupIndex, 0, 408)[2];
ThrowSpeedMult2 = visual.Kicker.Unknown3F * 0.01f; ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
BallAcceleration.X = visual.Kicker.Unknown4F; BallAcceleration = visual.Kicker.ThrowBallAcceleration;
BallAcceleration.Y = visual.Kicker.Unknown5F; ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
BallAcceleration.Z = visual.Kicker.Unknown6F; ThrowSpeedMult1 = visual.Kicker.Boost;
ThrowAngleMult = visual.Kicker.Unknown7F;
ThrowSpeedMult1 = visual.Kicker.Unknown2F;
circle.RadiusSq = Circle.RadiusSq; circle.RadiusSq = Circle.RadiusSq;
circle.Center.X = Circle.Center.X; circle.Center.X = Circle.Center.X;
@ -111,7 +109,7 @@ void TKickout::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
if (!KickFlag1) if (!KickFlag1)
{ {
Ball = ball; Ball = ball;
MaxCollisionSpeed = 1000000000.0; Threshold = 1000000000.0;
KickFlag1 = 1; KickFlag1 = 1;
ball->CollisionComp = this; ball->CollisionComp = this;
ball->Position.X = Circle.Center.X; ball->Position.X = Circle.Center.X;
@ -124,7 +122,7 @@ void TKickout::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
} }
else else
{ {
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
control::handler(63, this); control::handler(63, this);
} }
} }
@ -160,7 +158,7 @@ void TKickout::TimerExpired(int timerId, void* caller)
kick->ThrowSpeedMult2); kick->ThrowSpeedMult2);
kick->UnknownBaseFlag2 = 0; kick->UnknownBaseFlag2 = 0;
kick->Ball = nullptr; kick->Ball = nullptr;
loader::play_sound(kick->SoundIndex1); loader::play_sound(kick->HardHitSoundId);
} }
} }
} }

View File

@ -54,7 +54,7 @@ void TLightRollover::Collision(TBall* ball, vector_type* nextPosition, vector_ty
} }
else else
{ {
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
control::handler(63, this); control::handler(63, this);
RolloverFlag = RolloverFlag == 0; RolloverFlag = RolloverFlag == 0;
if (ListBitmap) if (ListBitmap)

View File

@ -51,26 +51,26 @@ void TOneway::Collision(TBall* ball, vector_type* nextPosition, vector_type* dir
ball->RayMaxDistance -= coef; ball->RayMaxDistance -= coef;
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {
if (SoundIndex1) if (HardHitSoundId)
loader::play_sound(SoundIndex1); loader::play_sound(HardHitSoundId);
control::handler(63, this); control::handler(63, this);
} }
} }
else if (PinballTable->TiltLockFlag) else if (PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
} }
else if (maths::basic_collision( else if (maths::basic_collision(
ball, ball,
nextPosition, nextPosition,
direction, direction,
UnknownC4F, Elasticity,
UnknownC5F, Smoothness,
MaxCollisionSpeed, Threshold,
CollisionMultiplier) > 0.2) Boost) > 0.2)
{ {
if (SoundIndex2) if (SoftHitSoundId)
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
} }
} }

View File

@ -17,16 +17,16 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t
visualStruct visual{}; visualStruct visual{};
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
CollisionMultiplier = 0.0; Boost = 0.0;
BallFeedTimer_ = 0; BallFeedTimer_ = 0;
PullbackTimer_ = 0; PullbackTimer_ = 0;
SoundIndexP1 = visual.SoundIndex4; SoundIndexP1 = visual.SoundIndex4;
SoundIndexP2 = visual.SoundIndex3; SoundIndexP2 = visual.SoundIndex3;
SoundIndex1 = visual.Kicker.SoundIndex; HardHitSoundId = visual.Kicker.HardHitSoundId;
MaxCollisionSpeed = 1000000000.0; Threshold = 1000000000.0;
MaxPullback = 100; MaxPullback = 100;
UnknownC4F = 0.5f; Elasticity = 0.5f;
UnknownC5F = 0.5f; Smoothness = 0.5f;
PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->Count() * 8.0)); PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->Count() * 8.0));
Unknown4F = 0.025f; Unknown4F = 0.025f;
float* floatArr = loader::query_float_attribute(groupIndex, 0, 601); float* floatArr = loader::query_float_attribute(groupIndex, 0, 601);
@ -38,8 +38,8 @@ void TPlunger::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
{ {
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
Message(1017, 0.0); Message(1017, 0.0);
coef = static_cast<float>(rand()) * 0.00003051850947599719f * CollisionMultiplier * 0.1f + CollisionMultiplier; coef = static_cast<float>(rand()) * 0.00003051850947599719f * Boost * 0.1f + Boost;
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, MaxCollisionSpeed, coef); maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, coef);
} }
int TPlunger::Message(int code, float value) int TPlunger::Message(int code, float value)
@ -49,9 +49,9 @@ int TPlunger::Message(int code, float value)
case 1004: case 1004:
if (!PullbackTimer_) if (!PullbackTimer_)
{ {
CollisionMultiplier = 0.0; Boost = 0.0;
MaxCollisionSpeed = 1000000000.0; Threshold = 1000000000.0;
loader::play_sound(SoundIndex1); loader::play_sound(HardHitSoundId);
PullbackTimer(0, this); PullbackTimer(0, this);
} }
return 0; return 0;
@ -59,7 +59,7 @@ int TPlunger::Message(int code, float value)
case 1009: case 1009:
case 1010: case 1010:
{ {
MaxCollisionSpeed = 0.0; Threshold = 0.0;
if (PullbackTimer_) if (PullbackTimer_)
timer::kill(PullbackTimer_); timer::kill(PullbackTimer_);
PullbackTimer_ = 0; PullbackTimer_ = 0;
@ -97,8 +97,8 @@ int TPlunger::Message(int code, float value)
control::handler(code, this); control::handler(code, this);
return 0; return 0;
case 1017: case 1017:
MaxCollisionSpeed = 0.0; Threshold = 0.0;
CollisionMultiplier = static_cast<float>(MaxPullback); Boost = static_cast<float>(MaxPullback);
timer::set(0.2f, this, PlungerReleasedTimer); timer::set(0.2f, this, PlungerReleasedTimer);
break; break;
case 1024: case 1024:
@ -106,7 +106,7 @@ int TPlunger::Message(int code, float value)
if (BallFeedTimer_) if (BallFeedTimer_)
timer::kill(BallFeedTimer_); timer::kill(BallFeedTimer_);
BallFeedTimer_ = 0; BallFeedTimer_ = 0;
MaxCollisionSpeed = 0.0; Threshold = 0.0;
if (PullbackTimer_) if (PullbackTimer_)
timer::kill(PullbackTimer_); timer::kill(PullbackTimer_);
PullbackTimer_ = 0; PullbackTimer_ = 0;
@ -140,19 +140,19 @@ void TPlunger::BallFeedTimer(int timerId, void* caller)
void TPlunger::PullbackTimer(int timerId, void* caller) void TPlunger::PullbackTimer(int timerId, void* caller)
{ {
auto plunger = static_cast<TPlunger*>(caller); auto plunger = static_cast<TPlunger*>(caller);
plunger->CollisionMultiplier += static_cast<float>(plunger->PullbackIncrement); plunger->Boost += static_cast<float>(plunger->PullbackIncrement);
if (plunger->CollisionMultiplier <= static_cast<float>(plunger->MaxPullback)) if (plunger->Boost <= static_cast<float>(plunger->MaxPullback))
{ {
plunger->PullbackTimer_ = timer::set(plunger->Unknown4F, plunger, PullbackTimer); plunger->PullbackTimer_ = timer::set(plunger->Unknown4F, plunger, PullbackTimer);
} }
else else
{ {
plunger->PullbackTimer_ = 0; plunger->PullbackTimer_ = 0;
plunger->CollisionMultiplier = static_cast<float>(plunger->MaxPullback); plunger->Boost = static_cast<float>(plunger->MaxPullback);
} }
int index = static_cast<int>(floor( int index = static_cast<int>(floor(
static_cast<float>(plunger->ListBitmap->Count() - 1) * static_cast<float>(plunger->ListBitmap->Count() - 1) *
(plunger->CollisionMultiplier / static_cast<float>(plunger->MaxPullback)))); (plunger->Boost / static_cast<float>(plunger->MaxPullback))));
auto bmp = static_cast<gdrv_bitmap8*>(plunger->ListBitmap->Get(index)); auto bmp = static_cast<gdrv_bitmap8*>(plunger->ListBitmap->Get(index));
auto zMap = static_cast<zmap_header_type*>(plunger->ListZMap->Get(index)); auto zMap = static_cast<zmap_header_type*>(plunger->ListZMap->Get(index));
render::sprite_set( render::sprite_set(
@ -166,6 +166,6 @@ void TPlunger::PullbackTimer(int timerId, void* caller)
void TPlunger::PlungerReleasedTimer(int timerId, void* caller) void TPlunger::PlungerReleasedTimer(int timerId, void* caller)
{ {
auto plunger = static_cast<TPlunger*>(caller); auto plunger = static_cast<TPlunger*>(caller);
plunger->MaxCollisionSpeed = 1000000000.0; plunger->Threshold = 1000000000.0;
plunger->CollisionMultiplier = 0.0; plunger->Boost = 0.0;
} }

View File

@ -68,19 +68,19 @@ void TPopupTarget::Collision(TBall* ball, vector_type* nextPosition, vector_type
{ {
if (this->PinballTable->TiltLockFlag) if (this->PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, this->UnknownC4F, this->UnknownC5F, 1000000000.0, 0.0); maths::basic_collision(ball, nextPosition, direction, this->Elasticity, this->Smoothness, 1000000000.0, 0.0);
} }
else if (maths::basic_collision( else if (maths::basic_collision(
ball, ball,
nextPosition, nextPosition,
direction, direction,
this->UnknownC4F, this->Elasticity,
this->UnknownC5F, this->Smoothness,
this->MaxCollisionSpeed, this->Threshold,
this->CollisionMultiplier) > this->MaxCollisionSpeed) this->Boost) > this->Threshold)
{ {
if (this->SoundIndex1) if (this->HardHitSoundId)
loader::play_sound(this->SoundIndex1); loader::play_sound(this->HardHitSoundId);
this->Message(49, 0.0); this->Message(49, 0.0);
control::handler(63, this); control::handler(63, this);
} }
@ -94,7 +94,7 @@ void TPopupTarget::TimerExpired(int timerId, void* caller)
render::sprite_set_bitmap(target->RenderSprite, static_cast<gdrv_bitmap8*>(target->ListBitmap->Get(0))); render::sprite_set_bitmap(target->RenderSprite, static_cast<gdrv_bitmap8*>(target->ListBitmap->Get(0)));
if (timerId) if (timerId)
{ {
if (target->SoundIndex2) if (target->SoftHitSoundId)
loader::play_sound(target->SoundIndex2); loader::play_sound(target->SoftHitSoundId);
} }
} }

View File

@ -189,7 +189,7 @@ void TRamp::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
{ {
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
control::handler(63, this); control::handler(63, this);
} }
} }

View File

@ -56,7 +56,7 @@ void TRollover::Collision(TBall* ball, vector_type* nextPosition, vector_type* d
} }
else else
{ {
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
control::handler(63, this); control::handler(63, this);
} }
RolloverFlag = RolloverFlag == 0; RolloverFlag = RolloverFlag == 0;

View File

@ -17,12 +17,10 @@ TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
MessageField = 0; MessageField = 0;
Timer = 0; Timer = 0;
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
BallAcceleration.X = visual.Kicker.Unknown4F; BallAcceleration = visual.Kicker.ThrowBallAcceleration;
BallAcceleration.Y = visual.Kicker.Unknown5F; ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
BallAcceleration.Z = visual.Kicker.Unknown6F; ThrowSpeedMult1 = visual.Kicker.Boost;
ThrowAngleMult = visual.Kicker.Unknown7F; ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f;
ThrowSpeedMult1 = visual.Kicker.Unknown2F;
ThrowSpeedMult2 = visual.Kicker.Unknown3F * 0.01f;
SoundIndex4 = visual.SoundIndex4; SoundIndex4 = visual.SoundIndex4;
SoundIndex3 = visual.SoundIndex3; SoundIndex3 = visual.SoundIndex3;
auto floatArr = loader::query_float_attribute(groupIndex, 0, 601); auto floatArr = loader::query_float_attribute(groupIndex, 0, 601);
@ -83,7 +81,7 @@ void TSink::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc
Timer = 0; Timer = 0;
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
} }
else else
{ {

View File

@ -33,7 +33,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
PinballTable->SoundIndex1 = visual.SoundIndex4; PinballTable->SoundIndex1 = visual.SoundIndex4;
PinballTable->SoundIndex2 = visual.SoundIndex3; PinballTable->SoundIndex2 = visual.SoundIndex3;
PinballTable->SoundIndex3 = visual.Kicker.SoundIndex; PinballTable->SoundIndex3 = visual.Kicker.HardHitSoundId;
auto tableAngleArr = loader::query_float_attribute(groupIndex, 0, 305); auto tableAngleArr = loader::query_float_attribute(groupIndex, 0, 305);
if (tableAngleArr) if (tableAngleArr)
@ -62,8 +62,8 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
table->YOffset = bmp->YPosition; table->YOffset = bmp->YPosition;
table->Width = bmp->Width; table->Width = bmp->Width;
table->Height = bmp->Height; table->Height = bmp->Height;
MaxCollisionSpeed = visual.Kicker.Unknown1F; Threshold = visual.Kicker.Threshold;
CollisionMultiplier = 15.0f; Boost = 15.0f;
auto visArrPtr = visual.FloatArr; auto visArrPtr = visual.FloatArr;
Unknown1F = min(visArrPtr[0], min(visArrPtr[2], visArrPtr[4])); Unknown1F = min(visArrPtr[0], min(visArrPtr[2], visArrPtr[4]));

View File

@ -19,7 +19,7 @@ void TTripwire::Collision(TBall* ball, vector_type* nextPosition, vector_type* d
ball->not_again(edge); ball->not_again(edge);
if (!PinballTable->TiltLockFlag) if (!PinballTable->TiltLockFlag)
{ {
loader::play_sound(SoundIndex2); loader::play_sound(SoftHitSoundId);
control::handler(63, this); control::handler(63, this);
} }
} }

View File

@ -85,12 +85,12 @@ int loader::error(int errorCode, int captionCode)
void loader::default_vsi(visualStruct* visual) void loader::default_vsi(visualStruct* visual)
{ {
visual->Flag = 0; visual->Flag = 0;
visual->Kicker.Unknown1F = 8.9999999e10f; visual->Kicker.Threshold = 8.9999999e10f;
visual->Kicker.SoundIndex = 0; visual->Kicker.HardHitSoundId = 0;
visual->Unknown1F = 0.94999999f; visual->Smoothness = 0.94999999f;
visual->Unknown2F = 0.60000002f; visual->Elasticity = 0.60000002f;
visual->FloatArrCount = 0; visual->FloatArrCount = 0;
visual->SoundIndex2 = 0; visual->SoftHitSoundId = 0;
visual->Bitmap = 0; visual->Bitmap = 0;
visual->ZMap = 0; visual->ZMap = 0;
visual->SoundIndex3 = 0; visual->SoundIndex3 = 0;
@ -301,13 +301,13 @@ int loader::material(int groupIndex, visualStruct* visual)
switch (static_cast<int>(floor(*floatArr))) switch (static_cast<int>(floor(*floatArr)))
{ {
case 301: case 301:
visual->Unknown1F = *nextFloatVal; visual->Smoothness = *nextFloatVal;
break; break;
case 302: case 302:
visual->Unknown2F = *nextFloatVal; visual->Elasticity = *nextFloatVal;
break; break;
case 304: case 304:
visual->SoundIndex2 = get_sound_id((int)floor(*nextFloatVal)); visual->SoftHitSoundId = get_sound_id((int)floor(*nextFloatVal));
break; break;
default: default:
return error(9, 21); return error(9, 21);
@ -379,25 +379,24 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker)
switch (floorVal) switch (floorVal)
{ {
case 401: case 401:
kicker->Unknown1F = *floatArr; kicker->Threshold = *floatArr;
break; break;
case 402: case 402:
kicker->Unknown2F = *floatArr; kicker->Boost = *floatArr;
break; break;
case 403: case 403:
kicker->Unknown3F = *floatArr; kicker->ThrowBallMult = *floatArr;
break; break;
case 404: case 404:
kicker->Unknown4F = *floatArr++; kicker->ThrowBallAcceleration = *reinterpret_cast<vector_type*>(floatArr);
kicker->Unknown5F = *floatArr++; floatArr += 3;
kicker->Unknown6F = *floatArr++;
index += 4; index += 4;
break; break;
case 405: case 405:
kicker->Unknown7F = *floatArr; kicker->ThrowBallAngleMult = *floatArr;
break; break;
case 406: case 406:
kicker->SoundIndex = get_sound_id(static_cast<int>(floor(*floatArr))); kicker->HardHitSoundId = get_sound_id(static_cast<int>(floor(*floatArr)));
break; break;
default: default:
return error(10, 20); return error(10, 20);
@ -472,7 +471,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
{ {
if (shortVal == 406) if (shortVal == 406)
{ {
visual2->Kicker.SoundIndex = get_sound_id(*nextShortVal); visual2->Kicker.HardHitSoundId = get_sound_id(*nextShortVal);
} }
else else
{ {
@ -492,7 +491,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
} }
else else
{ {
visual2->SoundIndex2 = get_sound_id(*nextShortVal); visual2->SoftHitSoundId = get_sound_id(*nextShortVal);
} }
} }
else if (material(*nextShortVal, visual2)) else if (material(*nextShortVal, visual2))

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "gdrv.h" #include "gdrv.h"
#include "maths.h"
#include "zdrv.h" #include "zdrv.h"
@ -22,24 +23,22 @@ struct soundListStruct
struct __declspec(align(4)) visualKickerStruct struct __declspec(align(4)) visualKickerStruct
{ {
float Unknown1F; float Threshold;
float Unknown2F; float Boost;
float Unknown3F; float ThrowBallMult;
float Unknown4F; vector_type ThrowBallAcceleration;
float Unknown5F; float ThrowBallAngleMult;
float Unknown6F; int HardHitSoundId;
float Unknown7F;
int SoundIndex;
}; };
struct __declspec(align(4)) visualStruct struct __declspec(align(4)) visualStruct
{ {
float Unknown1F; float Smoothness;
float Unknown2F; float Elasticity;
int FloatArrCount; int FloatArrCount;
float* FloatArr; float* FloatArr;
int SoundIndex2; int SoftHitSoundId;
visualKickerStruct Kicker; visualKickerStruct Kicker;
int Flag; int Flag;
int SoundIndex4; int SoundIndex4;

View File

@ -269,9 +269,8 @@ void maths::vector_add(vector_type* vec1Dst, vector_type* vec2)
vec1Dst->Y += vec2->Y; vec1Dst->Y += vec2->Y;
} }
float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float elasticity, float smoothness,
float maxSpeed, float threshold, float boost)
float multiplier)
{ {
ball->Position.X = nextPosition->X; ball->Position.X = nextPosition->X;
ball->Position.Y = nextPosition->Y; ball->Position.Y = nextPosition->Y;
@ -284,19 +283,17 @@ float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type
{ {
float dx1 = proj * direction->X; float dx1 = proj * direction->X;
float dy1 = proj * direction->Y; float dy1 = proj * direction->Y;
float v17 = dx1 + ball->Acceleration.X; ball->Acceleration.X = (dx1 + ball->Acceleration.X) * smoothness + dx1 * elasticity;
float v18 = dy1 + ball->Acceleration.Y; ball->Acceleration.Y = (dy1 + ball->Acceleration.Y) * smoothness + dy1 * elasticity;
ball->Acceleration.X = v17 * a5 + dx1 * a4;
ball->Acceleration.Y = v18 * a5 + dy1 * a4;
normalize_2d(&ball->Acceleration); normalize_2d(&ball->Acceleration);
} }
float projSpeed = proj * ball->Speed; float projSpeed = proj * ball->Speed;
float newSpeed = ball->Speed - (1.0f - a4) * projSpeed; float newSpeed = ball->Speed - (1.0f - elasticity) * projSpeed;
ball->Speed = newSpeed; ball->Speed = newSpeed;
if (projSpeed >= maxSpeed) if (projSpeed >= threshold)
{ {
ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * multiplier; ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * boost;
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * multiplier; ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * boost;
ball->Speed = normalize_2d(&ball->Acceleration); ball->Speed = normalize_2d(&ball->Acceleration);
} }
return projSpeed; return projSpeed;

View File

@ -84,8 +84,8 @@ public:
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec); static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
static float magnitude(vector_type* vec); static float magnitude(vector_type* vec);
static void vector_add(vector_type* vec1Dst, vector_type* vec2); static void vector_add(vector_type* vec1Dst, vector_type* vec2);
static float basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, static float basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float elasticity, float smoothness,
float maxSpeed, float multiplier); float threshold, float boost);
static float Distance_Squared(vector_type vec1, vector_type vec2); static float Distance_Squared(vector_type vec1, vector_type vec2);
static float DotProduct(vector_type* vec1, vector_type* vec2); static float DotProduct(vector_type* vec1, vector_type* vec2);
static void vswap(vector_type* vec1, vector_type* vec2); static void vswap(vector_type* vec1, vector_type* vec2);

View File

@ -1,27 +1,64 @@
#include "pch.h" #include "pch.h"
#include "midi.h" #include "midi.h"
#include "pinball.h"
tagMCI_OPEN_PARMSA midi::mci_open_info;
char midi::midi_device_type[28];
HWND midi::midi_notify_hwnd;
int midi::midi_seq1_open, midi::midi_seq1_playing;
MCIERROR midi::play_pb_theme(int flag) MCIERROR midi::play_pb_theme(int flag)
{ {
return MCIERROR(); MCI_PLAY_PARMS playParams;
MCIERROR result = 0;
music_stop();
playParams.dwFrom = 0;
playParams.dwCallback = (DWORD_PTR)midi_notify_hwnd;
if (!flag && midi_seq1_open)
{
result = mciSendCommandA(mci_open_info.wDeviceID, MCI_PLAY, MCI_FROM | MCI_NOTIFY, (DWORD_PTR)&playParams);
midi_seq1_playing = result == 0;
}
return result;
} }
MCIERROR midi::music_stop() MCIERROR midi::music_stop()
{ {
return MCIERROR(); MCIERROR result = 0;
if (midi_seq1_playing)
result = mciSendCommandA(mci_open_info.wDeviceID, MCI_STOP, 0, 0);
return result;
} }
int midi::music_init(HWND hwnd) int midi::music_init(HWND hwnd)
{ {
return 1; mci_open_info.wDeviceID = 0;
midi_notify_hwnd = hwnd;
lstrcpyA(midi_device_type, pinball::get_rc_string(156, 0));
mci_open_info.lpstrElementName = nullptr;
mci_open_info.lpstrDeviceType = midi_device_type;
auto result = mciSendCommandA(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_NOTIFY_SUPERSEDED, (DWORD_PTR)&mci_open_info);
midi_seq1_open = result == 0;
return midi_seq1_open;
} }
MCIERROR midi::restart_midi_seq(int param) MCIERROR midi::restart_midi_seq(int param)
{ {
return MCIERROR(); MCI_PLAY_PARMS playParams;
MCIERROR result = 0;
playParams.dwFrom = 0;
playParams.dwCallback = (DWORD_PTR)midi_notify_hwnd;
if (midi_seq1_playing)
result = mciSendCommandA(mci_open_info.wDeviceID, MCI_PLAY, MCI_FROM | MCI_NOTIFY, (DWORD_PTR)&playParams);
return result;
} }
MCIERROR midi::music_shutdown() void midi::music_shutdown()
{ {
return MCIERROR(); if (midi_seq1_open)
mciSendCommandA(mci_open_info.wDeviceID, MCI_CLOSE, 0, 0);
midi_seq1_open = 0;
} }

View File

@ -6,5 +6,11 @@ public:
static MCIERROR music_stop(); static MCIERROR music_stop();
static int music_init(HWND hwnd); static int music_init(HWND hwnd);
static MCIERROR restart_midi_seq(int param); static MCIERROR restart_midi_seq(int param);
static MCIERROR music_shutdown(); static void music_shutdown();
private:
static tagMCI_OPEN_PARMSA mci_open_info;
static char midi_device_type[28];
static HWND midi_notify_hwnd;
static int midi_seq1_open, midi_seq1_playing;
}; };