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;