From 61fe0410b0dcf418f544594d6d0481706f567486 Mon Sep 17 00:00:00 2001 From: oz Date: Sun, 10 Jan 2021 15:22:06 +0300 Subject: [PATCH] TFlipper, TFlipperEdge ready. --- Doc/FuncStats.xlsx | Bin 38506 -> 38552 bytes .../SpaceCadetPinball.vcxproj.filters | 4 +- SpaceCadetPinball/TFlipper.cpp | 186 +++++++ SpaceCadetPinball/TFlipper.h | 21 +- SpaceCadetPinball/TFlipperEdge.cpp | 474 +++++++++--------- SpaceCadetPinball/TFlipperEdge.h | 20 +- SpaceCadetPinball/maths.cpp | 67 ++- SpaceCadetPinball/pb.h | 4 +- 8 files changed, 510 insertions(+), 266 deletions(-) diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index 5aa3f46db4ea658cc7f4997bccfaf46def394bcc..8a91eb6afe30a460023786e7acee0ed2bd972bae 100644 GIT binary patch delta 30234 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 buM*0WM3JWxc9PVQjS?i1>CveY5Fh&=S}WHo delta 30064 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 diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters index 8a4faae..7317e0e 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters @@ -220,7 +220,7 @@ Header Files\TPinballComponent - Header Files + Header Files\TEdgeSegment @@ -408,7 +408,7 @@ Source Files\TPinballComponent - Source Files + Source Files\TEdgeSegment diff --git a/SpaceCadetPinball/TFlipper.cpp b/SpaceCadetPinball/TFlipper.cpp index d515cd4..690892d 100644 --- a/SpaceCadetPinball/TFlipper.cpp +++ b/SpaceCadetPinball/TFlipper.cpp @@ -1,2 +1,188 @@ #include "pch.h" #include "TFlipper.h" + + +#include "control.h" +#include "loader.h" +#include "pb.h" +#include "render.h" +#include "TFlipperEdge.h" +#include "timer.h" +#include "TZmapList.h" + +TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) +{ + visualStruct visual{}; + + loader::query_visual(groupIndex, 0, &visual); + SoundIndex1 = visual.SoundIndex4; + SoundIndex2 = visual.SoundIndex3; + UnknownC4F = visual.Unknown2F; + Timer = 0; + UnknownC5F = visual.Unknown1F; + + auto floatArr = loader::query_float_attribute(groupIndex, 0, 803); + auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 805); + auto floatArr3 = loader::query_float_attribute(groupIndex, 0, 804); + auto collMult = *floatArr; + auto bmpCoef2 = *floatArr2; + auto bmpCoef1 = *floatArr3; + auto vecT2 = reinterpret_cast(loader::query_float_attribute(groupIndex, 0, 802)); + auto vecT1 = reinterpret_cast(loader::query_float_attribute(groupIndex, 0, 801)); + auto origin = reinterpret_cast(loader::query_float_attribute(groupIndex, 0, 800)); + auto flipperEdge = new TFlipperEdge( + this, + &UnknownBaseFlag2, + visual.Flag, + table, + origin, + vecT1, + vecT2, + bmpCoef1, + bmpCoef2, + collMult, + UnknownC4F, + UnknownC5F); + + FlipperEdge = flipperEdge; + if (flipperEdge) + { + BmpCoef1 = flipperEdge->BmpCoef1 / static_cast(ListBitmap->Count() - 1); + BmpCoef2 = flipperEdge->BmpCoef2 / static_cast(ListBitmap->Count() - 1); + } + BmpIndex = 0; + InputTime = 0.0; +} + +TFlipper::~TFlipper() +{ + delete FlipperEdge; +} + +int TFlipper::Message(int code, float value) +{ + if (code == 1 || code == 2 || code > 1008 && code <= 1011 || code == 1022) + { + float timerTime; + int soundIndex = 0, code2 = code; + if (code == 1) + { + control::handler(1, this); + TimerTime = BmpCoef1; + soundIndex = SoundIndex1; + } + else if (code == 2) + { + TimerTime = BmpCoef2; + soundIndex = SoundIndex2; + } + else + { + code2 = 2; + TimerTime = BmpCoef2; + } + + if (soundIndex) + loader::play_sound(soundIndex); + if (Timer) + { + timer::kill(Timer); + Timer = 0; + } + if (MessageField) + { + auto v10 = value - FlipperEdge->InputTime; + timerTime = v10 - floor(v10 / TimerTime) * TimerTime; + if (timerTime < 0.0) + timerTime = 0.0; + } + else + { + timerTime = TimerTime; + } + MessageField = code2; + InputTime = value; + Timer = timer::set(timerTime, this, TimerExpired); + FlipperEdge->SetMotion(code2, value); + } + + if (code == 1020 || code == 1024) + { + if (MessageField) + { + if (Timer) + timer::kill(Timer); + BmpIndex = -1; + MessageField = 2; + TimerExpired(Timer, this); + FlipperEdge->SetMotion(code, value); + } + } + return 0; +} + +void TFlipper::port_draw() +{ + FlipperEdge->port_draw(); +} + +void TFlipper::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ +} + +void TFlipper::TimerExpired(int timerId, void* caller) +{ + auto flip = static_cast(caller); + int timer; // eax + + bool bmpIndexOutOfBounds = false; + auto bmpIndexAdvance = static_cast(floor((pb::time_now - flip->InputTime) / flip->TimerTime + 0.5f)); + int bmpCount = flip->ListBitmap->Count(); + if (bmpIndexAdvance > bmpCount) + bmpIndexAdvance = bmpCount; + if (bmpIndexAdvance < 0) + bmpIndexAdvance = 0; + + if (!bmpIndexAdvance) + bmpIndexAdvance = 1; + + if (flip->MessageField == 1) + { + flip->BmpIndex += bmpIndexAdvance; + int countSub1 = flip->ListBitmap->Count() - 1; + if (flip->BmpIndex >= countSub1) + { + flip->BmpIndex = countSub1; + bmpIndexOutOfBounds = true; + } + } + if (flip->MessageField == 2) + { + flip->BmpIndex -= bmpIndexAdvance; + timer = 0; + if (flip->BmpIndex <= 0) + { + flip->BmpIndex = 0; + bmpIndexOutOfBounds = true; + } + } + else + { + timer = 0; + } + + if (bmpIndexOutOfBounds) + flip->MessageField = 0; + else + timer = timer::set(flip->TimerTime, flip, TimerExpired); + flip->Timer = timer; + + auto bmp = static_cast(flip->ListBitmap->Get(flip->BmpIndex)); + auto zMap = static_cast(flip->ListZMap->Get(flip->BmpIndex)); + render::sprite_set( + flip->RenderSprite, + bmp, + zMap, + bmp->XPosition - flip->PinballTable->XOffset, + bmp->YPosition - flip->PinballTable->YOffset); +} diff --git a/SpaceCadetPinball/TFlipper.h b/SpaceCadetPinball/TFlipper.h index ebd59bd..1f830d2 100644 --- a/SpaceCadetPinball/TFlipper.h +++ b/SpaceCadetPinball/TFlipper.h @@ -1,11 +1,26 @@ #pragma once #include "TCollisionComponent.h" +class TFlipperEdge; + class TFlipper : public TCollisionComponent { public: - TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) - { - } + TFlipper(TPinballTable* table, int groupIndex); + ~TFlipper() override; + int Message(int code, float value) override; + void port_draw() override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + + static void TimerExpired(int timerId, void* caller); + + int BmpIndex; + TFlipperEdge* FlipperEdge; + int Timer; + float BmpCoef1; + float BmpCoef2; + float TimerTime; + float InputTime; }; diff --git a/SpaceCadetPinball/TFlipperEdge.cpp b/SpaceCadetPinball/TFlipperEdge.cpp index a32f9d9..2187f5f 100644 --- a/SpaceCadetPinball/TFlipperEdge.cpp +++ b/SpaceCadetPinball/TFlipperEdge.cpp @@ -12,8 +12,8 @@ line_type TFlipperEdge::lineA, TFlipperEdge::lineB; circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1; TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, TPinballTable* table, - vector_type* origin, vector_type* vecT, vector_type* vec3, float bmpCoef1, float bmpCoef2, - float a11, float c4F, float c5F): TEdgeSegment(collComp, someFlag, visualFlag) + vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2, + float collMult, float c4F, float c5F): TEdgeSegment(collComp, someFlag, visualFlag) { vector_type crossProd{}, vecDir1{}, vecDir2{}; @@ -21,10 +21,10 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsign CollisionC5F = c5F; BmpCoef1 = bmpCoef1; BmpCoef2 = bmpCoef2; - Unknown32F = a11; + CollisionMult = collMult; - T1Src = *vecT; - Unknown36V = *vec3; + T1Src = *vecT1; + T2Src = *vecT2; RotOrigin.X = origin->X; RotOrigin.Y = origin->Y; @@ -32,17 +32,17 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsign CirclebaseRadiusMSq = CirclebaseRadius * 1.01f * (CirclebaseRadius * 1.01f); CirclebaseRadiusSq = CirclebaseRadius * CirclebaseRadius; - CircleT1Radius = vecT->Z + table->CollisionCompOffset; + CircleT1Radius = vecT1->Z + table->CollisionCompOffset; CircleT1RadiusMSq = CircleT1Radius * 1.01f * (CircleT1Radius * 1.01f); CircleT1RadiusSq = CircleT1Radius * CircleT1Radius; - vecDir1.X = vecT->X - origin->X; - vecDir1.Y = vecT->Y - origin->Y; + vecDir1.X = vecT1->X - origin->X; + vecDir1.Y = vecT1->Y - origin->Y; vecDir1.Z = 0.0; maths::normalize_2d(&vecDir1); - vecDir2.X = vec3->X - origin->X; - vecDir2.Y = vec3->Y - origin->Y; + vecDir2.X = vecT2->X - origin->X; + vecDir2.Y = vecT2->Y - origin->Y; vecDir2.Z = 0.0; maths::normalize_2d(&vecDir2); @@ -57,15 +57,15 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsign auto dirY1 = -vecDir1.Y; A2Src.X = dirY1 * CirclebaseRadius + origin->X; A2Src.Y = dirX1 * CirclebaseRadius + origin->Y; - A1Src.X = dirY1 * CircleT1Radius + vecT->X; - A1Src.Y = dirX1 * CircleT1Radius + vecT->Y; + A1Src.X = dirY1 * CircleT1Radius + vecT1->X; + A1Src.Y = dirX1 * CircleT1Radius + vecT1->Y; dirX1 = -dirX1; dirY1 = -dirY1; B1Src.X = dirY1 * CirclebaseRadius + origin->X; B1Src.Y = dirX1 * CirclebaseRadius + origin->Y; - B2Src.X = dirY1 * CircleT1Radius + vecT->X; - B2Src.Y = dirX1 * CircleT1Radius + vecT->Y; + B2Src.X = dirY1 * CircleT1Radius + vecT1->X; + B2Src.Y = dirX1 * CircleT1Radius + vecT1->Y; if (AngleMax < 0.0) { @@ -73,261 +73,239 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsign maths::vswap(&A2Src, &B2Src); } - auto dx = vecT->X - RotOrigin.X; - auto dy = vecT->Y - RotOrigin.Y; - auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT->Z; + auto dx = vecT1->X - RotOrigin.X; + auto dy = vecT1->Y - RotOrigin.Y; + auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z; DistanceDivSq = distance1 * distance1; float bmpCoef = min(BmpCoef1, BmpCoef2); - auto distance = maths::Distance(vecT, vec3); - Unknown40F = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius); + auto distance = maths::Distance(vecT1, vecT2); + CollisionTimeAdvance = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius); TFlipperEdge::place_in_grid(); - Unknown44 = 0; - TimeAngle = 0.0; - Unknown15 = 0; - Unknown46F = 0.0; + EdgeCollisionFlag = 0; + InputTime = 0.0; + CollisionFlag1 = 0; + AngleStopTime = 0.0; AngleMult = 0.0; } void TFlipperEdge::port_draw() { - set_control_points(TimeAngle); + set_control_points(InputTime); build_edges_in_motion(); } float TFlipperEdge::FindCollisionDistance(ray_type* ray) { auto ogRay = ray; + ray_type dstRay{}, srcRay{}; - - float* pfVar2; - short uVar3; - int iVar4; - int uVar5; - vector_type* prVar6; - vector_type* plVar6; - vector_type* pvVar7; - float fVar8; - ray_type ray2; - ray_type ray1; - float local_1c; - float local_18; - float local_14; - float local_10; - float local_c; - float local_8; - - if (ogRay->TimeNow > this->Unknown46F) { - this->FlipperFlag = 0; + if (ogRay->TimeNow > AngleStopTime) + { + FlipperFlag = 0; } - if (this->Unknown44 == 0) { - if (this->FlipperFlag == 0) { - this->Unknown44 = 0; - this->Unknown15 = 0; - this->Unknown16 = 0; - set_control_points( ogRay->TimeNow); + if (EdgeCollisionFlag == 0) + { + if (FlipperFlag == 0) + { + EdgeCollisionFlag = 0; + CollisionFlag1 = 0; + CollisionFlag2 = 0; + set_control_points(ogRay->TimeNow); build_edges_in_motion(); - iVar4 = is_ball_inside( (ogRay->Origin).X, (ogRay->Origin).Y); - ray1.MinDistance = ogRay->MinDistance; - if (iVar4 == 0) { - ray1.Direction.X = (ogRay->Direction).X; - ray1.Direction.Y = (ogRay->Direction).Y; - ray1.Direction.Z = (ogRay->Direction).Z; - ray1.MaxDistance = ogRay->MaxDistance; - ray1.Origin.X = (ogRay->Origin).X; - ray1.Origin.Y = (ogRay->Origin).Y; - ray1.Origin.Z = (ogRay->Origin).Z; - fVar8 = maths::distance_to_flipper(&ray1, &ray2); - plVar6 = &ray2.Origin; - if (fVar8 == 0.0) { - pvVar7 = &this->NextBallPosition; - pvVar7->X = ray2.Origin.X; - (this->NextBallPosition).Y = ray2.Origin.Y; - (this->NextBallPosition).Z = ray2.Origin.Z; - pvVar7->X = pvVar7->X - ray1.Direction.X * 1e-05f; - pfVar2 = &(this->NextBallPosition).Y; - *pfVar2 = *pfVar2 - ray1.Direction.Y * 1e-05f; + auto ballInside = is_ball_inside(ogRay->Origin.X, ogRay->Origin.Y); + srcRay.MinDistance = ogRay->MinDistance; + if (ballInside == 0) + { + srcRay.Direction = ogRay->Direction; + srcRay.MaxDistance = ogRay->MaxDistance; + srcRay.Origin = ogRay->Origin; + auto distance = maths::distance_to_flipper(&srcRay, &dstRay); + if (distance == 0.0) + { + NextBallPosition = dstRay.Origin; + NextBallPosition.X -= srcRay.Direction.X * 1e-05f; + NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f; } - else { - pvVar7 = &this->NextBallPosition; - LAB_0101bab7: - pvVar7->X = (plVar6)->X; - pvVar7->Y = (plVar6)->Y; - pvVar7->Z = (plVar6)->Z; + else + { + NextBallPosition = dstRay.Origin; } - (this->CollisionDirection).X = ray2.Direction.X; - (this->CollisionDirection).Y = ray2.Direction.Y; - (this->CollisionDirection).Z = ray2.Direction.Z; - return fVar8; + CollisionDirection = dstRay.Direction; + return distance; } - fVar8 = maths::Distance_Squared(ogRay->Origin, this->RotOrigin); - if (this->CirclebaseRadiusMSq <= fVar8) { - fVar8 = maths::Distance_Squared(ogRay->Origin, T1); - if (this->CircleT1RadiusMSq <= fVar8) { - ray1.Direction.Y = lineB.PerpendicularL.Y; - ray1.Direction.X = lineB.PerpendicularL.X; - if (iVar4 == 4) { - ray1.Direction.Y = lineA.PerpendicularL.Y; - ray1.Direction.X = lineA.PerpendicularL.X; + + if (maths::Distance_Squared(ogRay->Origin, RotOrigin) >= CirclebaseRadiusMSq) + { + if (maths::Distance_Squared(ogRay->Origin, T1) >= CircleT1RadiusMSq) + { + srcRay.Direction.Y = lineB.PerpendicularL.Y; + srcRay.Direction.X = lineB.PerpendicularL.X; + if (ballInside == 4) + { + srcRay.Direction.Y = lineA.PerpendicularL.Y; + srcRay.Direction.X = lineA.PerpendicularL.X; } - ray1.Direction.X = -ray1.Direction.X; - ray1.Direction.Y = -ray1.Direction.Y; + srcRay.Direction.X = -srcRay.Direction.X; + srcRay.Direction.Y = -srcRay.Direction.Y; } - else { - ray1.Direction.X = T1.X - (ogRay->Origin).X; - ray1.Direction.Y = T1.Y - (ogRay->Origin).Y; - maths::normalize_2d(&ray1.Direction); + else + { + srcRay.Direction.X = T1.X - ogRay->Origin.X; + srcRay.Direction.Y = T1.Y - ogRay->Origin.Y; + maths::normalize_2d(&srcRay.Direction); } } - else { - ray1.Direction.X = (this->RotOrigin).X - (ogRay->Origin).X; - ray1.Direction.Y = (this->RotOrigin).Y - (ogRay->Origin).Y; - maths::normalize_2d(&ray1.Direction); + else + { + srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X; + srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y; + maths::normalize_2d(&srcRay.Direction); } - ray1.Origin.X = (ogRay->Origin).X - ray1.Direction.X * 5.0f; - ray1.Origin.Y = (ogRay->Origin).Y - ray1.Direction.Y * 5.0f; - ray1.MaxDistance = ogRay->MaxDistance + 10.0f; - fVar8 = maths::distance_to_flipper(&ray1, &ray2); - if (1e+09 <= fVar8) { - ray1.Direction.X = (this->RotOrigin).X - (ogRay->Origin).X; - ray1.Direction.Y = (this->RotOrigin).Y - (ogRay->Origin).Y; - maths::normalize_2d(&ray1.Direction); - ray1.Origin.X = (ogRay->Origin).X - ray1.Direction.X * 5.0f; - ray1.Origin.Y = (ogRay->Origin).Y - ray1.Direction.Y * 5.0f; - fVar8 = maths::distance_to_flipper(&ray1, &ray2); - if (1e+09 <= fVar8) { + + srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f; + srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f; + srcRay.MaxDistance = ogRay->MaxDistance + 10.0f; + if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09) + { + srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X; + srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y; + maths::normalize_2d(&srcRay.Direction); + srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f; + srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f; + if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09) + { return 1e+09; } } - LAB_0101ba1a: - (this->NextBallPosition).X = ray2.Origin.X; - (this->NextBallPosition).Y = ray2.Origin.Y; - (this->NextBallPosition).Z = ray2.Origin.Z; - pvVar7 = &this->CollisionDirection; - prVar6 = &ray2.Direction; - LAB_0101bc82: - pvVar7->X = prVar6->X; - pvVar7->Y = prVar6->Y; - pvVar7->Z = prVar6->Z; - (this->NextBallPosition).X = (this->NextBallPosition).X - ray1.Direction.X * 1e-05; - pfVar2 = &(this->NextBallPosition).Y; - *pfVar2 = *pfVar2 - ray1.Direction.Y * 1e-05; + + NextBallPosition = dstRay.Origin; + CollisionDirection = dstRay.Direction; + NextBallPosition.X -= srcRay.Direction.X * 1e-05f; + NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f; return 0.0; } - local_8 = (ogRay->Origin).X; - local_14 = this->Unknown40F * ogRay->MaxDistance; - local_c = (ogRay->Origin).Y; - local_10 = ogRay->TimeNow; - local_18 = this->Unknown40F * (ogRay->Direction).X; - local_1c = (ogRay->Direction).Y * this->Unknown40F; - fVar8 = ogRay->TimeDelta + ogRay->TimeNow; - uVar3 = fVar8 <= local_10;// fp flag shift - while (uVar3 == 0) { - set_control_points( local_10); + + auto posX = ogRay->Origin.X; + auto posY = ogRay->Origin.Y; + auto posXAdvance = ogRay->Direction.X * CollisionTimeAdvance; + auto posYAdvance = ogRay->Direction.Y * CollisionTimeAdvance; + auto rayMaxDistance = ogRay->MaxDistance * CollisionTimeAdvance; + auto timeNow = ogRay->TimeNow; + auto stopTime = ogRay->TimeDelta + ogRay->TimeNow; + while (timeNow < stopTime) + { + set_control_points(timeNow); build_edges_in_motion(); - iVar4 = is_ball_inside( local_8, local_c); - if (iVar4 != 0) { - if ((this->FlipperFlag == 1) && (iVar4 != 5)) { - plVar6 = &lineA.PerpendicularL; - ray1.Direction.Y = lineA.PerpendicularL.Y; - ray1.Direction.X = lineA.PerpendicularL.X; + auto ballInside = is_ball_inside(posX, posY); + if (ballInside != 0) + { + vector_type* linePtr; + if (FlipperFlag == 1 && ballInside != 5) + { + linePtr = &lineA.PerpendicularL; + srcRay.Direction.Y = lineA.PerpendicularL.Y; + srcRay.Direction.X = lineA.PerpendicularL.X; } - else { - if ((this->FlipperFlag != 2) || (iVar4 == 4)) { - ray1.Direction.X = (this->RotOrigin).X - local_8; - this->Unknown15 = 0; - this->Unknown16 = 1; - ray1.Direction.Y = (this->RotOrigin).Y - local_c; - maths::normalize_2d(&ray1.Direction); - ray1.Origin.X = local_8 - ray1.Direction.X * 5.0f; - ray1.Origin.Y = local_c - ray1.Direction.Y * 5.0f; - ray1.MaxDistance = ogRay->MaxDistance + 10.0f; - fVar8 = maths::distance_to_flipper(&ray1, &ray2); - if (1e+09 <= fVar8) { - (this->NextBallPosition).X = local_8; - (this->CollisionDirection).X = -ray1.Direction.X; - (this->NextBallPosition).Y = local_c; - (this->CollisionDirection).Y = -ray1.Direction.Y; + else + { + if (FlipperFlag != 2 || ballInside == 4) + { + CollisionFlag1 = 0; + CollisionFlag2 = 1; + srcRay.Direction.X = RotOrigin.X - posX; + srcRay.Direction.Y = RotOrigin.Y - posY; + maths::normalize_2d(&srcRay.Direction); + + srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f; + srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f; + srcRay.MaxDistance = ogRay->MaxDistance + 10.0f; + if (maths::distance_to_flipper(&srcRay, &dstRay) >= 1e+09) + { + NextBallPosition.X = posX; + NextBallPosition.Y = posY; + CollisionDirection.X = -srcRay.Direction.X; + CollisionDirection.Y = -srcRay.Direction.Y; return 0.0; } - goto LAB_0101ba1a; + + NextBallPosition = dstRay.Origin; + CollisionDirection = dstRay.Direction; + NextBallPosition.X -= srcRay.Direction.X * 1e-05f; + NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f; + return 0.0; } - plVar6 = &lineB.PerpendicularL; - ray1.Direction.Y = lineB.PerpendicularL.Y; - ray1.Direction.X = lineB.PerpendicularL.X; + linePtr = &lineB.PerpendicularL; + srcRay.Direction.Y = lineB.PerpendicularL.Y; + srcRay.Direction.X = lineB.PerpendicularL.X; } - ray1.Direction.X = -ray1.Direction.X; - ray1.Direction.Y = -ray1.Direction.Y; - (this->Unknown17V).X = plVar6->X; - (this->Unknown17V).Y = plVar6->Y; - (this->Unknown17V).Z = plVar6->Z; - this->Unknown16 = 0; - this->Unknown15 = 1; - ray1.MinDistance = 0.002; - ray1.Origin.X = (ogRay->Origin).X - ray1.Direction.X * 5.0f; - ray1.Origin.Y = (ogRay->Origin).Y - ray1.Direction.Y * 5.0f; - ray1.MaxDistance = ogRay->MaxDistance + 10.0f; - fVar8 = maths::distance_to_flipper(&ray1, &ray2); - (this->CollisionDirection).X = ray2.Direction.X; - (this->CollisionDirection).Y = ray2.Direction.Y; - (this->CollisionDirection).Z = ray2.Direction.Z; - if (1e+09 <= fVar8) { + + CollisionLinePerp = *linePtr; + CollisionFlag2 = 0; + CollisionFlag1 = 1; + srcRay.Direction.X = -srcRay.Direction.X; + srcRay.Direction.Y = -srcRay.Direction.Y; + srcRay.MinDistance = 0.002f; + srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f; + srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f; + srcRay.MaxDistance = ogRay->MaxDistance + 10.0f; + auto distance = maths::distance_to_flipper(&srcRay, &dstRay); + CollisionDirection = dstRay.Direction; + if (distance >= 1e+09) + { return 1e+09; } - pvVar7 = &this->NextBallPosition; - prVar6 = &ray2.Origin; - goto LAB_0101bc82; + NextBallPosition = dstRay.Origin; + NextBallPosition.X -= srcRay.Direction.X * 1e-05f; + NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f; + return 0.0; } - ray1.Direction.X = (ogRay->Direction).X; - ray1.Direction.Y = (ogRay->Direction).Y; - ray1.Direction.Z = (ogRay->Direction).Z; - ray1.MinDistance = ogRay->MinDistance; - ray1.Origin.X = (ogRay->Origin).X; - ray1.Origin.Y = (ogRay->Origin).Y; - ray1.Origin.Z = (ogRay->Origin).Z; - ray1.MaxDistance = local_14; - fVar8 = maths::distance_to_flipper(&ray1, &ray2); - if (fVar8 < 1e+09) { - pvVar7 = &this->NextBallPosition; - pvVar7->X = ray2.Origin.X; - (this->NextBallPosition).Y = ray2.Origin.Y; - (this->NextBallPosition).Z = ray2.Origin.Z; - pvVar7->X = pvVar7->X - ray1.Direction.X * 1e-05f; - pfVar2 = &(this->NextBallPosition).Y; - *pfVar2 = *pfVar2 - ray1.Direction.Y * 1e-05f; - uVar5 = this->AngleMax > 0.0; - pvVar7 = &this->Unknown17V; - if (this->FlipperFlag == 2) { - plVar6 = &lineB.PerpendicularL; - this->Unknown15 = (uVar5 == 0); + + srcRay.Direction = ogRay->Direction; + srcRay.MinDistance = ogRay->MinDistance; + srcRay.Origin = ogRay->Origin; + srcRay.MaxDistance = rayMaxDistance; + auto distance = maths::distance_to_flipper(&srcRay, &dstRay); + if (distance < 1e+09) + { + NextBallPosition = dstRay.Origin; + NextBallPosition.X -= srcRay.Direction.X * 1e-05f; + NextBallPosition.Y -= srcRay.Direction.Y * 1e-05f; + vector_type* linePtr; + if (FlipperFlag == 2) + { + linePtr = &lineB.PerpendicularL; + CollisionFlag1 = AngleMax <= 0.0; } - else { - this->Unknown15 = uVar5; - plVar6 = &lineA.PerpendicularL; + else + { + CollisionFlag1 = AngleMax > 0.0; + linePtr = &lineA.PerpendicularL; } - goto LAB_0101bab7; + CollisionLinePerp = *linePtr; + CollisionDirection = dstRay.Direction; + return distance; } - local_10 = local_10 + this->Unknown40F; - local_8 = local_8 + local_18; - local_c = local_c + local_1c; - fVar8 = ogRay->TimeDelta + ogRay->TimeNow; - uVar3 = fVar8 <= local_10; + timeNow = timeNow + CollisionTimeAdvance; + posX = posX + posXAdvance; + posY = posY + posYAdvance; } } - else { - this->Unknown44 = 0; + else + { + EdgeCollisionFlag = 0; } return 1e+09; } void TFlipperEdge::EdgeCollision(TBall* ball, float coef) { - Unknown44 = 1; - if (!FlipperFlag || !Unknown16 || Unknown15) + EdgeCollisionFlag = 1; + if (!FlipperFlag || !CollisionFlag2 || CollisionFlag1) { float collMult = 0.0; - if (Unknown15) + if (CollisionFlag1) { float dx = NextBallPosition.X - RotOrigin.X; float dy = NextBallPosition.Y - RotOrigin.Y; @@ -336,12 +314,12 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float coef) { float v11; float v20 = sqrt(distance / DistanceDivSq) * (fabs(AngleMax) / AngleMult); - float dot1 = maths::DotProduct(&Unknown17V, &CollisionDirection); + float dot1 = maths::DotProduct(&CollisionLinePerp, &CollisionDirection); if (dot1 >= 0.0) v11 = dot1 * v20; else v11 = 0.0; - collMult = v11 * Unknown32F; + collMult = v11 * CollisionMult; } } @@ -372,9 +350,9 @@ void TFlipperEdge::place_in_grid() { float x0 = RotOrigin.X - CirclebaseRadius; float y0 = RotOrigin.Y - CirclebaseRadius; - float x1 = CirclebaseRadius + RotOrigin.X; + float x1 = RotOrigin.X + CirclebaseRadius; + float y1 = RotOrigin.Y + CirclebaseRadius; - float v1 = RotOrigin.Y + CirclebaseRadius; float v2 = T1Src.X - CircleT1Radius; if (v2 < x0) x0 = v2; @@ -383,31 +361,30 @@ void TFlipperEdge::place_in_grid() if (v3 < y0) y0 = v3; - float v4 = CircleT1Radius + T1Src.X; + float v4 = T1Src.X + CircleT1Radius; if (v4 > x1) x1 = v4; float v5 = T1Src.Y + CircleT1Radius; - if (v5 > v1) - v1 = v5; + if (v5 > y1) + y1 = v5; - float v6 = Unknown36V.X - CircleT1Radius; + float v6 = T2Src.X - CircleT1Radius; if (v6 < x0) x0 = v6; - float v7 = Unknown36V.Y - CircleT1Radius; + float v7 = T2Src.Y - CircleT1Radius; if (v7 < y0) y0 = v7; - float v8 = Unknown36V.X + CircleT1Radius; + float v8 = T2Src.X + CircleT1Radius; if (v8 > x1) x1 = v8; - float v9 = CircleT1Radius + Unknown36V.Y; - if (v9 > v1) - v1 = v9; + float v9 = T2Src.Y + CircleT1Radius; + if (v9 > y1) + y1 = v9; - float y1 = v1; TTableLayer::edges_insert_square(y0, x0, y1, x1, this, nullptr); } @@ -447,7 +424,7 @@ float TFlipperEdge::flipper_angle(float timeNow) angle = -angle; if (angle >= 0.0000001) - angle = (timeNow - TimeAngle) / angle; + angle = (timeNow - InputTime) / angle; else angle = 1.0; @@ -459,7 +436,7 @@ float TFlipperEdge::flipper_angle(float timeNow) int TFlipperEdge::is_ball_inside(float x, float y) { - vector_type ptTest{}; + vector_type testPoint{}; float dx = RotOrigin.X - x; float dy = RotOrigin.Y - y; if ((A2.X - A1.X) * (y - A1.Y) - (A2.Y - A1.Y) * (x - A1.X) >= 0.0 && @@ -469,15 +446,16 @@ int TFlipperEdge::is_ball_inside(float x, float y) dy * dy + dx * dx <= CirclebaseRadiusSq || (T1.Y - y) * (T1.Y - y) + (T1.X - x) * (T1.X - x) < CircleT1RadiusSq) { + float flipperLR = AngleMax < 0.0 ? -1 : 1; if (FlipperFlag == 1) - ptTest = AngleMax < 0.0 ? B1 : B2; + testPoint = AngleMax < 0.0 ? B1 : B2; else if (FlipperFlag == 2) - ptTest = AngleMax < 0.0 ? A2 : A1; + testPoint = AngleMax < 0.0 ? A2 : A1; else - ptTest = T1; + testPoint = T1; - if ((y - ptTest.Y) * (RotOrigin.X - ptTest.X) - - (x - ptTest.X) * (RotOrigin.Y - ptTest.Y) >= 0.0f) + if (((y - testPoint.Y) * (RotOrigin.X - testPoint.X) - + (x - testPoint.X) * (RotOrigin.Y - testPoint.Y)) * flipperLR < 0.0) return 4; return 5; } @@ -489,24 +467,24 @@ void TFlipperEdge::SetMotion(int code, float value) switch (code) { case 1: - this->Angle2 = flipper_angle(value); - this->Angle1 = this->AngleMax; - this->AngleMult = this->BmpCoef1; + Angle2 = flipper_angle(value); + Angle1 = AngleMax; + AngleMult = BmpCoef1; break; case 2: - this->Angle2 = flipper_angle(value); - this->Angle1 = 0.0; - this->AngleMult = this->BmpCoef2; + Angle2 = flipper_angle(value); + Angle1 = 0.0; + AngleMult = BmpCoef2; break; case 1024: - this->FlipperFlag = 0; - this->Angle1 = 0.0; + FlipperFlag = 0; + Angle1 = 0.0; return; default: break; } - if (!this->FlipperFlag) - this->TimeAngle = value; - this->FlipperFlag = code; - this->Unknown46F = this->AngleMult + this->TimeAngle; + if (!FlipperFlag) + InputTime = value; + FlipperFlag = code; + AngleStopTime = AngleMult + InputTime; } diff --git a/SpaceCadetPinball/TFlipperEdge.h b/SpaceCadetPinball/TFlipperEdge.h index c19f366..3d6dc69 100644 --- a/SpaceCadetPinball/TFlipperEdge.h +++ b/SpaceCadetPinball/TFlipperEdge.h @@ -8,7 +8,7 @@ class TFlipperEdge : public TEdgeSegment { public: TFlipperEdge(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag, TPinballTable* table, - vector_type* origin, vector_type* vecT, vector_type* vec3, float bmpCoef1, float bmpCoef2, float a11, + vector_type* origin, vector_type* vecT1, vector_type* vecT2, float bmpCoef1, float bmpCoef2, float collMult, float c4F, float c5F); void port_draw() override; float FindCollisionDistance(ray_type* ray) override; @@ -33,22 +33,22 @@ public: float AngleMax; float Angle2; float Angle1; - int Unknown15; - int Unknown16; - vector_type Unknown17V; + int CollisionFlag1; + int CollisionFlag2; + vector_type CollisionLinePerp; vector_type A1Src; vector_type A2Src; vector_type B1Src; vector_type B2Src; - float Unknown32F; + float CollisionMult; vector_type T1Src; - vector_type Unknown36V; + vector_type T2Src; float DistanceDivSq; - float Unknown40F; + float CollisionTimeAdvance; vector_type CollisionDirection; - int Unknown44; - float TimeAngle; - float Unknown46F; + int EdgeCollisionFlag; + float InputTime; + float AngleStopTime; float AngleMult; float BmpCoef1; float BmpCoef2; diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index 0623913..9aaf441 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -2,6 +2,7 @@ #include "maths.h" #include "TBall.h" +#include "TFlipperEdge.h" void maths::enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect) @@ -341,5 +342,69 @@ void maths::RotatePt(vector_type* point, float sin, float cos, vector_type* orig float maths::distance_to_flipper(ray_type* ray1, ray_type* ray2) { - return 0; + auto distance = 1000000000.0f; + auto distanceType = -1; + auto newDistance = ray_intersect_line(ray1, &TFlipperEdge::lineA); + if (newDistance < 1000000000.0) + { + distance = newDistance; + distanceType = 0; + } + newDistance = ray_intersect_circle(ray1, &TFlipperEdge::circlebase); + if (newDistance < distance) + { + distance = newDistance; + distanceType = 2; + } + newDistance = ray_intersect_circle(ray1, &TFlipperEdge::circleT1); + if (newDistance < distance) + { + distance = newDistance; + distanceType = 3; + } + newDistance = ray_intersect_line(ray1, &TFlipperEdge::lineB); + if (newDistance < distance) + { + distance = newDistance; + distanceType = 1; + } + if (!ray2 || distance >= 1000000000.0) + return distance; + + if (distanceType != -1) + { + vector_type* nextOrigin; + if (distanceType) + { + if (distanceType != 1) + { + float dirY; + ray2->Origin.X = distance * ray1->Direction.X + ray1->Origin.X; + ray2->Origin.Y = distance * ray1->Direction.Y + ray1->Origin.Y; + if (distanceType == 2) + { + ray2->Direction.X = ray2->Origin.X - TFlipperEdge::circlebase.Center.X; + dirY = ray2->Origin.Y - TFlipperEdge::circlebase.Center.Y; + } + else + { + ray2->Direction.X = ray2->Origin.X - TFlipperEdge::circleT1.Center.X; + dirY = ray2->Origin.Y - TFlipperEdge::circleT1.Center.Y; + } + ray2->Direction.Y = dirY; + normalize_2d(&ray2->Direction); + return distance; + } + ray2->Direction = TFlipperEdge::lineB.PerpendicularL; + nextOrigin = &TFlipperEdge::lineB.RayIntersect; + } + else + { + ray2->Direction = TFlipperEdge::lineA.PerpendicularL; + nextOrigin = &TFlipperEdge::lineA.RayIntersect; + } + ray2->Origin = *nextOrigin; + return distance; + } + return 1000000000.0; } diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index beae935..35748e7 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -9,7 +9,7 @@ class pb { public: static int time_ticks; - static float ball_speed_limit; + static float ball_speed_limit, time_now; static int cheat_mode, game_mode; static datFileStruct* record_table; static TPinballTable* MainTable; @@ -39,7 +39,7 @@ public: static float collide(float timeNow, float timeDelta, TBall* ball); private : static int demo_mode, mode_countdown_; - static float time_now, time_next; + static float time_next; static high_score_struct highscore_table[5]; static int state; };