diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index c0872b3..a8fa039 100644 Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ diff --git a/SpaceCadetPinball/TBall.h b/SpaceCadetPinball/TBall.h index 1ab6707..74f117b 100644 --- a/SpaceCadetPinball/TBall.h +++ b/SpaceCadetPinball/TBall.h @@ -24,9 +24,7 @@ public : float TimeDelta; float TimeNow; vector_type InvAcceleration; - int Unknown13; - int Unknown14; - int Unknown15; + vector_type RampFieldForce; TCollisionComponent* CollisionComp; int FieldFlag; TEdgeSegment* Collisions[5]; diff --git a/SpaceCadetPinball/TDemo.cpp b/SpaceCadetPinball/TDemo.cpp index 7284cb1..baf401b 100644 --- a/SpaceCadetPinball/TDemo.cpp +++ b/SpaceCadetPinball/TDemo.cpp @@ -100,7 +100,7 @@ void TDemo::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc ball->Position.Y = nextPosition->Y; ball->RayMaxDistance -= coef; - switch (edge->WallValue) + switch (reinterpret_cast(edge->WallValue)) { case 1400: if (!FlipLeftTimer && !FlipLeftFlag) @@ -134,7 +134,7 @@ void TDemo::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc break; default: break; - } + } } void TDemo::PlungerRelease(int timerId, void* caller) diff --git a/SpaceCadetPinball/TEdgeSegment.cpp b/SpaceCadetPinball/TEdgeSegment.cpp index da1cfbf..5cff1d9 100644 --- a/SpaceCadetPinball/TEdgeSegment.cpp +++ b/SpaceCadetPinball/TEdgeSegment.cpp @@ -20,7 +20,7 @@ void TEdgeSegment::port_draw() TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr, unsigned int visual_flag, - float offset, int someValue) + float offset, int wallValue) { vector_type center{}, start{}, end{}, prevCenter{}, vec1{}, vec2{}, dstVec{}; TEdgeSegment* edge = nullptr; @@ -38,7 +38,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c if (circle) { - circle->WallValue = someValue; + circle->WallValue = reinterpret_cast(wallValue); circle->place_in_grid(); } @@ -56,7 +56,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c if (line) { - line->WallValue = someValue; + line->WallValue = reinterpret_cast(wallValue); line->Offset(offset); line->place_in_grid(); collComp->EdgeList->Add(line); @@ -103,7 +103,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c if (circle) { - circle->WallValue = someValue; + circle->WallValue = reinterpret_cast(wallValue); circle->place_in_grid(); collComp->EdgeList->Add(circle); } @@ -119,7 +119,7 @@ TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* c if (line) { - line->WallValue = someValue; + line->WallValue = reinterpret_cast(wallValue); line->Offset(offset); line->place_in_grid(); collComp->EdgeList->Add(line); diff --git a/SpaceCadetPinball/TEdgeSegment.h b/SpaceCadetPinball/TEdgeSegment.h index 4cec022..f07ef35 100644 --- a/SpaceCadetPinball/TEdgeSegment.h +++ b/SpaceCadetPinball/TEdgeSegment.h @@ -16,7 +16,7 @@ public: TCollisionComponent* CollisionComponent; char* PinbCompFlag2Ptr; char ProcessedFlag; - int WallValue; + void* WallValue; int VisualFlag; TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag); @@ -28,5 +28,5 @@ public: virtual float FindCollisionDistance(ray_type* ray) = 0; static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr, - unsigned int visual_flag, float offset, int someValue); + unsigned int visual_flag, float offset, int wallValue); }; diff --git a/SpaceCadetPinball/TLine.h b/SpaceCadetPinball/TLine.h index d4fd798..a823cba 100644 --- a/SpaceCadetPinball/TLine.h +++ b/SpaceCadetPinball/TLine.h @@ -9,8 +9,7 @@ public: line_type Line; float X0, Y0, X1, Y1; TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1, float y1); - TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start, - struct vector_type* end); + TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, vector_type* start, vector_type* end); void Offset(float offset); float FindCollisionDistance(ray_type* ray) override; void EdgeCollision(TBall* ball, float coef) override; diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp index 700bed1..c197f5c 100644 --- a/SpaceCadetPinball/TPinballTable.cpp +++ b/SpaceCadetPinball/TPinballTable.cpp @@ -635,25 +635,14 @@ void TPinballTable::replay_timer_callback(int timerId, void* caller) void TPinballTable::tilt_timeout(int timerId, void* caller) { auto table = static_cast(caller); + vector_type vec{}; + table->TiltTimeoutTimer = 0; if (table->TiltLockFlag) { - /*v2 = table->ListP2.ListPtr; - v3 = v2->Array; - if (v2->Count > 0) + for (int i = 0; i < table->BallList->Count(); i++) { - v4 = v2->Count; - do - { - (*(void(__stdcall**)(void*, char*, char*, _DWORD, _DWORD))(*(_DWORD*)table->Drain + 20))( - *v3, - &v5, - &v5, - 0.0, - 0); - ++v3; - --v4; - } while (v4); - }*/ + table->Drain->Collision(static_cast(table->BallList->Get(i)), &vec, &vec, 0.0, nullptr); + } } } diff --git a/SpaceCadetPinball/TRamp.cpp b/SpaceCadetPinball/TRamp.cpp index 6357994..b24a2d4 100644 --- a/SpaceCadetPinball/TRamp.cpp +++ b/SpaceCadetPinball/TRamp.cpp @@ -2,6 +2,224 @@ #include "TRamp.h" +#include "control.h" +#include "loader.h" +#include "objlist_class.h" +#include "TBall.h" +#include "TEdgeSegment.h" +#include "TLine.h" +#include "TPinballTable.h" +#include "TTableLayer.h" + + +TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) +{ + visualStruct visual{}; + vector_type end{}, start{}, *end2, *start2, *start3, *end3; + + MessageField = 0; + UnknownBaseFlag1 = 1; + loader::query_visual(groupIndex, 0, &visual); + VisualFlag = visual.Flag; + + auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 701); + if (floatArr1) + BallFieldMult = *floatArr1; + else + BallFieldMult = 0.2f; + auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 1305); + if (floatArr2) + RampFlag1 = static_cast(floor(*floatArr2)); + else + RampFlag1 = 0; + + auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300); + RampPlaneCount = static_cast(floor(*floatArr3Plane)); + RampPlane = reinterpret_cast(floatArr3Plane + 1); + + auto floatArr4 = loader::query_float_attribute(groupIndex, 0, 1303); + end.X = floatArr4[2]; + end.Y = floatArr4[3]; + start.X = floatArr4[4]; + start.Y = floatArr4[5]; + Line1 = new TLine(this, &UnknownBaseFlag2, 1 << static_cast(floor(floatArr4[0])), &start, &end); + EdgeList->Add(Line1); + if (Line1) + { + Line1->WallValue = nullptr; + Line1->place_in_grid(); + } + + auto floatArr5WallPoint = loader::query_float_attribute(groupIndex, 0, 1301); + Wall1PointFirst = 1 << static_cast(floor(floatArr5WallPoint[0])); + auto wallPt1_2 = static_cast(floor(floatArr5WallPoint[1])); + Wall1PointLast = floatArr5WallPoint[7]; + maths::find_closest_edge( + RampPlane, + RampPlaneCount, + reinterpret_cast(floatArr5WallPoint + 3), + &end2, + &start2); + Line2 = new TLine(this, &UnknownBaseFlag2, VisualFlag, start2, end2); + EdgeList->Add(Line2); + if (Line2) + { + Line2->WallValue = nullptr; + Line2->place_in_grid(); + } + + auto floatArr6WallPoint = loader::query_float_attribute(groupIndex, 0, 1302); + auto wall2Pt1_2 = static_cast(floor(floatArr6WallPoint[1])); + Wall2PointFirst = 1 << static_cast(floor(floatArr6WallPoint[0])); + Wall2PointLast = floatArr6WallPoint[7]; + maths::find_closest_edge( + RampPlane, + RampPlaneCount, + reinterpret_cast(floatArr6WallPoint + 3), + &end3, + &start3); + Line3 = new TLine(this, &UnknownBaseFlag2, VisualFlag, start3, end3); + EdgeList->Add(Line3); + if (Line3) + { + Line3->WallValue = nullptr; + Line3->place_in_grid(); + } + + + auto xMin = 1000000000.0f; + auto yMin = 1000000000.0f; + auto yMax = -1000000000.0f; + auto xMax = -1000000000.0f; + for (auto index = 0; index < RampPlaneCount; index++) + { + auto plane = &RampPlane[index]; + auto pVec1 = reinterpret_cast(&plane->V1); + auto pVec2 = reinterpret_cast(&plane->V2); + auto pVec3 = reinterpret_cast(&plane->V3); + + xMin = min(min(min(plane->V3.X, plane->V1.X), plane->V2.X), xMin); + yMin = min(min(min(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); // Sic + xMax = max(max(max(plane->V3.X, plane->V1.X), plane->V2.X), xMin); + yMax = max(max(max(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); + + vector_type* pointOrder[4] = {pVec1, pVec2, pVec3, pVec1}; + for (auto pt = 0; pt < 3; pt++) + { + auto point1 = pointOrder[pt], point2 = pointOrder[pt + 1]; + auto lineFlag = 0; + if (point1 != end2 || point2 != start2) + { + if (point1 != end3 || point2 != start3) + { + lineFlag = visual.Flag; + } + else if (wall2Pt1_2) + { + lineFlag = Wall2PointFirst; + } + } + else if (wallPt1_2) + { + lineFlag = Wall1PointFirst; + } + if (lineFlag) + { + auto line = new TLine(this, &UnknownBaseFlag2, lineFlag, point1, point2); + EdgeList->Add(line); + if (line) + { + line->WallValue = plane; + line->place_in_grid(); + } + } + } + + plane->FieldForce.X = cos(plane->GravityAngle2) * sin(plane->GravityAngle1) * + PinballTable->GravityDirVectMult; + plane->FieldForce.Y = sin(plane->GravityAngle2) * sin(plane->GravityAngle1) * + PinballTable->GravityDirVectMult; + } + + Field.Flag2Ptr = &UnknownBaseFlag2; + Field.CollisionComp = this; + Field.Mask = visual.Flag; + + auto x1 = xMax; + auto y1 = yMax; + auto x0 = xMin; + auto y0 = yMin; + TTableLayer::edges_insert_square(y0, x0, y1, x1, nullptr, &Field); +} + +void TRamp::put_scoring(int index, int score) +{ + if (index < 4) + Scores[index] = score; +} + +int TRamp::get_scoring(int index) +{ + return index < 4 ? Scores[index] : 0; +} + +void TRamp::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ + ball->not_again(edge); + ball->Position.X = nextPosition->X; + ball->Position.Y = nextPosition->Y; + ball->RayMaxDistance -= coef; + + auto plane = static_cast(edge->WallValue); + if (plane) + { + ball->CollisionFlag = 1; + ball->CollisionOffset.X = plane->BallCollisionOffset.X; + ball->CollisionOffset.Y = plane->BallCollisionOffset.Y; + ball->CollisionOffset.Z = plane->BallCollisionOffset.Z; + ball->RampFieldForce.X = plane->FieldForce.X; + ball->RampFieldForce.Y = plane->FieldForce.Y; + ball->Position.Z = ball->Position.X * ball->CollisionOffset.X + ball->Position.Y * ball->CollisionOffset.Y + + ball->Offset + ball->CollisionOffset.Z; + ball->FieldFlag = VisualFlag; + return; + } + + if (edge == Line1) + { + if (!PinballTable->TiltLockFlag) + { + loader::play_sound(SoundIndex2); + control::handler(63, this); + } + } + else + { + ball->CollisionFlag = 0; + if (edge == Line2) + { + ball->FieldFlag = Wall1PointFirst; + if (!RampFlag1) + return; + ball->Position.Z = ball->Offset + Wall1PointLast; + } + else + { + ball->FieldFlag = Wall2PointFirst; + if (!RampFlag1) + return; + ball->Position.Z = ball->Offset + Wall2PointLast; + } + } +} + +int TRamp::FieldEffect(TBall* ball, vector_type* vecDst) +{ + vecDst->X = ball->RampFieldForce.X - ball->Acceleration.X * ball->Speed * BallFieldMult; + vecDst->Y = ball->RampFieldForce.Y - ball->Acceleration.Y * ball->Speed * BallFieldMult; + return 1; +} + void TRamp::port_draw() { TCollisionComponent::port_draw(); diff --git a/SpaceCadetPinball/TRamp.h b/SpaceCadetPinball/TRamp.h index ca5b7f0..21b598b 100644 --- a/SpaceCadetPinball/TRamp.h +++ b/SpaceCadetPinball/TRamp.h @@ -1,13 +1,34 @@ #pragma once + #include "TCollisionComponent.h" +#include "TEdgeManager.h" + +struct ramp_plane_type; class TRamp : public TCollisionComponent { public: - TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) - { - } - + TRamp(TPinballTable* table, int groupIndex); + void put_scoring(int index, int score) override; + int get_scoring(int index) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + int FieldEffect(TBall* ball, vector_type* vecDst) override; void port_draw() override; + + int Scores[4]; + field_effect_type Field; + int VisualFlag; + int RampFlag1; + int RampPlaneCount; + float BallFieldMult; + ramp_plane_type* RampPlane; + TEdgeSegment* Line2; + TEdgeSegment* Line3; + TEdgeSegment* Line1; + int Wall1PointFirst; + int Wall2PointFirst; + float Wall1PointLast; + float Wall2PointLast; }; diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index cfbf9f1..d369c03 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -47,8 +47,8 @@ struct __declspec(align(4)) line_type struct vector_type2 { - int X; - int Y; + float X; + float Y; }; struct wall_point_type @@ -61,14 +61,13 @@ struct wall_point_type struct __declspec(align(4)) ramp_plane_type { - float Unknown12; - vector_type2 V0; + vector_type BallCollisionOffset; vector_type2 V1; vector_type2 V2; vector_type2 V3; float GravityAngle1; float GravityAngle2; - vector_type2 V5_Zero; + vector_type2 FieldForce; };