From 7d15427dd9159379865bc96746af66eeb877bd9d Mon Sep 17 00:00:00 2001 From: oz Date: Sat, 23 Jan 2021 13:33:30 +0300 Subject: [PATCH] midi ready, TCollision cleanup. --- Doc/FuncStats.xlsx | Bin 39309 -> 39284 bytes SpaceCadetPinball/TBlocker.cpp | 2 +- SpaceCadetPinball/TBumper.cpp | 6 +-- SpaceCadetPinball/TBumper.h | 2 +- SpaceCadetPinball/TCollisionComponent.cpp | 44 ++++++++++--------- SpaceCadetPinball/TCollisionComponent.h | 14 +++---- SpaceCadetPinball/TFlagSpinner.cpp | 4 +- SpaceCadetPinball/TFlipper.cpp | 16 +++---- SpaceCadetPinball/TFlipperEdge.cpp | 28 ++++++------- SpaceCadetPinball/TFlipperEdge.h | 6 +-- SpaceCadetPinball/THole.cpp | 6 +-- SpaceCadetPinball/TKickback.cpp | 14 +++---- SpaceCadetPinball/TKickout.cpp | 20 ++++----- SpaceCadetPinball/TLightRollover.cpp | 2 +- SpaceCadetPinball/TOneway.cpp | 18 ++++---- SpaceCadetPinball/TPlunger.cpp | 40 +++++++++--------- SpaceCadetPinball/TPopupTarget.cpp | 18 ++++---- SpaceCadetPinball/TRamp.cpp | 2 +- SpaceCadetPinball/TRollover.cpp | 2 +- SpaceCadetPinball/TSink.cpp | 12 +++--- SpaceCadetPinball/TTableLayer.cpp | 6 +-- SpaceCadetPinball/TTripwire.cpp | 2 +- SpaceCadetPinball/loader.cpp | 35 ++++++++-------- SpaceCadetPinball/loader.h | 21 +++++----- SpaceCadetPinball/maths.cpp | 19 ++++----- SpaceCadetPinball/maths.h | 4 +- SpaceCadetPinball/midi.cpp | 49 +++++++++++++++++++--- SpaceCadetPinball/midi.h | 8 +++- 28 files changed, 215 insertions(+), 185 deletions(-) diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index c96f380de6b1b23fca78e17fb0a9649b58a88c97..44a23b53454fa99a2aeaf214ad769578023d4aad 100644 GIT binary patch delta 31140 zcmZ6wWmp{R(gm8}1oz)`J0dfEFs=iK|; zzfOJny2h(wO1o53>!boNtEFD!1M3FSox!Al0Qb9rDAZ1~$bE z8Ex+Bl7v7N%CN9S)7NuzFb<@$OE~Phgq>Bqk%>oC4YD};HkzB*-R~A_?2|Bj3C2a zWZ;c2-D#i~Z zwJBJ{wR^3;x(~+68At1zC{PsE#+e5nB9;z3Oe2#n4H~IWe!rMJnLvGpD;5L>`jn-s z_pIGm|DN5JZ{0h$rw0HKfzCvfin5hdqiU89>|E~OTKgSwHMhg*)R0bN-O`fHk0fK* znki>r1S3wWn+aCp$=OyrRtTO%Y=nm=o1cjCH@IbEkdeC26uy2qcQ;wQ&A6;#Vl?`^ zV^oDpS$TLZRZ3&hvsJpXV-m6Cutv3Z?XiAeX68LH=8o&+O9 zNE4LwqX(A8)EXc;^ zd0_4hqIsL}Og8}k1A4sJSD(&@3e`hIF@19Q8eqnVJl>YV7DV`IxPF`6vl%r!#1Tns{@kV+S)I4n>|?QXQ-dH660eQ{2>_^#s7QH`aibU+158nGK?wV-2P?9ah4d zKQ|2{s2}X%l;~jMbQfD$7h+Vwj9;P_L-O=Xk2|3^I*h&5!+MzXDuOtQ1D<#2j@pR= zo|l#90l^QCkIM5k0wt2=5YnzP%bx`POE^dTi=t-I$SbeNgFy+&V~lqhDQusOI))6 zeb$c|>y+FJq!KahuI|aCRe{)MsB@{!VQ}zc_Yr=z!JD3$iu1Ac`H`PoVa~1Nr*+8Z zKq;3QLk8Vc`rd6#FISNjr@$Z6k2kAl#pG$5Ogup8nMfmMqrVd%=kr&aqu=o1u-zpV#lJMoRdq8wH0W>xlO~0>k;{ zL~0&ze0DB}kMGxrdMa)aY3PT1HTO*#AsM1Q?*m1?KxuQzwH~QkRk0ak?Az@ku}++| zJ9nN#Hy}-=YI6w_J;W=uR>&Lp2_?E}=_iF0R2YNq2b(w(d~%Z(>v#6B6fq-1*VM80 zcD=YHNK)^^iEv7qqz^!XUFIv;2s~X_2OqisGV1nT-*+&UI2GZI9LQvuI#m%yh8b(< zf5tAgBfeZQL|`-E1z2u+%5-XIj4di%B6H;NGzY#EfVjH7Q~Xj`pq5ADUj3XIvzg?@ z_MmJJ>o8Hah?jac_IZI#+$vXeKJ$fkoDc-rChDp5s54Hx^8fq@l zBzct$Ta>@AYpE_K%Hwm{C+EJeM>y5naimrUr`Uaw4v5i^#?>e|cn#V#4jr#x&z=oY zs0-E}4vXQ&AH`E
#{TxyyZyRSz%V-K5Qx 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%0DO9G;YsPtzMwfEy`P#IhGGh; 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 delta 31198 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 - bump->PinballTable->XOffset, bmp->YPosition - bump->PinballTable->YOffset); - bump->MaxCollisionSpeed = bump->MaxCollisionSpeed2; + bump->Threshold = bump->OriginalThreshold; } void TBumper::Fire() @@ -148,5 +148,5 @@ void TBumper::Fire() bmp->XPosition - PinballTable->XOffset, bmp->YPosition - PinballTable->YOffset); Timer = timer::set(TimerTime, this, TimerExpired); - MaxCollisionSpeed = 1000000000.0; + Threshold = 1000000000.0; } diff --git a/SpaceCadetPinball/TBumper.h b/SpaceCadetPinball/TBumper.h index 7309c50..59325b2 100644 --- a/SpaceCadetPinball/TBumper.h +++ b/SpaceCadetPinball/TBumper.h @@ -25,7 +25,7 @@ public: int BmpIndex; int Timer; float TimerTime; - float MaxCollisionSpeed2; + float OriginalThreshold; int SoundIndex4; int SoundIndex3; int Scores[4]; diff --git a/SpaceCadetPinball/TCollisionComponent.cpp b/SpaceCadetPinball/TCollisionComponent.cpp index b4f2156..56febf9 100644 --- a/SpaceCadetPinball/TCollisionComponent.cpp +++ b/SpaceCadetPinball/TCollisionComponent.cpp @@ -31,12 +31,12 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b } } - MaxCollisionSpeed = visual.Kicker.Unknown1F; - UnknownC4F = visual.Unknown2F; - UnknownC5F = visual.Unknown1F; - CollisionMultiplier = visual.Kicker.Unknown2F; - SoundIndex1 = visual.Kicker.SoundIndex; - SoundIndex2 = visual.SoundIndex2; + Threshold = visual.Kicker.Threshold; + Elasticity = visual.Elasticity; + Smoothness = visual.Smoothness; + Boost = visual.Kicker.Boost; + HardHitSoundId = visual.Kicker.HardHitSoundId; + SoftHitSoundId = visual.SoftHitSoundId; GroupIndex = groupIndex; } @@ -64,23 +64,21 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* nextPosition { 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; } - auto projSpeed = maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, - MaxCollisionSpeed, - CollisionMultiplier); - if (projSpeed <= MaxCollisionSpeed) + auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost); + if (projSpeed <= Threshold) { if (projSpeed > 0.2) { - if (SoundIndex2) - loader::play_sound(SoundIndex2); + if (SoftHitSoundId) + loader::play_sound(SoftHitSoundId); } return 0; } - if (SoundIndex1) - loader::play_sound(SoundIndex1); + if (HardHitSoundId) + loader::play_sound(HardHitSoundId); return 1; } @@ -91,26 +89,26 @@ void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vect 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; } double projSpeed = maths::basic_collision( ball, nextPosition, direction, - UnknownC4F, - UnknownC5F, - MaxCollisionSpeed, - CollisionMultiplier); - if (projSpeed <= MaxCollisionSpeed) + Elasticity, + Smoothness, + Threshold, + Boost); + if (projSpeed <= Threshold) { if (projSpeed <= 0.2) return; - soundIndex = SoundIndex2; + soundIndex = SoftHitSoundId; } else { - soundIndex = SoundIndex1; + soundIndex = HardHitSoundId; } if (soundIndex) loader::play_sound(soundIndex); diff --git a/SpaceCadetPinball/TCollisionComponent.h b/SpaceCadetPinball/TCollisionComponent.h index db891ad..6a72219 100644 --- a/SpaceCadetPinball/TCollisionComponent.h +++ b/SpaceCadetPinball/TCollisionComponent.h @@ -10,14 +10,12 @@ class TCollisionComponent : public TPinballComponent { public: objlist_class* EdgeList; - __int16 UnknownC2; - __int16 UnknownC3; - float UnknownC4F; - float UnknownC5F; - float CollisionMultiplier; - float MaxCollisionSpeed; - int SoundIndex2; - int SoundIndex1; + float Elasticity; + float Smoothness; + float Boost; + float Threshold; + int SoftHitSoundId; + int HardHitSoundId; TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall); ~TCollisionComponent() override; diff --git a/SpaceCadetPinball/TFlagSpinner.cpp b/SpaceCadetPinball/TFlagSpinner.cpp index 1b51261..4754696 100644 --- a/SpaceCadetPinball/TFlagSpinner.cpp +++ b/SpaceCadetPinball/TFlagSpinner.cpp @@ -118,8 +118,8 @@ void TFlagSpinner::NextFrame() if (!PinballTable->TiltLockFlag) { control::handler(63, this); - if (SoundIndex2) - loader::play_sound(SoundIndex2); + if (SoftHitSoundId) + loader::play_sound(SoftHitSoundId); if (!BmpIndex) control::handler(62, this); } diff --git a/SpaceCadetPinball/TFlipper.cpp b/SpaceCadetPinball/TFlipper.cpp index 690892d..60bb633 100644 --- a/SpaceCadetPinball/TFlipper.cpp +++ b/SpaceCadetPinball/TFlipper.cpp @@ -15,11 +15,11 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t visualStruct visual{}; loader::query_visual(groupIndex, 0, &visual); - SoundIndex1 = visual.SoundIndex4; - SoundIndex2 = visual.SoundIndex3; - UnknownC4F = visual.Unknown2F; + HardHitSoundId = visual.SoundIndex4; + SoftHitSoundId = visual.SoundIndex3; + Elasticity = visual.Elasticity; Timer = 0; - UnknownC5F = visual.Unknown1F; + Smoothness = visual.Smoothness; auto floatArr = loader::query_float_attribute(groupIndex, 0, 803); auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 805); @@ -41,8 +41,8 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t bmpCoef1, bmpCoef2, collMult, - UnknownC4F, - UnknownC5F); + Elasticity, + Smoothness); FlipperEdge = flipperEdge; if (flipperEdge) @@ -69,12 +69,12 @@ int TFlipper::Message(int code, float value) { control::handler(1, this); TimerTime = BmpCoef1; - soundIndex = SoundIndex1; + soundIndex = HardHitSoundId; } else if (code == 2) { TimerTime = BmpCoef2; - soundIndex = SoundIndex2; + soundIndex = SoftHitSoundId; } else { diff --git a/SpaceCadetPinball/TFlipperEdge.cpp b/SpaceCadetPinball/TFlipperEdge.cpp index f15fc1f..5a9de7d 100644 --- a/SpaceCadetPinball/TFlipperEdge.cpp +++ b/SpaceCadetPinball/TFlipperEdge.cpp @@ -13,12 +13,12 @@ circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1; TFlipperEdge::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, float c4F, float c5F): TEdgeSegment(collComp, someFlag, visualFlag) + float collMult, float elasticity, float smoothness): TEdgeSegment(collComp, someFlag, visualFlag) { vector_type crossProd{}, vecDir1{}, vecDir2{}; - CollisionC4F = c4F; - CollisionC5F = c5F; + Elasticity = elasticity; + Smoothness = smoothness; BmpCoef1 = bmpCoef1; BmpCoef2 = bmpCoef2; CollisionMult = collMult; @@ -304,7 +304,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef) EdgeCollisionFlag = 1; if (!FlipperFlag || !CollisionFlag2 || CollisionFlag1) { - float collMult = 0.0; + float boost = 0.0; if (CollisionFlag1) { float dx = NextBallPosition.X - RotOrigin.X; @@ -319,31 +319,31 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef) v11 = dot1 * v20; else 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( ball, &NextBallPosition, &CollisionDirection, - CollisionC4F, - CollisionC5F, - maxSpeed, - collMult); + Elasticity, + Smoothness, + threshold, + boost); return; } - float c4F; + float elasticity; float dx = NextBallPosition.X - RotOrigin.X; float dy = NextBallPosition.Y - RotOrigin.Y; float distance = dy * dy + dx * dx; if (circlebase.RadiusSq * 1.01 < distance) - c4F = (1.0f - sqrt(distance / DistanceDivSq)) * CollisionC4F; + elasticity = (1.0f - sqrt(distance / DistanceDivSq)) * Elasticity; else - c4F = CollisionC4F; - maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, c4F, CollisionC5F, 1000000000.0, 0.0); + elasticity = Elasticity; + maths::basic_collision(ball, &NextBallPosition, &CollisionDirection, elasticity, Smoothness, 1000000000.0, 0.0); } void TFlipperEdge::place_in_grid() diff --git a/SpaceCadetPinball/TFlipperEdge.h b/SpaceCadetPinball/TFlipperEdge.h index 3d6dc69..0a62025 100644 --- a/SpaceCadetPinball/TFlipperEdge.h +++ b/SpaceCadetPinball/TFlipperEdge.h @@ -9,7 +9,7 @@ class TFlipperEdge : public TEdgeSegment public: 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, - float c4F, float c5F); + float elasticity, float smoothness); void port_draw() override; float FindCollisionDistance(ray_type* ray) override; void EdgeCollision(TBall* ball, float coef) override; @@ -21,8 +21,8 @@ public: void SetMotion(int code, float value); int FlipperFlag; - float CollisionC4F; - float CollisionC5F; + float Elasticity; + float Smoothness; vector_type RotOrigin; float CirclebaseRadius; float CircleT1Radius; diff --git a/SpaceCadetPinball/THole.cpp b/SpaceCadetPinball/THole.cpp index c2b7c7e..493d23b 100644 --- a/SpaceCadetPinball/THole.cpp +++ b/SpaceCadetPinball/THole.cpp @@ -78,7 +78,7 @@ void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc if (!BallCapturedFlag) { BallCapturedSecondStage = 0; - MaxCollisionSpeed = 1000000000.0; + Threshold = 1000000000.0; BallCapturedFlag = 1; ball->CollisionComp = this; 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); if (!PinballTable->TiltLockFlag) { - loader::play_sound(SoundIndex1); + loader::play_sound(HardHitSoundId); control::handler(57, this); } } @@ -115,7 +115,7 @@ int THole::FieldEffect(TBall* ball, vector_type* vecDst) ball->CollisionComp = nullptr; ball->Acceleration.X = 0.0; ball->Speed = 0.0; - loader::play_sound(SoundIndex2); + loader::play_sound(SoftHitSoundId); control::handler(58, this); } } diff --git a/SpaceCadetPinball/TKickback.cpp b/SpaceCadetPinball/TKickback.cpp index d422244..c83bf9b 100644 --- a/SpaceCadetPinball/TKickback.cpp +++ b/SpaceCadetPinball/TKickback.cpp @@ -17,7 +17,7 @@ TKickback::TKickback(TPinballTable* table, int groupIndex): TCollisionComponent( ActiveFlag = 0; TimerTime = 0.69999999f; TimerTime2 = 0.1f; - MaxCollisionSpeed = 1000000000.0f; + Threshold = 1000000000.0f; } int TKickback::Message(int code, float value) @@ -29,7 +29,7 @@ int TKickback::Message(int code, float value) render::sprite_set_bitmap(RenderSprite, nullptr); Timer = 0; ActiveFlag = 0; - MaxCollisionSpeed = 1000000000.0; + Threshold = 1000000000.0; } return 0; } @@ -39,14 +39,14 @@ void TKickback::Collision(TBall* ball, vector_type* nextPosition, vector_type* d { if (PinballTable->TiltLockFlag) { - maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 0.0, - CollisionMultiplier); + maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 0.0, + Boost); } else { if (!ActiveFlag) { - MaxCollisionSpeed = 1000000000.0; + Threshold = 1000000000.0; ActiveFlag = 1; Timer = timer::set(TimerTime, this, TimerExpired); } @@ -61,9 +61,9 @@ void TKickback::TimerExpired(int timerId, void* caller) if (kick->ActiveFlag) { - kick->MaxCollisionSpeed = 0.0; + kick->Threshold = 0.0; kick->Timer = timer::set(kick->TimerTime2, kick, TimerExpired); - loader::play_sound(kick->SoundIndex1); + loader::play_sound(kick->HardHitSoundId); if (kick->ListBitmap) { auto bmp = static_cast(kick->ListBitmap->Get(1)); diff --git a/SpaceCadetPinball/TKickout.cpp b/SpaceCadetPinball/TKickout.cpp index 5ae378c..1ce63bd 100644 --- a/SpaceCadetPinball/TKickout.cpp +++ b/SpaceCadetPinball/TKickout.cpp @@ -27,8 +27,8 @@ TKickout::TKickout(TPinballTable* table, int groupIndex, bool someFlag): TCollis KickFlag1 = 0; FieldMult = *loader::query_float_attribute(groupIndex, 0, 305); loader::query_visual(groupIndex, 0, &visual); - SoundIndex2 = visual.SoundIndex2; - SoundIndex1 = visual.Kicker.SoundIndex; + SoftHitSoundId = visual.SoftHitSoundId; + HardHitSoundId = visual.Kicker.HardHitSoundId; Circle.Center.X = *visual.FloatArr; 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]; CollisionBallSetZ = loader::query_float_attribute(groupIndex, 0, 408)[2]; - ThrowSpeedMult2 = visual.Kicker.Unknown3F * 0.01f; - BallAcceleration.X = visual.Kicker.Unknown4F; - BallAcceleration.Y = visual.Kicker.Unknown5F; - BallAcceleration.Z = visual.Kicker.Unknown6F; - ThrowAngleMult = visual.Kicker.Unknown7F; - ThrowSpeedMult1 = visual.Kicker.Unknown2F; + ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f; + BallAcceleration = visual.Kicker.ThrowBallAcceleration; + ThrowAngleMult = visual.Kicker.ThrowBallAngleMult; + ThrowSpeedMult1 = visual.Kicker.Boost; circle.RadiusSq = Circle.RadiusSq; circle.Center.X = Circle.Center.X; @@ -111,7 +109,7 @@ void TKickout::Collision(TBall* ball, vector_type* nextPosition, vector_type* di if (!KickFlag1) { Ball = ball; - MaxCollisionSpeed = 1000000000.0; + Threshold = 1000000000.0; KickFlag1 = 1; ball->CollisionComp = this; ball->Position.X = Circle.Center.X; @@ -124,7 +122,7 @@ void TKickout::Collision(TBall* ball, vector_type* nextPosition, vector_type* di } else { - loader::play_sound(SoundIndex2); + loader::play_sound(SoftHitSoundId); control::handler(63, this); } } @@ -160,7 +158,7 @@ void TKickout::TimerExpired(int timerId, void* caller) kick->ThrowSpeedMult2); kick->UnknownBaseFlag2 = 0; kick->Ball = nullptr; - loader::play_sound(kick->SoundIndex1); + loader::play_sound(kick->HardHitSoundId); } } } diff --git a/SpaceCadetPinball/TLightRollover.cpp b/SpaceCadetPinball/TLightRollover.cpp index 1b2cbe9..b7eee76 100644 --- a/SpaceCadetPinball/TLightRollover.cpp +++ b/SpaceCadetPinball/TLightRollover.cpp @@ -54,7 +54,7 @@ void TLightRollover::Collision(TBall* ball, vector_type* nextPosition, vector_ty } else { - loader::play_sound(SoundIndex2); + loader::play_sound(SoftHitSoundId); control::handler(63, this); RolloverFlag = RolloverFlag == 0; if (ListBitmap) diff --git a/SpaceCadetPinball/TOneway.cpp b/SpaceCadetPinball/TOneway.cpp index 5454756..17c4269 100644 --- a/SpaceCadetPinball/TOneway.cpp +++ b/SpaceCadetPinball/TOneway.cpp @@ -51,26 +51,26 @@ void TOneway::Collision(TBall* ball, vector_type* nextPosition, vector_type* dir ball->RayMaxDistance -= coef; if (!PinballTable->TiltLockFlag) { - if (SoundIndex1) - loader::play_sound(SoundIndex1); + if (HardHitSoundId) + loader::play_sound(HardHitSoundId); control::handler(63, this); } } 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( ball, nextPosition, direction, - UnknownC4F, - UnknownC5F, - MaxCollisionSpeed, - CollisionMultiplier) > 0.2) + Elasticity, + Smoothness, + Threshold, + Boost) > 0.2) { - if (SoundIndex2) - loader::play_sound(SoundIndex2); + if (SoftHitSoundId) + loader::play_sound(SoftHitSoundId); } } diff --git a/SpaceCadetPinball/TPlunger.cpp b/SpaceCadetPinball/TPlunger.cpp index 0c5e98b..edf095d 100644 --- a/SpaceCadetPinball/TPlunger.cpp +++ b/SpaceCadetPinball/TPlunger.cpp @@ -17,16 +17,16 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t visualStruct visual{}; loader::query_visual(groupIndex, 0, &visual); - CollisionMultiplier = 0.0; + Boost = 0.0; BallFeedTimer_ = 0; PullbackTimer_ = 0; SoundIndexP1 = visual.SoundIndex4; SoundIndexP2 = visual.SoundIndex3; - SoundIndex1 = visual.Kicker.SoundIndex; - MaxCollisionSpeed = 1000000000.0; + HardHitSoundId = visual.Kicker.HardHitSoundId; + Threshold = 1000000000.0; MaxPullback = 100; - UnknownC4F = 0.5f; - UnknownC5F = 0.5f; + Elasticity = 0.5f; + Smoothness = 0.5f; PullbackIncrement = static_cast(100.0 / (ListBitmap->Count() * 8.0)); Unknown4F = 0.025f; 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) Message(1017, 0.0); - coef = static_cast(rand()) * 0.00003051850947599719f * CollisionMultiplier * 0.1f + CollisionMultiplier; - maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, MaxCollisionSpeed, coef); + coef = static_cast(rand()) * 0.00003051850947599719f * Boost * 0.1f + Boost; + maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, coef); } int TPlunger::Message(int code, float value) @@ -49,9 +49,9 @@ int TPlunger::Message(int code, float value) case 1004: if (!PullbackTimer_) { - CollisionMultiplier = 0.0; - MaxCollisionSpeed = 1000000000.0; - loader::play_sound(SoundIndex1); + Boost = 0.0; + Threshold = 1000000000.0; + loader::play_sound(HardHitSoundId); PullbackTimer(0, this); } return 0; @@ -59,7 +59,7 @@ int TPlunger::Message(int code, float value) case 1009: case 1010: { - MaxCollisionSpeed = 0.0; + Threshold = 0.0; if (PullbackTimer_) timer::kill(PullbackTimer_); PullbackTimer_ = 0; @@ -97,8 +97,8 @@ int TPlunger::Message(int code, float value) control::handler(code, this); return 0; case 1017: - MaxCollisionSpeed = 0.0; - CollisionMultiplier = static_cast(MaxPullback); + Threshold = 0.0; + Boost = static_cast(MaxPullback); timer::set(0.2f, this, PlungerReleasedTimer); break; case 1024: @@ -106,7 +106,7 @@ int TPlunger::Message(int code, float value) if (BallFeedTimer_) timer::kill(BallFeedTimer_); BallFeedTimer_ = 0; - MaxCollisionSpeed = 0.0; + Threshold = 0.0; if (PullbackTimer_) timer::kill(PullbackTimer_); PullbackTimer_ = 0; @@ -140,19 +140,19 @@ void TPlunger::BallFeedTimer(int timerId, void* caller) void TPlunger::PullbackTimer(int timerId, void* caller) { auto plunger = static_cast(caller); - plunger->CollisionMultiplier += static_cast(plunger->PullbackIncrement); - if (plunger->CollisionMultiplier <= static_cast(plunger->MaxPullback)) + plunger->Boost += static_cast(plunger->PullbackIncrement); + if (plunger->Boost <= static_cast(plunger->MaxPullback)) { plunger->PullbackTimer_ = timer::set(plunger->Unknown4F, plunger, PullbackTimer); } else { plunger->PullbackTimer_ = 0; - plunger->CollisionMultiplier = static_cast(plunger->MaxPullback); + plunger->Boost = static_cast(plunger->MaxPullback); } int index = static_cast(floor( static_cast(plunger->ListBitmap->Count() - 1) * - (plunger->CollisionMultiplier / static_cast(plunger->MaxPullback)))); + (plunger->Boost / static_cast(plunger->MaxPullback)))); auto bmp = static_cast(plunger->ListBitmap->Get(index)); auto zMap = static_cast(plunger->ListZMap->Get(index)); render::sprite_set( @@ -166,6 +166,6 @@ void TPlunger::PullbackTimer(int timerId, void* caller) void TPlunger::PlungerReleasedTimer(int timerId, void* caller) { auto plunger = static_cast(caller); - plunger->MaxCollisionSpeed = 1000000000.0; - plunger->CollisionMultiplier = 0.0; + plunger->Threshold = 1000000000.0; + plunger->Boost = 0.0; } diff --git a/SpaceCadetPinball/TPopupTarget.cpp b/SpaceCadetPinball/TPopupTarget.cpp index 5f5cc57..e8bf520 100644 --- a/SpaceCadetPinball/TPopupTarget.cpp +++ b/SpaceCadetPinball/TPopupTarget.cpp @@ -68,19 +68,19 @@ void TPopupTarget::Collision(TBall* ball, vector_type* nextPosition, vector_type { 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( ball, nextPosition, direction, - this->UnknownC4F, - this->UnknownC5F, - this->MaxCollisionSpeed, - this->CollisionMultiplier) > this->MaxCollisionSpeed) + this->Elasticity, + this->Smoothness, + this->Threshold, + this->Boost) > this->Threshold) { - if (this->SoundIndex1) - loader::play_sound(this->SoundIndex1); + if (this->HardHitSoundId) + loader::play_sound(this->HardHitSoundId); this->Message(49, 0.0); control::handler(63, this); } @@ -94,7 +94,7 @@ void TPopupTarget::TimerExpired(int timerId, void* caller) render::sprite_set_bitmap(target->RenderSprite, static_cast(target->ListBitmap->Get(0))); if (timerId) { - if (target->SoundIndex2) - loader::play_sound(target->SoundIndex2); + if (target->SoftHitSoundId) + loader::play_sound(target->SoftHitSoundId); } } diff --git a/SpaceCadetPinball/TRamp.cpp b/SpaceCadetPinball/TRamp.cpp index b24a2d4..eb9be82 100644 --- a/SpaceCadetPinball/TRamp.cpp +++ b/SpaceCadetPinball/TRamp.cpp @@ -189,7 +189,7 @@ void TRamp::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc { if (!PinballTable->TiltLockFlag) { - loader::play_sound(SoundIndex2); + loader::play_sound(SoftHitSoundId); control::handler(63, this); } } diff --git a/SpaceCadetPinball/TRollover.cpp b/SpaceCadetPinball/TRollover.cpp index f1f3faa..dfcd6e1 100644 --- a/SpaceCadetPinball/TRollover.cpp +++ b/SpaceCadetPinball/TRollover.cpp @@ -56,7 +56,7 @@ void TRollover::Collision(TBall* ball, vector_type* nextPosition, vector_type* d } else { - loader::play_sound(SoundIndex2); + loader::play_sound(SoftHitSoundId); control::handler(63, this); } RolloverFlag = RolloverFlag == 0; diff --git a/SpaceCadetPinball/TSink.cpp b/SpaceCadetPinball/TSink.cpp index 61a6b18..de5ba95 100644 --- a/SpaceCadetPinball/TSink.cpp +++ b/SpaceCadetPinball/TSink.cpp @@ -17,12 +17,10 @@ TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table, MessageField = 0; Timer = 0; loader::query_visual(groupIndex, 0, &visual); - BallAcceleration.X = visual.Kicker.Unknown4F; - BallAcceleration.Y = visual.Kicker.Unknown5F; - BallAcceleration.Z = visual.Kicker.Unknown6F; - ThrowAngleMult = visual.Kicker.Unknown7F; - ThrowSpeedMult1 = visual.Kicker.Unknown2F; - ThrowSpeedMult2 = visual.Kicker.Unknown3F * 0.01f; + BallAcceleration = visual.Kicker.ThrowBallAcceleration; + ThrowAngleMult = visual.Kicker.ThrowBallAngleMult; + ThrowSpeedMult1 = visual.Kicker.Boost; + ThrowSpeedMult2 = visual.Kicker.ThrowBallMult * 0.01f; SoundIndex4 = visual.SoundIndex4; SoundIndex3 = visual.SoundIndex3; 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; 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 { diff --git a/SpaceCadetPinball/TTableLayer.cpp b/SpaceCadetPinball/TTableLayer.cpp index ce0b8ff..9d78fae 100644 --- a/SpaceCadetPinball/TTableLayer.cpp +++ b/SpaceCadetPinball/TTableLayer.cpp @@ -33,7 +33,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f PinballTable->SoundIndex1 = visual.SoundIndex4; PinballTable->SoundIndex2 = visual.SoundIndex3; - PinballTable->SoundIndex3 = visual.Kicker.SoundIndex; + PinballTable->SoundIndex3 = visual.Kicker.HardHitSoundId; auto tableAngleArr = loader::query_float_attribute(groupIndex, 0, 305); if (tableAngleArr) @@ -62,8 +62,8 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f table->YOffset = bmp->YPosition; table->Width = bmp->Width; table->Height = bmp->Height; - MaxCollisionSpeed = visual.Kicker.Unknown1F; - CollisionMultiplier = 15.0f; + Threshold = visual.Kicker.Threshold; + Boost = 15.0f; auto visArrPtr = visual.FloatArr; Unknown1F = min(visArrPtr[0], min(visArrPtr[2], visArrPtr[4])); diff --git a/SpaceCadetPinball/TTripwire.cpp b/SpaceCadetPinball/TTripwire.cpp index 0e4dfc0..46bdacc 100644 --- a/SpaceCadetPinball/TTripwire.cpp +++ b/SpaceCadetPinball/TTripwire.cpp @@ -19,7 +19,7 @@ void TTripwire::Collision(TBall* ball, vector_type* nextPosition, vector_type* d ball->not_again(edge); if (!PinballTable->TiltLockFlag) { - loader::play_sound(SoundIndex2); + loader::play_sound(SoftHitSoundId); control::handler(63, this); } } diff --git a/SpaceCadetPinball/loader.cpp b/SpaceCadetPinball/loader.cpp index fe5130a..8e0b581 100644 --- a/SpaceCadetPinball/loader.cpp +++ b/SpaceCadetPinball/loader.cpp @@ -85,12 +85,12 @@ int loader::error(int errorCode, int captionCode) void loader::default_vsi(visualStruct* visual) { visual->Flag = 0; - visual->Kicker.Unknown1F = 8.9999999e10f; - visual->Kicker.SoundIndex = 0; - visual->Unknown1F = 0.94999999f; - visual->Unknown2F = 0.60000002f; + visual->Kicker.Threshold = 8.9999999e10f; + visual->Kicker.HardHitSoundId = 0; + visual->Smoothness = 0.94999999f; + visual->Elasticity = 0.60000002f; visual->FloatArrCount = 0; - visual->SoundIndex2 = 0; + visual->SoftHitSoundId = 0; visual->Bitmap = 0; visual->ZMap = 0; visual->SoundIndex3 = 0; @@ -301,13 +301,13 @@ int loader::material(int groupIndex, visualStruct* visual) switch (static_cast(floor(*floatArr))) { case 301: - visual->Unknown1F = *nextFloatVal; + visual->Smoothness = *nextFloatVal; break; case 302: - visual->Unknown2F = *nextFloatVal; + visual->Elasticity = *nextFloatVal; break; case 304: - visual->SoundIndex2 = get_sound_id((int)floor(*nextFloatVal)); + visual->SoftHitSoundId = get_sound_id((int)floor(*nextFloatVal)); break; default: return error(9, 21); @@ -379,25 +379,24 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker) switch (floorVal) { case 401: - kicker->Unknown1F = *floatArr; + kicker->Threshold = *floatArr; break; case 402: - kicker->Unknown2F = *floatArr; + kicker->Boost = *floatArr; break; case 403: - kicker->Unknown3F = *floatArr; + kicker->ThrowBallMult = *floatArr; break; case 404: - kicker->Unknown4F = *floatArr++; - kicker->Unknown5F = *floatArr++; - kicker->Unknown6F = *floatArr++; + kicker->ThrowBallAcceleration = *reinterpret_cast(floatArr); + floatArr += 3; index += 4; break; case 405: - kicker->Unknown7F = *floatArr; + kicker->ThrowBallAngleMult = *floatArr; break; case 406: - kicker->SoundIndex = get_sound_id(static_cast(floor(*floatArr))); + kicker->HardHitSoundId = get_sound_id(static_cast(floor(*floatArr))); break; default: return error(10, 20); @@ -472,7 +471,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi { if (shortVal == 406) { - visual2->Kicker.SoundIndex = get_sound_id(*nextShortVal); + visual2->Kicker.HardHitSoundId = get_sound_id(*nextShortVal); } else { @@ -492,7 +491,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi } else { - visual2->SoundIndex2 = get_sound_id(*nextShortVal); + visual2->SoftHitSoundId = get_sound_id(*nextShortVal); } } else if (material(*nextShortVal, visual2)) diff --git a/SpaceCadetPinball/loader.h b/SpaceCadetPinball/loader.h index e7658f8..b8e6ba7 100644 --- a/SpaceCadetPinball/loader.h +++ b/SpaceCadetPinball/loader.h @@ -1,5 +1,6 @@ #pragma once #include "gdrv.h" +#include "maths.h" #include "zdrv.h" @@ -22,24 +23,22 @@ struct soundListStruct struct __declspec(align(4)) visualKickerStruct { - float Unknown1F; - float Unknown2F; - float Unknown3F; - float Unknown4F; - float Unknown5F; - float Unknown6F; - float Unknown7F; - int SoundIndex; + float Threshold; + float Boost; + float ThrowBallMult; + vector_type ThrowBallAcceleration; + float ThrowBallAngleMult; + int HardHitSoundId; }; struct __declspec(align(4)) visualStruct { - float Unknown1F; - float Unknown2F; + float Smoothness; + float Elasticity; int FloatArrCount; float* FloatArr; - int SoundIndex2; + int SoftHitSoundId; visualKickerStruct Kicker; int Flag; int SoundIndex4; diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index 43eed05..753b7cb 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -269,9 +269,8 @@ void maths::vector_add(vector_type* vec1Dst, vector_type* vec2) vec1Dst->Y += vec2->Y; } -float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, - float maxSpeed, - float multiplier) +float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float elasticity, float smoothness, + float threshold, float boost) { ball->Position.X = nextPosition->X; 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 dy1 = proj * direction->Y; - float v17 = dx1 + ball->Acceleration.X; - float v18 = dy1 + ball->Acceleration.Y; - ball->Acceleration.X = v17 * a5 + dx1 * a4; - ball->Acceleration.Y = v18 * a5 + dy1 * a4; + ball->Acceleration.X = (dx1 + ball->Acceleration.X) * smoothness + dx1 * elasticity; + ball->Acceleration.Y = (dy1 + ball->Acceleration.Y) * smoothness + dy1 * elasticity; normalize_2d(&ball->Acceleration); } float projSpeed = proj * ball->Speed; - float newSpeed = ball->Speed - (1.0f - a4) * projSpeed; + float newSpeed = ball->Speed - (1.0f - elasticity) * projSpeed; ball->Speed = newSpeed; - if (projSpeed >= maxSpeed) + if (projSpeed >= threshold) { - ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * multiplier; - ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * multiplier; + ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * boost; + ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * boost; ball->Speed = normalize_2d(&ball->Acceleration); } return projSpeed; diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index d369c03..fa9f81f 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -84,8 +84,8 @@ public: static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec); static float magnitude(vector_type* vec); 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, - float maxSpeed, float multiplier); + static float basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float elasticity, float smoothness, + float threshold, float boost); static float Distance_Squared(vector_type vec1, vector_type vec2); static float DotProduct(vector_type* vec1, vector_type* vec2); static void vswap(vector_type* vec1, vector_type* vec2); diff --git a/SpaceCadetPinball/midi.cpp b/SpaceCadetPinball/midi.cpp index 2ea232f..89f8031 100644 --- a/SpaceCadetPinball/midi.cpp +++ b/SpaceCadetPinball/midi.cpp @@ -1,27 +1,64 @@ #include "pch.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) { - 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() { - 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) { - 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) { - 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; } diff --git a/SpaceCadetPinball/midi.h b/SpaceCadetPinball/midi.h index 79a1ca1..a569593 100644 --- a/SpaceCadetPinball/midi.h +++ b/SpaceCadetPinball/midi.h @@ -6,5 +6,11 @@ public: static MCIERROR music_stop(); static int music_init(HWND hwnd); 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; };