forked from iscle/SpaceCadetPinball
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathTBall.cpp
138 lines (120 loc) · 3.09 KB
/
TBall.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "pch.h"
#include "TBall.h"
#include "fullscrn.h"
#include "loader.h"
#include "maths.h"
#include "pb.h"
#include "proj.h"
#include "render.h"
#include "TPinballTable.h"
TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
{
visualStruct visual{};
char ballGroupName[10]{"ball"};
TimeNow = 0.0;
RayMaxDistance = 0.0;
ActiveFlag = 1;
CollisionComp = nullptr;
EdgeCollisionCount = 0;
TimeDelta = 0.0;
FieldFlag = 1;
CollisionFlag = 0;
Speed = 0.0;
Acceleration.Y = 0.0;
Acceleration.X = 0.0;
InvAcceleration.Y = 1000000000.0;
InvAcceleration.X = 1000000000.0;
Position.X = 0.0;
Position.Y = 0.0;
ListBitmap = new std::vector<gdrv_bitmap8*>();
/*Full tilt: ball is ballN, where N[0,2] resolution*/
if (pb::FullTiltMode)
ballGroupName[4] = '0' + fullscrn::GetResolution();
auto groupIndex = loader::query_handle(ballGroupName);
Offset = *loader::query_float_attribute(groupIndex, 0, 500);
auto visualCount = loader::query_visual_states(groupIndex);
for (auto index = 0; index < visualCount; ++index)
{
loader::query_visual(groupIndex, index, &visual);
if (ListBitmap)
ListBitmap->push_back(visual.Bitmap);
auto visVec = reinterpret_cast<vector3*>(loader::query_float_attribute(groupIndex, index, 501));
auto zDepth = proj::z_distance(visVec);
VisualZArray[index] = zDepth;
}
RenderSprite = render::create_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr);
PinballTable->CollisionCompOffset = Offset;
Position.Z = Offset;
}
void TBall::Repaint()
{
int pos2D[2];
if (CollisionFlag)
{
Position.Z =
CollisionOffset.X * Position.X +
CollisionOffset.Y * Position.Y +
Offset + CollisionOffset.Z;
}
proj::xform_to_2d(&Position, pos2D);
auto zDepth = proj::z_distance(&Position);
auto zArrPtr = VisualZArray;
auto index = 0u;
for (; index < ListBitmap->size() - 1; ++index, zArrPtr++)
{
if (*zArrPtr <= zDepth) break;
}
auto bmp = ListBitmap->at(index);
render::ball_set(
RenderSprite,
bmp,
zDepth,
pos2D[0] - bmp->Width / 2,
pos2D[1] - bmp->Height / 2);
}
void TBall::not_again(TEdgeSegment* edge)
{
if (EdgeCollisionCount < 5)
{
Collisions[EdgeCollisionCount] = edge;
++EdgeCollisionCount;
}
}
bool TBall::already_hit(TEdgeSegment* edge)
{
for (int i = 0; i < EdgeCollisionCount; i++)
{
if (Collisions[i] == edge)
return true;
}
return false;
}
int TBall::Message(int code, float value)
{
if (code == 1024)
{
render::ball_set(RenderSprite, nullptr, 0.0, 0, 0);
Position.X = 0.0;
CollisionComp = nullptr;
Position.Y = 0.0;
ActiveFlag = 0;
CollisionFlag = 0;
FieldFlag = 1;
Acceleration.Y = 0.0;
Position.Z = Offset;
Acceleration.X = 0.0;
Speed = 0.0;
RayMaxDistance = 0.0;
}
return 0;
}
void TBall::throw_ball(TBall* ball, vector3* acceleration, float angleMult, float speedMult1, float speedMult2)
{
ball->CollisionComp = nullptr;
ball->Acceleration = *acceleration;
float rnd = RandFloat();
float angle = (1.0f - (rnd + rnd)) * angleMult;
maths::RotateVector(ball->Acceleration, angle);
rnd = RandFloat();
ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
}