diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index ed22afb..31388c3 100644 Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj index 56c65af..91c58c3 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj @@ -184,6 +184,7 @@ + @@ -252,6 +253,7 @@ + diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters index 4088f83..57f0cf1 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters @@ -216,6 +216,9 @@ Header Files\TPinballComponent + + Header Files\TPinballComponent + @@ -398,6 +401,9 @@ Source Files\TPinballComponent + + Source Files\TPinballComponent + diff --git a/SpaceCadetPinball/TBall.cpp b/SpaceCadetPinball/TBall.cpp index 574873b..1fda769 100644 --- a/SpaceCadetPinball/TBall.cpp +++ b/SpaceCadetPinball/TBall.cpp @@ -20,7 +20,7 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false) CollisionComp = nullptr; EdgeCollisionCount = 0; TimeDelta = 0.0; - Unknown17F = 1; + FieldFlag = 1; CollisionFlag = 0; Speed = 0.0; Acceleration.Y = 0.0; @@ -83,8 +83,8 @@ void TBall::Repaint() RenderSprite, bmp, zDepth, - bmp->Width / 2 - pos2D[0], - bmp->Height / 2 - pos2D[1]); + pos2D[0] - bmp->Width / 2, + pos2D[1] - bmp->Height / 2); } void TBall::not_again(TEdgeSegment* edge) @@ -117,7 +117,7 @@ int TBall::Message(int code, float value) Position.Y = 0.0; UnknownBaseFlag2 = 0; CollisionFlag = 0; - Unknown17F = 1; + FieldFlag = 1; Acceleration.Y = 0.0; Position.Z = Offset; Acceleration.X = 0.0; diff --git a/SpaceCadetPinball/TBall.h b/SpaceCadetPinball/TBall.h index e7ef2a3..f64366d 100644 --- a/SpaceCadetPinball/TBall.h +++ b/SpaceCadetPinball/TBall.h @@ -25,7 +25,7 @@ public : int Unknown14; int Unknown15; TCollisionComponent* CollisionComp; - float Unknown17F; + int FieldFlag; TEdgeSegment* Collisions[5]; int EdgeCollisionCount; vector_type CollisionOffset; diff --git a/SpaceCadetPinball/TCircle.cpp b/SpaceCadetPinball/TCircle.cpp index c8d00b6..8800cdc 100644 --- a/SpaceCadetPinball/TCircle.cpp +++ b/SpaceCadetPinball/TCircle.cpp @@ -8,7 +8,19 @@ TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visu Circle.Center = *center; } -double TCircle::FindCollisionDistance(ray_type* ray) +float TCircle::FindCollisionDistance(ray_type* ray) { return maths::ray_intersect_circle(ray, &Circle); -} \ No newline at end of file +} + +void TCircle::EdgeCollision(TBall* ball, float coef) +{ + vector_type direction{}, nextPosition{}; + + nextPosition.X = coef * ball->Acceleration.X + ball->Position.X; + nextPosition.Y = coef * ball->Acceleration.Y + ball->Position.Y; + direction.X = nextPosition.X - Circle.Center.X; + direction.Y = nextPosition.Y - Circle.Center.Y; + maths::normalize_2d(&direction); + CollisionComponent->Collision(ball, &nextPosition, &direction, coef, this); +} diff --git a/SpaceCadetPinball/TCircle.h b/SpaceCadetPinball/TCircle.h index ce17f1a..779128c 100644 --- a/SpaceCadetPinball/TCircle.h +++ b/SpaceCadetPinball/TCircle.h @@ -10,11 +10,8 @@ public: TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned int visualFlag, vector_type* center, float radius); - double FindCollisionDistance(ray_type* ray) override; - - void EdgeCollision(TBall* ball, float coef) override - { - } + float FindCollisionDistance(ray_type* ray) override; + void EdgeCollision(TBall* ball, float coef) override; void place_in_grid() override { diff --git a/SpaceCadetPinball/TCollisionComponent.cpp b/SpaceCadetPinball/TCollisionComponent.cpp index 762b136..efb9aff 100644 --- a/SpaceCadetPinball/TCollisionComponent.cpp +++ b/SpaceCadetPinball/TCollisionComponent.cpp @@ -29,10 +29,10 @@ TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, b } } - UnknownC7F = visual.Kicker.Unknown1F; + MaxCollisionSpeed = visual.Kicker.Unknown1F; UnknownC4F = visual.Unknown2F; UnknownC5F = visual.Unknown1F; - UnknownC6F = visual.Kicker.Unknown2F; + CollisionMultiplier = visual.Kicker.Unknown2F; SoundIndex1 = visual.Kicker.SoundIndex; SoundIndex2 = visual.SoundIndex2; GroupIndex = groupIndex; @@ -58,17 +58,17 @@ void TCollisionComponent::port_draw() } } -int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* ballPosition, vector_type* vec2) +int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* nextPosition, vector_type* direction) { if (PinballTable->TiltLockFlag) { - maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); + maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); return 0; } - auto projSpeed = maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F, - UnknownC7F, - UnknownC6F); - if (projSpeed <= UnknownC7F) + auto projSpeed = maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, + MaxCollisionSpeed, + CollisionMultiplier); + if (projSpeed <= MaxCollisionSpeed) { if (projSpeed > 0.2) { @@ -82,25 +82,25 @@ int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* ballPosition return 1; } -void TCollisionComponent::Collision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2, - float someVal, TEdgeSegment* edge) +void TCollisionComponent::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, + float coef, TEdgeSegment* edge) { int soundIndex; if (PinballTable->TiltLockFlag) { - maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); + maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 1000000000.0, 0.0); return; } double projSpeed = maths::basic_collision( ball, - ballPosition, - vec2, + nextPosition, + direction, UnknownC4F, UnknownC5F, - UnknownC7F, - UnknownC6F); - if (projSpeed <= UnknownC7F) + MaxCollisionSpeed, + CollisionMultiplier); + if (projSpeed <= MaxCollisionSpeed) { if (projSpeed <= 0.2) return; diff --git a/SpaceCadetPinball/TCollisionComponent.h b/SpaceCadetPinball/TCollisionComponent.h index dc66cd2..ba097e7 100644 --- a/SpaceCadetPinball/TCollisionComponent.h +++ b/SpaceCadetPinball/TCollisionComponent.h @@ -2,6 +2,7 @@ #include "objlist_class.h" #include "TPinballComponent.h" +struct vector_type; class TEdgeSegment; class TBall; @@ -13,16 +14,16 @@ public: __int16 UnknownC3; float UnknownC4F; float UnknownC5F; - float UnknownC6F; - float UnknownC7F; + float CollisionMultiplier; + float MaxCollisionSpeed; int SoundIndex2; int SoundIndex1; TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall); ~TCollisionComponent(); void port_draw() override; - virtual void Collision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2, float someVal, + virtual void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge); - virtual int FieldEffect(TBall* ball, struct vector_type* vecDst); - int DefaultCollision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2); + virtual int FieldEffect(TBall* ball, vector_type* vecDst); + int DefaultCollision(TBall* ball, vector_type* nextPosition, vector_type* direction); }; diff --git a/SpaceCadetPinball/TEdgeBox.cpp b/SpaceCadetPinball/TEdgeBox.cpp new file mode 100644 index 0000000..6d998b5 --- /dev/null +++ b/SpaceCadetPinball/TEdgeBox.cpp @@ -0,0 +1,16 @@ +#include "pch.h" +#include "TEdgeBox.h" + +#include "objlist_class.h" + +TEdgeBox::TEdgeBox() +{ + EdgeList = new objlist_class(0, 4); + FieldList = new objlist_class(0, 1); +} + +TEdgeBox::~TEdgeBox() +{ + delete EdgeList; + delete FieldList; +} diff --git a/SpaceCadetPinball/TEdgeBox.h b/SpaceCadetPinball/TEdgeBox.h new file mode 100644 index 0000000..4a25313 --- /dev/null +++ b/SpaceCadetPinball/TEdgeBox.h @@ -0,0 +1,13 @@ +#pragma once +class objlist_class; + +class TEdgeBox +{ +public: + TEdgeBox(); + ~TEdgeBox(); + + objlist_class* EdgeList; + objlist_class* FieldList; +}; + diff --git a/SpaceCadetPinball/TEdgeManager.cpp b/SpaceCadetPinball/TEdgeManager.cpp index b22c884..0d98a37 100644 --- a/SpaceCadetPinball/TEdgeManager.cpp +++ b/SpaceCadetPinball/TEdgeManager.cpp @@ -1,16 +1,274 @@ #include "pch.h" #include "TEdgeManager.h" -int TEdgeManager::FieldEffects(TBall* ball, vector_type* vecDst) +#include "TEdgeBox.h" +#include "TTableLayer.h" + +TEdgeManager::TEdgeManager(float posX, float posY, float width, float height) { - return 0; + X = posX; + Y = posY; + MaxBoxX = 10; + MaxBoxY = 15; + AdvanceX = width / 10.0f; + AdvanceY = height / 15.0f; + AdvanceXInv = 1.0f / AdvanceX; + AdvanceYInv = 1.0f / AdvanceY; + BoxArray = new TEdgeBox[150]; } -void TEdgeManager::edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6) +TEdgeManager::~TEdgeManager() { + delete[] BoxArray; +} + +int TEdgeManager::box_x(float x) +{ + return static_cast((max(0, min(floor((x - X) * AdvanceXInv), (MaxBoxX - 1))))); +} + +int TEdgeManager::box_y(float y) +{ + return static_cast((max(0, min(floor((y - Y) * AdvanceYInv), (MaxBoxY - 1))))); +} + +int TEdgeManager::increment_box_x(int x) +{ + return min(x + 1, MaxBoxX - 1); +} + +int TEdgeManager::increment_box_y(int y) +{ + return min(y + 1, MaxBoxY - 1); +} + +void TEdgeManager::add_edge_to_box(int x, int y, TEdgeSegment* edge) +{ + BoxArray[x + y * MaxBoxX].EdgeList->Add(edge); +} + +void TEdgeManager::add_field_to_box(int x, int y, field_effect_type* field) +{ + BoxArray[x + y * MaxBoxX].FieldList->Add(field); +} + +int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeDst, ray_type* ray, TBall* ball, + int edgeIndex) +{ + if (x >= 0 && x < 10 && y >= 0 && y < 15) + { + TEdgeBox* edgeBox = &BoxArray[x + y * MaxBoxX]; + TEdgeSegment** edgePtr = &EdgeArray[edgeIndex]; + for (auto index = edgeBox->EdgeList->Count() - 1; index >= 0; --index) + { + auto edge = static_cast(edgeBox->EdgeList->Get(index)); + if (!edge->ProcessedFlag && *edge->PinbCompFlag2Ptr && (edge->VisualFlag & ray->FieldFlag)) + { + if (!ball->already_hit(edge)) + { + ++edgeIndex; + *edgePtr = edge; + ++edgePtr; + edge->ProcessedFlag = 1; + auto dist = edge->FindCollisionDistance(ray); + if (dist < *distPtr) + { + *distPtr = dist; + *edgeDst = edge; + } + } + } + } + } + return edgeIndex; +} + +void TEdgeManager::FieldEffects(TBall* ball, vector_type* dstVec) +{ + vector_type vec{}; + TEdgeBox* edgeBox = &BoxArray[box_x(ball->Position.X) + box_y(ball->Position.Y) * + MaxBoxX]; + + for (int index = edgeBox->FieldList->Count() - 1; index >= 0; --index) + { + auto field = static_cast(edgeBox->FieldList->Get(index)); + if (*field->Flag2Ptr && ball->FieldFlag & field->Mask) + { + if (field->CollisionComp->FieldEffect(ball, &vec)) + { + maths::vector_add(dstVec, &vec); + } + } + } } float TEdgeManager::FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge) { - return 1000000000.0; + auto distance = 1000000000.0f; + auto edgeIndex = 0; + + auto rayX = ray->Origin.X; + auto rayY = ray->Origin.Y; + auto rayBoxX = box_x(rayX); + auto rayBoxY = box_y(rayY); + + auto rayEndX = ray->Direction.X * ray->MaxDistance + ray->Origin.X; + auto rayEndY = ray->Direction.Y * ray->MaxDistance + ray->Origin.Y; + auto rayEndBoxX = box_x(rayEndX); + auto rayEndBoxY = box_y(rayEndY); + + auto rayDirX = rayX >= rayEndX ? -1 : 1; + auto rayDirY = rayY >= rayEndY ? -1 : 1; + + if (rayBoxY == rayEndBoxY) + { + if (rayDirX == 1) + { + for (auto indexX = rayBoxX; indexX <= rayEndBoxX; indexX++) + { + edgeIndex = TestGridBox(indexX, rayBoxY, &distance, edge, ray, ball, edgeIndex); + } + } + else + { + for (auto indexX = rayBoxX; indexX >= rayEndBoxX; indexX--) + { + edgeIndex = TestGridBox(indexX, rayBoxY, &distance, edge, ray, ball, edgeIndex); + } + } + } + else + { + if (rayBoxX == rayEndBoxX) + { + if (rayDirY == 1) + { + for (auto indexY = rayBoxY; indexY <= rayEndBoxY; indexY++) + { + edgeIndex = TestGridBox(rayBoxX, indexY, &distance, edge, ray, ball, edgeIndex); + } + } + else + { + for (auto indexY = rayBoxY; indexY >= rayEndBoxY; indexY--) + { + edgeIndex = TestGridBox(rayBoxX, indexY, &distance, edge, ray, ball, edgeIndex); + } + } + } + else + { + auto rayDyDX = (rayY - rayEndY) / (rayX - rayEndX); + auto indexX = rayBoxX; + auto indexY = rayBoxY; + auto bresIndexX = rayBoxX + 1; + auto bresIndexY = rayBoxY + 1; + auto bresXAdd = rayY - rayDyDX * rayX; + edgeIndex = TestGridBox(rayBoxX, rayBoxY, &distance, edge, ray, ball, 0); + if (rayDirX == 1) + { + if (rayDirY == 1) + { + do + { + auto yCoord = bresIndexY * AdvanceY + Y; + auto xCoord = (bresIndexX * AdvanceX + X) * rayDyDX + bresXAdd; + if (xCoord >= yCoord) + { + if (xCoord == yCoord) + { + ++indexX; + ++bresIndexX; + } + ++indexY; + ++bresIndexY; + } + else + { + ++indexX; + ++bresIndexX; + } + edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex); + } + while (indexX < rayEndBoxX || indexY < rayEndBoxY); + } + else + { + do + { + auto yCoord = indexY * AdvanceY + Y; + auto xCoord = (bresIndexX * AdvanceX + X) * rayDyDX + bresXAdd; + if (xCoord <= yCoord) + { + if (xCoord == yCoord) + { + ++indexX; + ++bresIndexX; + } + --indexY; + } + else + { + ++indexX; + ++bresIndexX; + } + edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex); + } + while (indexX < rayEndBoxX || indexY > rayEndBoxY); + } + } + else + { + if (rayDirY == 1) + { + do + { + auto yCoord = bresIndexY * AdvanceY + Y; + auto xCoord = (indexX * AdvanceX + X) * rayDyDX + bresXAdd; + if (xCoord >= yCoord) + { + if (xCoord == yCoord) + --indexX; + ++indexY; + ++bresIndexY; + } + else + { + --indexX; + } + edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex); + } + while (indexX > rayEndBoxX || indexY < rayEndBoxY); + } + else + { + do + { + auto yCoord = indexY * AdvanceY + Y; + auto xCoord = (indexX * AdvanceX + X) * rayDyDX + bresXAdd; + if (xCoord <= yCoord) + { + if (xCoord == yCoord) + --indexX; + --indexY; + } + else + { + --indexX; + } + edgeIndex = TestGridBox(indexX, indexY, &distance, edge, ray, ball, edgeIndex); + } + while (indexX > rayEndBoxX || indexY > rayEndBoxY); + } + } + } + } + + + for (auto edgePtr = EdgeArray; edgeIndex > 0; --edgeIndex, ++edgePtr) + { + (*edgePtr)->ProcessedFlag = 0; + } + + return distance; } diff --git a/SpaceCadetPinball/TEdgeManager.h b/SpaceCadetPinball/TEdgeManager.h index 5e34342..d203862 100644 --- a/SpaceCadetPinball/TEdgeManager.h +++ b/SpaceCadetPinball/TEdgeManager.h @@ -2,22 +2,38 @@ #include "TCollisionComponent.h" #include "TEdgeSegment.h" +class TEdgeBox; + struct field_effect_type { char* Flag2Ptr; - int Unknown1; + int Mask; TCollisionComponent* CollisionComp; }; class TEdgeManager { public: - TEdgeManager(float a2, float a3, float a4, float a5) - { - } - - int FieldEffects(TBall* ball, struct vector_type* vecDst); - - static void edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6); + TEdgeManager(float posX, float posY, float width, float height); + ~TEdgeManager(); + void FieldEffects(TBall* ball, struct vector_type* dstVec); + int box_x(float x); + int box_y(float y); + int increment_box_x(int x); + int increment_box_y(int y); + void add_edge_to_box(int x, int y, TEdgeSegment* edge); + void add_field_to_box(int x, int y, field_effect_type* field); + int TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeDst, ray_type* ray, TBall* ball, int edgeIndex); float FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge); + + float AdvanceX; + float AdvanceY; + float AdvanceXInv; + float AdvanceYInv; + int MaxBoxX; + int MaxBoxY; + float X; + float Y; + TEdgeBox* BoxArray; + TEdgeSegment* EdgeArray[1000]; }; diff --git a/SpaceCadetPinball/TEdgeSegment.cpp b/SpaceCadetPinball/TEdgeSegment.cpp index 95235b7..2ab031a 100644 --- a/SpaceCadetPinball/TEdgeSegment.cpp +++ b/SpaceCadetPinball/TEdgeSegment.cpp @@ -8,7 +8,7 @@ TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsign this->CollisionComponent = collComp; this->PinbCompFlag2Ptr = someFlag; this->VisualFlag = visualFlag; - this->Unknown3_0 = 0; + this->ProcessedFlag = 0; } void TEdgeSegment::port_draw() diff --git a/SpaceCadetPinball/TEdgeSegment.h b/SpaceCadetPinball/TEdgeSegment.h index 286a218..cf2ac91 100644 --- a/SpaceCadetPinball/TEdgeSegment.h +++ b/SpaceCadetPinball/TEdgeSegment.h @@ -14,7 +14,7 @@ class TEdgeSegment public: TCollisionComponent* CollisionComponent; char* PinbCompFlag2Ptr; - char Unknown3_0; + char ProcessedFlag; int WallValue; int VisualFlag; @@ -24,7 +24,7 @@ public: virtual void EdgeCollision(TBall* ball, float coef) = 0; virtual void port_draw(); virtual void place_in_grid() = 0; - virtual double FindCollisionDistance(ray_type* ray) = 0; + 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); diff --git a/SpaceCadetPinball/TLightGroup.cpp b/SpaceCadetPinball/TLightGroup.cpp index f9cb24c..bc7eef5 100644 --- a/SpaceCadetPinball/TLightGroup.cpp +++ b/SpaceCadetPinball/TLightGroup.cpp @@ -9,7 +9,7 @@ #include "TLight.h" #include "TPinballTable.h" -TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, -1, false) +TLightGroup::TLightGroup(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false) { List = new objlist_class(4, 4); Timer = 0; diff --git a/SpaceCadetPinball/TLine.cpp b/SpaceCadetPinball/TLine.cpp index 66b5a7c..e67707b 100644 --- a/SpaceCadetPinball/TLine.cpp +++ b/SpaceCadetPinball/TLine.cpp @@ -1,24 +1,26 @@ #include "pch.h" #include "TLine.h" +#include "TTableLayer.h" + TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1, float y1): TEdgeSegment(collCmp, flagPtr, visualFlag) { - this->X0 = x0; - this->Y0 = y0; - this->X1 = x1; - this->Y1 = y1; + X0 = x0; + Y0 = y0; + X1 = x1; + Y1 = y1; maths::line_init(&Line, x0, y0, x1, y1); } TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start, struct vector_type* end) : TEdgeSegment(collCmp, flagPtr, visualFlag) { - this->X0 = start->X; - this->Y0 = start->Y; - this->X1 = end->X; - this->Y1 = end->Y; + X0 = start->X; + Y0 = start->Y; + X1 = end->X; + Y1 = end->Y; maths::line_init(&Line, X0, Y0, X1, Y1); } @@ -34,7 +36,169 @@ void TLine::Offset(float offset) maths::line_init(&Line, X0, Y0, X1, Y1); } -double TLine::FindCollisionDistance(ray_type* ray) +float TLine::FindCollisionDistance(ray_type* ray) { return maths::ray_intersect_line(ray, &Line); } + +void TLine::EdgeCollision(TBall* ball, float coef) +{ + CollisionComponent->Collision( + ball, + &Line.RayIntersect, + &Line.PerpendicularL, + coef, + this); +} + +void TLine::place_in_grid() +{ + auto xBox0 = TTableLayer::edge_manager->box_x(X0); + auto yBox0 = TTableLayer::edge_manager->box_y(Y0); + auto xBox1 = TTableLayer::edge_manager->box_x(X1); + auto yBox1 = TTableLayer::edge_manager->box_y(Y1); + + int dirX = X0 >= X1 ? -1 : 1; + int dirY = Y0 >= Y1 ? -1 : 1; + + if (yBox0 == yBox1) + { + if (dirX == 1) + { + while (xBox0 <= xBox1) + TTableLayer::edge_manager->add_edge_to_box(xBox0++, yBox0, this); + } + else + { + while (xBox0 >= xBox1) + TTableLayer::edge_manager->add_edge_to_box(xBox0--, yBox0, this); + } + } + else if (xBox0 == xBox1) + { + if (dirY == 1) + { + if (yBox0 <= yBox1) + { + do + TTableLayer::edge_manager->add_edge_to_box(xBox0, yBox0++, this); + while (yBox0 <= yBox1); + } + } + else if (yBox0 >= yBox1) + { + do + TTableLayer::edge_manager->add_edge_to_box(xBox0, yBox0--, this); + while (yBox0 >= yBox1); + } + } + else + { + float yCoord, xCoord; + int indexX1 = xBox0, indexY1 = yBox0; + int bresIndexX = xBox0 + 1, bresIndexY = yBox0 + 1; + auto bresDyDx = (Y0 - Y1) / (X0 - X1); + auto bresXAdd = Y0 - bresDyDx * X0; + TTableLayer::edge_manager->add_edge_to_box(xBox0, yBox0, this); + if (dirX == 1) + { + if (dirY == 1) + { + do + { + yCoord = bresIndexY * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y; + xCoord = (bresIndexX * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) * + bresDyDx + bresXAdd; + if (xCoord >= yCoord) + { + if (xCoord == yCoord) + { + ++indexX1; + ++bresIndexX; + } + ++indexY1; + ++bresIndexY; + } + else + { + ++indexX1; + ++bresIndexX; + } + TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this); + } + while (indexX1 != xBox1 || indexY1 != yBox1); + } + else + { + do + { + yCoord = indexY1 * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y; + xCoord = (bresIndexX * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) * + bresDyDx + bresXAdd; + if (xCoord <= yCoord) + { + if (xCoord == yCoord) + { + ++indexX1; + ++bresIndexX; + } + --indexY1; + } + else + { + ++indexX1; + ++bresIndexX; + } + TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this); + } + while (indexX1 != xBox1 || indexY1 != yBox1); + } + } + else + { + if (dirY == 1) + { + do + { + xCoord = bresIndexY * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y; + yCoord = (indexX1 * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) * + bresDyDx + bresXAdd; + if (yCoord >= xCoord) + { + if (yCoord == xCoord) + --indexX1; + ++indexY1; + ++bresIndexY; + } + else + { + --indexX1; + } + TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this); + } + while (indexX1 != xBox1 || indexY1 != yBox1); + } + else + { + do + { + yCoord = indexY1 * TTableLayer::edge_manager->AdvanceY + TTableLayer::edge_manager->Y; + xCoord = (indexX1 * TTableLayer::edge_manager->AdvanceX + TTableLayer::edge_manager->X) * + bresDyDx + bresXAdd; + if (xCoord <= yCoord) + { + if (xCoord == yCoord) + --indexX1; + --indexY1; + } + else + { + --indexX1; + } + TTableLayer::edge_manager->add_edge_to_box(indexX1, indexY1, this); + } + while (indexX1 != xBox1 || indexY1 != yBox1); + } + } + } +} diff --git a/SpaceCadetPinball/TLine.h b/SpaceCadetPinball/TLine.h index ffe88c4..d4fd798 100644 --- a/SpaceCadetPinball/TLine.h +++ b/SpaceCadetPinball/TLine.h @@ -12,13 +12,7 @@ public: TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, struct vector_type* start, struct vector_type* end); void Offset(float offset); - double FindCollisionDistance(ray_type* ray) override; - - void EdgeCollision(TBall* ball, float coef) override - { - } - - void place_in_grid() override - { - } + float FindCollisionDistance(ray_type* ray) override; + void EdgeCollision(TBall* ball, float coef) override; + void place_in_grid() override; }; diff --git a/SpaceCadetPinball/TPinballTable.h b/SpaceCadetPinball/TPinballTable.h index 39e7897..1b538b3 100644 --- a/SpaceCadetPinball/TPinballTable.h +++ b/SpaceCadetPinball/TPinballTable.h @@ -68,12 +68,12 @@ public: objlist_class* ComponentList; objlist_class* BallList; TLightGroup* LightGroup; - float TableAngleMult; - float TableAngle1; - float TableAngle2; + float GravityDirVectMult; + float GravityAngleX; + float GravityAnglY; float CollisionCompOffset; - int UnknownP62; - int UnknownP63; + float PlungerPositionX; + float PlungerPositionY; int ScoreMultiplier; int ScoreAdded; int ScoreSpecial1; diff --git a/SpaceCadetPinball/TPlunger.cpp b/SpaceCadetPinball/TPlunger.cpp index f32574c..209910a 100644 --- a/SpaceCadetPinball/TPlunger.cpp +++ b/SpaceCadetPinball/TPlunger.cpp @@ -1,2 +1,171 @@ #include "pch.h" #include "TPlunger.h" + + +#include "control.h" +#include "loader.h" +#include "maths.h" +#include "pb.h" +#include "render.h" +#include "TBall.h" +#include "timer.h" +#include "TPinballTable.h" +#include "TZmapList.h" + +TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + visualStruct visual{}; + + loader::query_visual(groupIndex, 0, &visual); + CollisionMultiplier = 0.0; + BallFeedTimer_ = 0; + PullbackTimer_ = 0; + SoundIndexP1 = visual.SoundIndex4; + SoundIndexP2 = visual.SoundIndex3; + SoundIndex1 = visual.Kicker.SoundIndex; + MaxCollisionSpeed = 1000000000.0; + MaxPullback = 100; + UnknownC4F = 0.5f; + UnknownC5F = 0.5f; + PullbackIncrement = static_cast(100.0 / (ListBitmap->Count() * 8.0)); + Unknown4F = 0.025f; + float* floatArr = loader::query_float_attribute(groupIndex, 0, 601); + table->PlungerPositionX = floatArr[0]; + table->PlungerPositionY = floatArr[1]; +} + +void TPlunger::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ + 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); +} + +int TPlunger::Message(int code, float value) +{ + switch (code) + { + case 1004: + if (!PullbackTimer_) + { + CollisionMultiplier = 0.0; + MaxCollisionSpeed = 1000000000.0; + loader::play_sound(SoundIndex1); + PullbackTimer(0, this); + } + return 0; + case 1005: + case 1009: + case 1010: + { + MaxCollisionSpeed = 0.0; + if (PullbackTimer_) + timer::kill(PullbackTimer_); + PullbackTimer_ = 0; + if (code == 1005) + loader::play_sound(SoundIndexP2); + auto bmp = static_cast(ListBitmap->Get(0)); + auto zMap = static_cast(ListZMap->Get(0)); + render::sprite_set( + RenderSprite, + bmp, + zMap, + bmp->XPosition - PinballTable->XOffset, + bmp->YPosition - PinballTable->YOffset); + + timer::set(Unknown4F, this, PlungerReleasedTimer); + break; + } + case 1015: + { + auto ball = static_cast(PinballTable->ComponentList->Get(0)); + ball->Message(1024, 0.0); + ball->Position.X = PinballTable->PlungerPositionX; + ball->Position.Y = PinballTable->PlungerPositionY; + ball->UnknownBaseFlag2 = 1; + PinballTable->UnknownP10 = 0; + pb::tilt_no_more(); + control::handler(code, this); + return 0; + } + case 1016: + if (BallFeedTimer_) + timer::kill(BallFeedTimer_); + BallFeedTimer_ = timer::set(0.95999998f, this, BallFeedTimer); + loader::play_sound(SoundIndexP1); + control::handler(code, this); + return 0; + case 1017: + MaxCollisionSpeed = 0.0; + CollisionMultiplier = static_cast(MaxPullback); + timer::set(0.2f, this, PlungerReleasedTimer); + break; + case 1024: + { + if (BallFeedTimer_) + timer::kill(BallFeedTimer_); + BallFeedTimer_ = 0; + MaxCollisionSpeed = 0.0; + if (PullbackTimer_) + timer::kill(PullbackTimer_); + PullbackTimer_ = 0; + if (code == 1005) + loader::play_sound(SoundIndexP2); + auto bmp = static_cast(ListBitmap->Get(0)); + auto zMap = static_cast(ListZMap->Get(0)); + render::sprite_set( + RenderSprite, + bmp, + zMap, + bmp->XPosition - PinballTable->XOffset, + bmp->YPosition - PinballTable->YOffset); + + timer::set(Unknown4F, this, PlungerReleasedTimer); + break; + } + default: + break; + } + return 0; +} + +void TPlunger::BallFeedTimer(int timerId, void* caller) +{ + auto plunger = static_cast(caller); + plunger->PullbackTimer_ = 0; + plunger->Message(1015, 0.0); +} + +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->PullbackTimer_ = timer::set(plunger->Unknown4F, plunger, PullbackTimer); + } + else + { + plunger->PullbackTimer_ = 0; + plunger->CollisionMultiplier = static_cast(plunger->MaxPullback); + } + int index = static_cast(floor( + static_cast(plunger->ListBitmap->Count() - 1) * + (plunger->CollisionMultiplier / static_cast(plunger->MaxPullback)))); + auto bmp = static_cast(plunger->ListBitmap->Get(index)); + auto zMap = static_cast(plunger->ListZMap->Get(index)); + render::sprite_set( + plunger->RenderSprite, + bmp, + zMap, + bmp->XPosition - plunger->PinballTable->XOffset, + bmp->YPosition - plunger->PinballTable->YOffset); +} + +void TPlunger::PlungerReleasedTimer(int timerId, void* caller) +{ + auto plunger = static_cast(caller); + plunger->MaxCollisionSpeed = 1000000000.0; + plunger->CollisionMultiplier = 0.0; +} diff --git a/SpaceCadetPinball/TPlunger.h b/SpaceCadetPinball/TPlunger.h index bd7ae7a..5ce1bdc 100644 --- a/SpaceCadetPinball/TPlunger.h +++ b/SpaceCadetPinball/TPlunger.h @@ -5,7 +5,20 @@ class TPlunger : public TCollisionComponent { public: - TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TPlunger(TPinballTable* table, int groupIndex); + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + int Message(int code, float value) override; + + static void BallFeedTimer(int timerId, void* caller); + static void PullbackTimer(int timerId, void* caller); + static void PlungerReleasedTimer(int timerId, void* caller); + + int PullbackTimer_; + int BallFeedTimer_; + int MaxPullback; + int PullbackIncrement; + float Unknown4F; + int SoundIndexP1; + int SoundIndexP2; }; diff --git a/SpaceCadetPinball/TTableLayer.cpp b/SpaceCadetPinball/TTableLayer.cpp index d100c53..f3bd644 100644 --- a/SpaceCadetPinball/TTableLayer.cpp +++ b/SpaceCadetPinball/TTableLayer.cpp @@ -36,32 +36,32 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f auto tableAngleArr = loader::query_float_attribute(groupIndex, 0, 305); if (tableAngleArr) { - PinballTable->TableAngleMult = tableAngleArr[0]; - PinballTable->TableAngle1 = tableAngleArr[1]; - PinballTable->TableAngle2 = tableAngleArr[2]; + PinballTable->GravityDirVectMult = tableAngleArr[0]; + PinballTable->GravityAngleX = tableAngleArr[1]; + PinballTable->GravityAnglY = tableAngleArr[2]; } else { - PinballTable->TableAngleMult = 25.0f; - PinballTable->TableAngle1 = 0.5f; - PinballTable->TableAngle2 = 1.570796f; + PinballTable->GravityDirVectMult = 25.0f; + PinballTable->GravityAngleX = 0.5f; + PinballTable->GravityAnglY = 1.570796f; } auto table3 = PinballTable; - Angle1 = cos(table3->TableAngle2) * sin(table3->TableAngle1) * table3->TableAngleMult; - Angle2 = sin(table3->TableAngle2) * sin(table3->TableAngle1) * table3->TableAngleMult; + GraityDirX = cos(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult; + GraityDiY = sin(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult; auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701); if (angleMultArr) - AngleMult = *angleMultArr; + GraityMult = *angleMultArr; else - AngleMult = 0.2f; + GraityMult = 0.2f; table->XOffset = bmp->XPosition; table->YOffset = bmp->YPosition; table->Width = bmp->Width; table->Height = bmp->Height; - UnknownC7F = visual.Kicker.Unknown1F; - UnknownC6F = 15.0f; + MaxCollisionSpeed = visual.Kicker.Unknown1F; + CollisionMultiplier = 15.0f; auto visArrPtr = visual.FloatArr; Unknown1F = min(visArrPtr[0], min(visArrPtr[2], visArrPtr[4])); @@ -90,11 +90,11 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f visArrPtr += 2; } - Field.Unknown1 = -1; + Field.Mask = -1; Field.Flag2Ptr = &UnknownBaseFlag2; Field.CollisionComp = this; - TEdgeManager::edges_insert_square(Unknown2F, Unknown1F, Unknown4F, Unknown3F, nullptr, - &Field); + edges_insert_square(Unknown2F, Unknown1F, Unknown4F, Unknown3F, nullptr, + &Field); } TTableLayer::~TTableLayer() @@ -102,3 +102,51 @@ TTableLayer::~TTableLayer() if (edge_manager) delete edge_manager; } + +int TTableLayer::FieldEffect(TBall* ball, vector_type* vecDst) +{ + vecDst->X = GraityDirX - (0.5f - static_cast(rand()) * 0.00003051850947599719f + ball->Acceleration.X) * + ball->Speed * GraityMult; + vecDst->Y = GraityDiY - ball->Acceleration.Y * ball->Speed * GraityMult; + return 1; +} + +void TTableLayer::edges_insert_square(float y0, float x0, float y1, float x1, TEdgeSegment* edge, + field_effect_type* field) +{ + float widthM = edge_manager->AdvanceX * 0.001f; + float heightM = edge_manager->AdvanceY * 0.001f; + float xMin = x0 - widthM; + float xMax = x1 + widthM; + float yMin = y0 - heightM; + float yMax = y1 + heightM; + + int xMinBox = edge_manager->box_x(xMin); + int yMinBox = edge_manager->box_y(yMin); + int xMaxBox = edge_manager->box_x(xMax); + int yMaxBox = edge_manager->box_y(yMax); + + float boxX = static_cast(xMinBox) * edge_manager->AdvanceX + edge_manager->X; + float boxY = static_cast(yMinBox) * edge_manager->AdvanceY + edge_manager->Y; + + for (int indexX = xMinBox; indexX <= xMaxBox; ++indexX) + { + for (int indexY = yMinBox; indexY <= yMaxBox; ++indexY) + { + if (xMax >= boxX && xMin <= boxX + edge_manager->AdvanceX && + yMax >= boxY && yMin <= boxY + edge_manager->AdvanceY) + { + if (edge) + { + edge_manager->add_edge_to_box(indexX, indexY, edge); + } + if (field) + { + edge_manager->add_field_to_box(indexX, indexY, field); + } + } + boxY += edge_manager->AdvanceY; + } + boxX += edge_manager->AdvanceX; + } +} diff --git a/SpaceCadetPinball/TTableLayer.h b/SpaceCadetPinball/TTableLayer.h index 869f2b5..d8bf9a9 100644 --- a/SpaceCadetPinball/TTableLayer.h +++ b/SpaceCadetPinball/TTableLayer.h @@ -10,20 +10,24 @@ struct gdrv_bitmap8; class TTableLayer : public TCollisionComponent { -public: - static TEdgeManager* edge_manager; - +public: TTableLayer(TPinballTable* table); ~TTableLayer() override; + int FieldEffect(TBall* ball, vector_type* vecDst) override; + static void edges_insert_square(float y0, float x0, float y1, float x1, TEdgeSegment* edge, + field_effect_type* field); + gdrv_bitmap8* VisBmp; float Unknown1F; float Unknown2F; float Unknown3F; float Unknown4F; - float Angle1; - float Angle2; + float GraityDirX; + float GraityDiY; int Unknown7; - float AngleMult; + float GraityMult; field_effect_type Field; + + static TEdgeManager* edge_manager; }; diff --git a/SpaceCadetPinball/control.cpp b/SpaceCadetPinball/control.cpp index 21d95fc..d6735df 100644 --- a/SpaceCadetPinball/control.cpp +++ b/SpaceCadetPinball/control.cpp @@ -3,6 +3,7 @@ #include "objlist_class.h" #include "pb.h" +#include "TLight.h" #include "TPinballTable.h" #include "TSound.h" @@ -795,6 +796,12 @@ int control::cheat_bump_rank() return 0; } +BOOL control::light_on(component_tag* tag) +{ + auto light = static_cast(tag->Component); + return light->BmpIndex1 || light->FlasherFlag2 || light->FlasherActive; +} + void control::FlipperRebounderControl1(int code, TPinballComponent* caller) { } @@ -1013,6 +1020,35 @@ void control::HyperspaceKickOutControl(int code, TPinballComponent* caller) void control::PlungerControl(int code, TPinballComponent* caller) { + if (code == 1015) + { + MissionControl(67, nullptr); + } + else if (code == 1016) + { + table_unlimited_balls = 0; + if (!control_middle_circle_tag.Component->Message(37, 0.0)) + control_middle_circle_tag.Component->Message(32, 0.0); + if (!light_on(&control_lite200_tag)) + { + control_skill_shot_lights_tag.Component->Message(20, 0.0); + control_lite67_tag.Component->Message(19, 0.0); + control_skill_shot_lights_tag.Component->Message(26, 0.25f); + control_l_trek_lights_tag.Component->Message(20, 0.0); + control_l_trek_lights_tag.Component->Message(32, 0.2f); + control_l_trek_lights_tag.Component->Message(26, 0.2f); + control_r_trek_lights_tag.Component->Message(20, 0.0); + control_r_trek_lights_tag.Component->Message(32, 0.2f); + control_r_trek_lights_tag.Component->Message(26, 0.2f); + TableG->ScoreSpecial1 = 25000; + MultiplierLightGroupControl(65, control_top_target_lights_tag.Component); + control_fuel_bargraph_tag.Component->Message(19, 0.0); + control_lite200_tag.Component->Message(19, 0.0); + control_gate1_tag.Component->Message(53, 0.0); + control_gate2_tag.Component->Message(53, 0.0); + } + control_lite200_tag.Component->MessageField = 0; + } } void control::MedalTargetControl(int code, TPinballComponent* caller) diff --git a/SpaceCadetPinball/control.h b/SpaceCadetPinball/control.h index cf73b0b..e4cc65f 100644 --- a/SpaceCadetPinball/control.h +++ b/SpaceCadetPinball/control.h @@ -38,6 +38,7 @@ public: static void pbctrl_bdoor_controller(int key); static void table_add_extra_ball(float count); static int cheat_bump_rank(); + static BOOL light_on(struct component_tag* tag); static void FlipperRebounderControl1(int code, TPinballComponent* caller); static void FlipperRebounderControl2(int code, TPinballComponent* caller); diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index 2532479..317eb0f 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -216,9 +216,9 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line) / perpDot); if (result >= -ray->MinDistance && result <= ray->MaxDistance) { - line->CompTmp1 = result * ray->Direction.X + ray->Origin.X; + line->RayIntersect.X = result * ray->Direction.X + ray->Origin.X; float v4 = result * ray->Direction.Y + ray->Origin.Y; - line->Unknown10 = v4; + line->RayIntersect.Y = v4; if (0.0 == line->Direction.X) { if (v4 >= line->OriginX) @@ -230,9 +230,9 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line) return 1000000000.0; } } - else if (line->OriginX <= line->CompTmp1) + else if (line->OriginX <= line->RayIntersect.X) { - float v7 = line->CompTmp1; + float v7 = line->RayIntersect.X; v5 = v7 < line->OriginY; v6 = v7 == line->OriginY; if (v5 || v6) @@ -268,20 +268,20 @@ void maths::vector_add(vector_type* vec1Dst, vector_type* vec2) vec1Dst->Y += vec2->Y; } -float maths::basic_collision(TBall* ball, vector_type* ballPosition, vector_type* vec2, float a4, float a5, float a6, - float a7) +float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float a4, float a5, float maxSpeed, + float multiplier) { - ball->Position.X = ballPosition->X; - ball->Position.Y = ballPosition->Y; - float proj = -(vec2->Y * ball->Acceleration.Y + vec2->X * ball->Acceleration.X); + ball->Position.X = nextPosition->X; + ball->Position.Y = nextPosition->Y; + float proj = -(direction->Y * ball->Acceleration.Y + direction->X * ball->Acceleration.X); if (proj < 0) { proj = -proj; } else { - float dx1 = proj * vec2->X; - float dy1 = proj * vec2->Y; + 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; @@ -291,10 +291,10 @@ float maths::basic_collision(TBall* ball, vector_type* ballPosition, vector_type float projSpeed = proj * ball->Speed; float newSpeed = ball->Speed - (1.0f - a4) * projSpeed; ball->Speed = newSpeed; - if (projSpeed >= a6) + if (projSpeed >= maxSpeed) { - ball->Acceleration.X = newSpeed * ball->Acceleration.X + vec2->X * a7; - ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + vec2->Y * a7; + ball->Acceleration.X = newSpeed * ball->Acceleration.X + direction->X * multiplier; + ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + direction->Y * multiplier; ball->Speed = normalize_2d(&ball->Acceleration); } return projSpeed; diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index 3d93bff..ed5752f 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -32,7 +32,7 @@ struct __declspec(align(4)) ray_type float MinDistance; float TimeNow; float TimeDelta; - float Unknown2; + int FieldFlag; }; struct __declspec(align(4)) line_type @@ -42,9 +42,7 @@ struct __declspec(align(4)) line_type float PreComp1; float OriginX; float OriginY; - float CompTmp1; - float Unknown10; - float Unknown11; + vector_type RayIntersect; }; @@ -61,5 +59,5 @@ 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, struct vector_type* ballPosition, struct vector_type* vec2, float a4, float a5, float a6, float a7); + static float basic_collision(TBall* ball, struct vector_type* nextPosition, struct vector_type* direction, float a4, float a5, float maxSpeed, float multiplier); }; diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index e78c12f..371e460 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -518,8 +518,8 @@ void pb::launch_ball() void pb::end_game() { - int scores[4]; - int scoreIndex[4]; + int scores[4]{}; + int scoreIndex[4]{}; char String1[200]; mode_change(2); @@ -616,7 +616,7 @@ float pb::collide(float timeNow, float timeDelta, TBall* ball) ray.Direction.Y = ball->Acceleration.Y; ray.Direction.Z = ball->Acceleration.Z; ray.MaxDistance = maxDistance; - ray.Unknown2 = ball->Unknown17F; + ray.FieldFlag = ball->FieldFlag; ray.TimeNow = timeNow; ray.TimeDelta = timeDelta; ray.MinDistance = 0.0020000001f;