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