mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-09-03 04:19:39 +02:00
vector_type is 3 x float, TCollisionComponent v1.
This commit is contained in:
parent
0258363287
commit
a1678120f8
@ -1,13 +1,11 @@
|
||||
#include "pch.h"
|
||||
#include "TCircle.h"
|
||||
|
||||
TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visualFlag, float* floatArr,
|
||||
TCircle::TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned visualFlag, vector_type* center,
|
||||
float radius): TEdgeSegment(collComp, someFlagPtr, visualFlag)
|
||||
{
|
||||
Circle.RadiusSq = radius * radius;
|
||||
Circle.X = *floatArr;
|
||||
Circle.Y = floatArr[1];
|
||||
Circle.Unknown2 = floatArr[2];
|
||||
Circle.Center = *center;
|
||||
}
|
||||
|
||||
double TCircle::FindCollisionDistance(ray_type* ray)
|
||||
|
@ -5,8 +5,18 @@
|
||||
class TCircle :
|
||||
public TEdgeSegment
|
||||
{
|
||||
public:
|
||||
circle_type Circle;
|
||||
|
||||
TCircle(TCollisionComponent* collComp, char* someFlagPtr, unsigned int visualFlag, float* floatArr, float radius);
|
||||
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
|
||||
{
|
||||
}
|
||||
|
||||
void place_in_grid() override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -1,2 +1,50 @@
|
||||
#include "pch.h"
|
||||
#include "TCollisionComponent.h"
|
||||
#include "loader.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "TPinballTable.h"
|
||||
|
||||
|
||||
TCollisionComponent::TCollisionComponent(TPinballTable* table, int groupIndex, int someFlag) : TPinballComponent(
|
||||
table, groupIndex, true)
|
||||
{
|
||||
visualStruct visual{};
|
||||
|
||||
EdgeList = new objlist_class(4, 4);
|
||||
UnknownBaseFlag2 = 1;
|
||||
if (GroupName != nullptr)
|
||||
UnknownBaseFlag1 = 1;
|
||||
if (groupIndex <= 0)
|
||||
{
|
||||
loader::default_vsi(&visual);
|
||||
}
|
||||
else
|
||||
{
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
if (someFlag)
|
||||
{
|
||||
float offset = table->UnknownP61F;
|
||||
float* floatArr = loader::query_float_attribute(groupIndex, 0, 600);
|
||||
TEdgeSegment::install_wall(floatArr, this, &UnknownBaseFlag2, visual.Flag, offset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
UnknownC7F = visual.Kicker.Unknown1F;
|
||||
UnknownC4F = visual.Unknown2F;
|
||||
UnknownC5F = visual.Unknown1F;
|
||||
UnknownC6F = visual.Kicker.Unknown2F;
|
||||
SoundIndex1 = visual.Kicker.SoundIndex;
|
||||
SoundIndex2 = visual.SoundIndex2;
|
||||
GroupIndex = groupIndex;
|
||||
}
|
||||
|
||||
TCollisionComponent::~TCollisionComponent()
|
||||
{
|
||||
for (TEdgeSegment* edge; EdgeList->Count() > 0;)
|
||||
{
|
||||
edge = static_cast<TEdgeSegment*>(EdgeList->Get(0));
|
||||
EdgeList->Delete(edge);
|
||||
delete edge;
|
||||
}
|
||||
delete this->EdgeList;
|
||||
}
|
||||
|
@ -1,5 +1,20 @@
|
||||
#pragma once
|
||||
class TCollisionComponent
|
||||
{
|
||||
};
|
||||
#include "objlist_class.h"
|
||||
#include "TPinballComponent.h"
|
||||
|
||||
class TCollisionComponent : public TPinballComponent
|
||||
{
|
||||
public:
|
||||
objlist_class* EdgeList;
|
||||
__int16 UnknownC2;
|
||||
__int16 UnknownC3;
|
||||
float UnknownC4F;
|
||||
float UnknownC5F;
|
||||
float UnknownC6F;
|
||||
float UnknownC7F;
|
||||
int SoundIndex2;
|
||||
int SoundIndex1;
|
||||
|
||||
TCollisionComponent(TPinballTable* table, int groupIndex, int someFlag);
|
||||
~TCollisionComponent();
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "TEdgeSegment.h"
|
||||
#include "TCircle.h"
|
||||
#include "TLine.h"
|
||||
|
||||
TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned visualFlag)
|
||||
{
|
||||
@ -8,3 +10,116 @@ TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsign
|
||||
this->VisualFlag = visualFlag;
|
||||
this->Unknown3_0 = 0;
|
||||
}
|
||||
|
||||
TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr,
|
||||
unsigned int visual_flag,
|
||||
float offset, int someValue)
|
||||
{
|
||||
vector_type center{}, start{}, end{}, prevCenter{}, vec1{}, vec2{}, dstVec{};
|
||||
TEdgeSegment* edge1;
|
||||
|
||||
wall_type wallType = static_cast<wall_type>(static_cast<int>(floor(*floatArr) - 1.0));
|
||||
switch (wallType)
|
||||
{
|
||||
case wall_type::Circle:
|
||||
{
|
||||
center.X = floatArr[1];
|
||||
center.Y = floatArr[2];
|
||||
|
||||
auto radius = offset + floatArr[3];
|
||||
auto circle = new TCircle(collComp, flagPtr, visual_flag, ¢er, radius);
|
||||
|
||||
if (circle)
|
||||
{
|
||||
circle->WallValue = someValue;
|
||||
circle->place_in_grid();
|
||||
}
|
||||
|
||||
collComp->EdgeList->Add(circle);
|
||||
return circle;
|
||||
}
|
||||
case wall_type::Line:
|
||||
{
|
||||
start.X = floatArr[1];
|
||||
start.Y = floatArr[2];
|
||||
end.X = floatArr[3];
|
||||
end.Y = floatArr[4];
|
||||
|
||||
auto line = new TLine(collComp, flagPtr, visual_flag, &start, &end);
|
||||
|
||||
if (line)
|
||||
{
|
||||
line->WallValue = someValue;
|
||||
line->Offset(offset);
|
||||
line->place_in_grid();
|
||||
collComp->EdgeList->Add(line);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
default:
|
||||
{
|
||||
int wallTypeI = static_cast<int>(wallType);
|
||||
auto floatArrPtr = floatArr + 1;
|
||||
prevCenter.X = floatArr[2 * wallTypeI - 1];
|
||||
prevCenter.Y = floatArr[2 * wallTypeI];
|
||||
|
||||
for (int index = 0; index < wallTypeI; index++, floatArrPtr += 2)
|
||||
{
|
||||
float centerX2, centerY2;
|
||||
if (index >= wallTypeI - 1)
|
||||
{
|
||||
centerX2 = floatArr[1];
|
||||
centerY2 = floatArr[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
centerX2 = floatArrPtr[2];
|
||||
centerY2 = floatArrPtr[3];
|
||||
}
|
||||
auto centerX1 = floatArrPtr[0];
|
||||
auto centerY1 = floatArrPtr[1];
|
||||
|
||||
center.X = centerX1;
|
||||
center.Y = centerY1;
|
||||
if (offset != 0.0)
|
||||
{
|
||||
vec1.X = centerX1 - prevCenter.X;
|
||||
vec1.Y = center.Y - prevCenter.Y;
|
||||
vec2.X = centerX2 - centerX1;
|
||||
vec2.Y = centerY2 - center.Y;
|
||||
maths::cross(&vec1, &vec2, &dstVec);
|
||||
if (dstVec.Z > 0.0 && offset > 0.0 ||
|
||||
dstVec.Z < 0.0 && offset < 0.0)
|
||||
{
|
||||
auto radius = offset * 1.001;
|
||||
auto circle = new TCircle(collComp, flagPtr, visual_flag, ¢er, radius);
|
||||
|
||||
if (circle)
|
||||
{
|
||||
circle->WallValue = someValue;
|
||||
circle->place_in_grid();
|
||||
collComp->EdgeList->Add(circle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
start.X = floatArrPtr[0];
|
||||
start.Y = floatArrPtr[1];
|
||||
end.X = floatArrPtr[2];
|
||||
end.Y = floatArrPtr[3];
|
||||
auto line = new TLine(collComp, flagPtr, visual_flag, &start, &end);
|
||||
if (line)
|
||||
{
|
||||
line->WallValue = someValue;
|
||||
line->Offset(offset);
|
||||
line->place_in_grid();
|
||||
collComp->EdgeList->Add(line);
|
||||
}
|
||||
|
||||
prevCenter = center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -3,21 +3,30 @@
|
||||
#include "maths.h"
|
||||
#include "TBall.h"
|
||||
|
||||
enum class wall_type
|
||||
{
|
||||
Circle = 0,
|
||||
Line = 1,
|
||||
};
|
||||
|
||||
class TEdgeSegment
|
||||
{
|
||||
public:
|
||||
TCollisionComponent* CollisionComponent;
|
||||
char* PinbCompFlag2Ptr;
|
||||
char Unknown3_0;
|
||||
char Unknown3_1;
|
||||
char Unknown3_2;
|
||||
char Unknown3_3;
|
||||
char Unknown4;
|
||||
int WallValue;
|
||||
int VisualFlag;
|
||||
|
||||
TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag);
|
||||
//virtual ~TEdgeSegment() = 0;
|
||||
|
||||
virtual ~TEdgeSegment()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void place_in_grid() = 0;
|
||||
virtual double FindCollisionDistance(ray_type* ray) = 0;
|
||||
virtual void EdgeCollision(TBall* ball, float coef) = 0;
|
||||
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr,
|
||||
unsigned int visual_flag, float offset, int someValue);
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "TPinballComponent.h"
|
||||
|
||||
class TFlipper :
|
||||
public TPinballComponent
|
||||
{
|
||||
|
@ -5,19 +5,21 @@
|
||||
TLine::TLine(TCollisionComponent* collCmp, char* flagPtr, unsigned int visualFlag, float x0, float y0, float x1,
|
||||
float y1): TEdgeSegment(collCmp, flagPtr, visualFlag)
|
||||
{
|
||||
Start.X = x0;
|
||||
Start.Y = y0;
|
||||
End.X = x1;
|
||||
End.Y = y1;
|
||||
this->X0 = x0;
|
||||
this->Y0 = y0;
|
||||
this->X1 = x1;
|
||||
this->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)
|
||||
{
|
||||
Start = *start;
|
||||
End = *end;
|
||||
maths::line_init(&Line, Start.X, Start.Y, End.X, End.Y);
|
||||
this->X0 = start->X;
|
||||
this->Y0 = start->Y;
|
||||
this->X1 = end->X;
|
||||
this->Y1 = end->Y;
|
||||
maths::line_init(&Line, X0, Y0, X1, Y1);
|
||||
}
|
||||
|
||||
void TLine::Offset(float offset)
|
||||
@ -25,14 +27,14 @@ void TLine::Offset(float offset)
|
||||
float offX = offset * Line.PerpendicularL.X;
|
||||
float offY = offset * Line.PerpendicularL.Y;
|
||||
|
||||
Start.X += offX;
|
||||
Start.Y += offY;
|
||||
End.X += offX;
|
||||
End.Y += offY;
|
||||
maths::line_init(&Line, Start.X, Start.Y, End.X, End.Y);
|
||||
X0 += offX;
|
||||
Y0 += offY;
|
||||
X1 += offX;
|
||||
Y1 += offY;
|
||||
maths::line_init(&Line, X0, Y0, X1, Y1);
|
||||
}
|
||||
|
||||
double TLine::FindCollisionDistance(ray_type* ray)
|
||||
{
|
||||
return maths::ray_intersect_line(ray, &Line);
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,18 @@ class TLine :
|
||||
{
|
||||
public:
|
||||
line_type Line;
|
||||
vector_type Start;
|
||||
vector_type End;
|
||||
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);
|
||||
void Offset(float offset);
|
||||
double FindCollisionDistance(ray_type* ray) override;
|
||||
|
||||
void EdgeCollision(TBall* ball, float coef) override
|
||||
{
|
||||
}
|
||||
|
||||
void place_in_grid() override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -2,11 +2,12 @@
|
||||
#include "render.h"
|
||||
#include "TZmapList.h"
|
||||
|
||||
class TPinballTable;
|
||||
|
||||
class TPinballComponent
|
||||
{
|
||||
public:
|
||||
TPinballComponent(class TPinballTable* table, int groupIndex, bool loadVisuals);
|
||||
TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals);
|
||||
virtual ~TPinballComponent();
|
||||
virtual int Message(int message1, float message2);
|
||||
virtual void put_scoring(int score1, int score2);
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
int UnknownP58;
|
||||
int UnknownP59;
|
||||
int UnknownP60;
|
||||
int UnknownP61;
|
||||
float UnknownP61F;
|
||||
int UnknownP62;
|
||||
int UnknownP63;
|
||||
int UnknownP64;
|
||||
|
@ -83,7 +83,7 @@ int loader::error(int errorCode, int captionCode)
|
||||
|
||||
void loader::default_vsi(visualStruct* visual)
|
||||
{
|
||||
visual->Unknown14Flag = 0;
|
||||
visual->Flag = 0;
|
||||
visual->Kicker.Unknown1F = 8.9999999e10f;
|
||||
visual->Kicker.SoundIndex = 0;
|
||||
visual->Unknown1F = 0.94999999f;
|
||||
@ -509,7 +509,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
|
||||
shortValSub602 = shortVal - 602;
|
||||
if (!shortValSub602)
|
||||
{
|
||||
visual2->Unknown14Flag |= 1 << *nextShortVal;
|
||||
visual2->Flag |= 1 << *nextShortVal;
|
||||
goto LABEL_31;
|
||||
}
|
||||
shortValSub1100 = shortValSub602 - 498;
|
||||
@ -537,8 +537,8 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
|
||||
}
|
||||
}
|
||||
LABEL_33:
|
||||
if (!visual2->Unknown14Flag)
|
||||
visual2->Unknown14Flag = 1;
|
||||
if (!visual2->Flag)
|
||||
visual2->Flag = 1;
|
||||
floatArr = (float*)partman::field(loader_table, groupIndexSum3, datFieldTypes::FloatArray);
|
||||
if (!floatArr)
|
||||
return 0;
|
||||
|
@ -41,7 +41,7 @@ struct __declspec(align(4)) visualStruct
|
||||
float* FloatArr;
|
||||
int SoundIndex2;
|
||||
visualKickerStruct Kicker;
|
||||
int Unknown14Flag;
|
||||
int Flag;
|
||||
int SoundIndex4;
|
||||
int SoundIndex3;
|
||||
gdrv_bitmap8* Bitmap;
|
||||
|
@ -123,8 +123,8 @@ float maths::ray_intersect_circle(ray_type* ray, circle_type* circle)
|
||||
// C - circle center
|
||||
// R - circle radius
|
||||
// L, C - O, vector between O and C
|
||||
float Lx = circle->X - ray->Origin.X;
|
||||
float Ly = circle->Y - ray->Origin.Y;
|
||||
float Lx = circle->Center.X - ray->Origin.X;
|
||||
float Ly = circle->Center.Y - ray->Origin.Y;
|
||||
|
||||
// Tca, L dot D, projection of L on D
|
||||
float Tca = Ly * ray->Direction.Y + Lx * ray->Direction.X;
|
||||
@ -191,13 +191,13 @@ void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
|
||||
}
|
||||
if (lineDirection)
|
||||
{
|
||||
line->Origin.X = v9;
|
||||
line->Origin.Y = v11;
|
||||
line->OriginX = v9;
|
||||
line->OriginY = v11;
|
||||
}
|
||||
else
|
||||
{
|
||||
line->Origin.Y = v9;
|
||||
line->Origin.X = v11;
|
||||
line->OriginY = v9;
|
||||
line->OriginX = v11;
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,27 +216,27 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
||||
{
|
||||
result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->PreComp1)
|
||||
/ perpDot);
|
||||
if (result >= -ray->Unknown7 && result <= ray->MaxDistance)
|
||||
if (result >= -ray->MinDistance && result <= ray->MaxDistance)
|
||||
{
|
||||
line->Unknown9 = result * ray->Direction.X + ray->Origin.X;
|
||||
line->CompTmp1 = result * ray->Direction.X + ray->Origin.X;
|
||||
v4 = result * ray->Direction.Y + ray->Origin.Y;
|
||||
line->Unknown10 = v4;
|
||||
if (0.0 == line->Direction.X)
|
||||
{
|
||||
if (v4 >= line->Origin.X)
|
||||
if (v4 >= line->OriginX)
|
||||
{
|
||||
v5 = v4 < line->Origin.Y;
|
||||
v6 = v4 == line->Origin.Y;
|
||||
v5 = v4 < line->OriginY;
|
||||
v6 = v4 == line->OriginY;
|
||||
if (v5 || v6)
|
||||
return result;
|
||||
return 1000000000.0;
|
||||
}
|
||||
}
|
||||
else if (line->Origin.X <= line->Unknown9)
|
||||
else if (line->OriginX <= line->CompTmp1)
|
||||
{
|
||||
v7 = line->Unknown9;
|
||||
v5 = v7 < line->Origin.Y;
|
||||
v6 = v7 == line->Origin.Y;
|
||||
v7 = line->CompTmp1;
|
||||
v5 = v7 < line->OriginY;
|
||||
v6 = v7 == line->OriginY;
|
||||
if (v5 || v6)
|
||||
return result;
|
||||
return 1000000000.0;
|
||||
@ -245,3 +245,10 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
|
||||
}
|
||||
return 1000000000.0;
|
||||
}
|
||||
|
||||
void maths::cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec)
|
||||
{
|
||||
dstVec->X = vec2->Z * vec1->Y - vec2->Y * vec1->Z;
|
||||
dstVec->Y = vec2->X * vec1->Z - vec1->X * vec2->Z;
|
||||
dstVec->Z = vec1->X * vec2->Y - vec2->X * vec1->Y;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ struct vector_type
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
};
|
||||
|
||||
|
||||
@ -17,31 +18,26 @@ struct __declspec(align(4)) rectangle_type
|
||||
|
||||
struct circle_type
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Unknown2;
|
||||
vector_type Center;
|
||||
float RadiusSq;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) ray_type
|
||||
{
|
||||
vector_type Origin;
|
||||
float Unknown2;
|
||||
vector_type Direction;
|
||||
float Unknown5;
|
||||
float MaxDistance;
|
||||
float Unknown7;
|
||||
float MinDistance;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) line_type
|
||||
{
|
||||
vector_type PerpendicularL;
|
||||
float Unknown2;
|
||||
vector_type Direction;
|
||||
float Unknown5;
|
||||
float PreComp1;
|
||||
vector_type Origin;
|
||||
float Unknown9;
|
||||
float OriginX;
|
||||
float OriginY;
|
||||
float CompTmp1;
|
||||
float Unknown10;
|
||||
float Unknown11;
|
||||
};
|
||||
@ -57,4 +53,5 @@ public:
|
||||
static float normalize_2d(vector_type* vec);
|
||||
static void line_init(line_type* line, float x0, float y0, float x1, float y1);
|
||||
static float ray_intersect_line(ray_type* ray, line_type* line);
|
||||
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user