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