Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-2-2013-Decompilation
Path: blob/main/RSDKv4/Scene3D.cpp
817 views
1
#include "RetroEngine.hpp"
2
3
int vertexCount = 0;
4
int faceCount = 0;
5
6
Matrix matFinal = Matrix();
7
Matrix matWorld = Matrix();
8
Matrix matView = Matrix();
9
Matrix matTemp = Matrix();
10
11
Face faceBuffer[FACEBUFFER_SIZE];
12
Vertex vertexBuffer[VERTEXBUFFER_SIZE];
13
Vertex vertexBufferT[VERTEXBUFFER_SIZE];
14
15
DrawListEntry3D drawList3D[FACEBUFFER_SIZE];
16
17
int projectionX = 136;
18
int projectionY = 160;
19
int fogColor = 0;
20
int fogStrength = 0;
21
22
int faceLineStart[SCREEN_YSIZE];
23
int faceLineEnd[SCREEN_YSIZE];
24
int faceLineStartU[SCREEN_YSIZE];
25
int faceLineEndU[SCREEN_YSIZE];
26
int faceLineStartV[SCREEN_YSIZE];
27
int faceLineEndV[SCREEN_YSIZE];
28
29
void SetIdentityMatrix(Matrix *matrix)
30
{
31
matrix->values[0][0] = 0x100;
32
matrix->values[0][1] = 0;
33
matrix->values[0][2] = 0;
34
matrix->values[0][3] = 0;
35
36
matrix->values[1][0] = 0;
37
matrix->values[1][1] = 0x100;
38
matrix->values[1][2] = 0;
39
matrix->values[1][3] = 0;
40
41
matrix->values[2][0] = 0;
42
matrix->values[2][1] = 0;
43
matrix->values[2][2] = 0x100;
44
matrix->values[2][3] = 0;
45
46
matrix->values[3][0] = 0;
47
matrix->values[3][1] = 0;
48
matrix->values[3][2] = 0;
49
matrix->values[3][3] = 0x100;
50
}
51
void MatrixMultiply(Matrix *matrixA, Matrix *matrixB)
52
{
53
int output[16];
54
55
for (int i = 0; i < 0x10; ++i) {
56
uint rowA = i / 4;
57
uint rowB = i % 4;
58
output[i] = (matrixA->values[rowA][3] * matrixB->values[3][rowB] >> 8) + (matrixA->values[rowA][2] * matrixB->values[2][rowB] >> 8)
59
+ (matrixA->values[rowA][1] * matrixB->values[1][rowB] >> 8) + (matrixA->values[rowA][0] * matrixB->values[0][rowB] >> 8);
60
}
61
62
for (int i = 0; i < 0x10; ++i) matrixA->values[i / 4][i % 4] = output[i];
63
}
64
void MatrixTranslateXYZ(Matrix *matrix, int XPos, int YPos, int ZPos)
65
{
66
matrix->values[0][0] = 0x100;
67
matrix->values[0][1] = 0;
68
matrix->values[0][2] = 0;
69
matrix->values[0][3] = 0;
70
71
matrix->values[1][0] = 0;
72
matrix->values[1][1] = 0x100;
73
matrix->values[1][2] = 0;
74
matrix->values[1][3] = 0;
75
76
matrix->values[2][0] = 0;
77
matrix->values[2][1] = 0;
78
matrix->values[2][2] = 0x100;
79
matrix->values[2][3] = 0;
80
81
matrix->values[3][0] = XPos;
82
matrix->values[3][1] = YPos;
83
matrix->values[3][2] = ZPos;
84
matrix->values[3][3] = 0x100;
85
}
86
void MatrixScaleXYZ(Matrix *matrix, int scaleX, int scaleY, int scaleZ)
87
{
88
matrix->values[0][0] = scaleX;
89
matrix->values[0][1] = 0;
90
matrix->values[0][2] = 0;
91
matrix->values[0][3] = 0;
92
93
matrix->values[1][0] = 0;
94
matrix->values[1][1] = scaleY;
95
matrix->values[1][2] = 0;
96
matrix->values[1][3] = 0;
97
98
matrix->values[2][0] = 0;
99
matrix->values[2][1] = 0;
100
matrix->values[2][2] = scaleZ;
101
matrix->values[2][3] = 0;
102
103
matrix->values[3][0] = 0;
104
matrix->values[3][1] = 0;
105
matrix->values[3][2] = 0;
106
matrix->values[3][3] = 0x100;
107
}
108
void MatrixRotateX(Matrix *matrix, int rotationX)
109
{
110
int sine = sin512LookupTable[rotationX & 0x1FF] >> 1;
111
int cosine = cos512LookupTable[rotationX & 0x1FF] >> 1;
112
113
matrix->values[0][0] = 0x100;
114
matrix->values[0][1] = 0;
115
matrix->values[0][2] = 0;
116
matrix->values[0][3] = 0;
117
118
matrix->values[1][0] = 0;
119
matrix->values[1][1] = cosine;
120
matrix->values[1][2] = sine;
121
matrix->values[1][3] = 0;
122
123
matrix->values[2][0] = 0;
124
matrix->values[2][1] = -sine;
125
matrix->values[2][2] = cosine;
126
matrix->values[2][3] = 0;
127
128
matrix->values[3][0] = 0;
129
matrix->values[3][1] = 0;
130
matrix->values[3][2] = 0;
131
matrix->values[3][3] = 0x100;
132
}
133
void MatrixRotateY(Matrix *matrix, int rotationY)
134
{
135
int sine = sin512LookupTable[rotationY & 0x1FF] >> 1;
136
int cosine = cos512LookupTable[rotationY & 0x1FF] >> 1;
137
138
matrix->values[0][0] = cosine;
139
matrix->values[0][1] = 0;
140
matrix->values[0][2] = sine;
141
matrix->values[0][3] = 0;
142
143
matrix->values[1][0] = 0;
144
matrix->values[1][1] = 0x100;
145
matrix->values[1][2] = 0;
146
matrix->values[1][3] = 0;
147
148
matrix->values[2][0] = -sine;
149
matrix->values[2][1] = 0;
150
matrix->values[2][2] = cosine;
151
matrix->values[2][3] = 0;
152
153
matrix->values[3][0] = 0;
154
matrix->values[3][1] = 0;
155
matrix->values[3][2] = 0;
156
matrix->values[3][3] = 0x100;
157
}
158
void MatrixRotateZ(Matrix *matrix, int rotationZ)
159
{
160
int sine = sin512LookupTable[rotationZ & 0x1FF] >> 1;
161
int cosine = cos512LookupTable[rotationZ & 0x1FF] >> 1;
162
matrix->values[0][0] = cosine;
163
matrix->values[0][1] = 0;
164
matrix->values[0][2] = sine;
165
matrix->values[0][3] = 0;
166
167
matrix->values[1][0] = 0;
168
matrix->values[1][1] = 0x100;
169
matrix->values[1][2] = 0;
170
matrix->values[1][3] = 0;
171
172
matrix->values[2][0] = -sine;
173
matrix->values[2][1] = 0;
174
matrix->values[2][2] = cosine;
175
matrix->values[2][3] = 0;
176
177
matrix->values[3][0] = 0;
178
matrix->values[3][1] = 0;
179
matrix->values[3][2] = 0;
180
matrix->values[3][3] = 0x100;
181
}
182
void MatrixRotateXYZ(Matrix *matrix, short rotationX, short rotationY, short rotationZ)
183
{
184
int sinX = sin512LookupTable[rotationX & 0x1FF] >> 1;
185
int cosX = cos512LookupTable[rotationX & 0x1FF] >> 1;
186
int sinY = sin512LookupTable[rotationY & 0x1FF] >> 1;
187
int cosY = cos512LookupTable[rotationY & 0x1FF] >> 1;
188
int sinZ = sin512LookupTable[rotationZ & 0x1FF] >> 1;
189
int cosZ = cos512LookupTable[rotationZ & 0x1FF] >> 1;
190
191
matrix->values[0][0] = (cosZ * cosY >> 8) + (sinZ * (sinY * sinX >> 8) >> 8);
192
matrix->values[0][1] = (sinZ * cosY >> 8) - (cosZ * (sinY * sinX >> 8) >> 8);
193
matrix->values[0][2] = sinY * cosX >> 8;
194
matrix->values[0][3] = 0;
195
196
matrix->values[1][0] = sinZ * -cosX >> 8;
197
matrix->values[1][1] = cosZ * cosX >> 8;
198
matrix->values[1][2] = sinX;
199
matrix->values[1][3] = 0;
200
201
matrix->values[2][0] = (sinZ * (cosY * sinX >> 8) >> 8) - (cosZ * sinY >> 8);
202
matrix->values[2][1] = (sinZ * -sinY >> 8) - (cosZ * (cosY * sinX >> 8) >> 8);
203
matrix->values[2][2] = cosY * cosX >> 8;
204
matrix->values[2][3] = 0;
205
206
matrix->values[3][0] = 0;
207
matrix->values[3][1] = 0;
208
matrix->values[3][2] = 0;
209
matrix->values[3][3] = 0x100;
210
}
211
#if !RETRO_REV00
212
void MatrixInverse(Matrix *matrix)
213
{
214
double inv[16], det;
215
double m[16];
216
for (int y = 0; y < 4; ++y) {
217
for (int x = 0; x < 4; ++x) {
218
m[(y << 2) + x] = matrix->values[y][x] / 256.0;
219
}
220
}
221
222
inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
223
224
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
225
226
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
227
228
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
229
230
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
231
232
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
233
234
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
235
236
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
237
238
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
239
240
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
241
242
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
243
244
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
245
246
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
247
248
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
249
250
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
251
252
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
253
254
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
255
256
if (det == 0)
257
return;
258
259
det = 1.0 / det;
260
261
for (int i = 0; i < 0x10; ++i) inv[i] = (int)((inv[i] * det) * 256);
262
for (int i = 0; i < 0x10; ++i) matrix->values[i / 4][i % 4] = inv[i];
263
}
264
#endif
265
void TransformVertexBuffer()
266
{
267
matFinal.values[0][0] = matWorld.values[0][0];
268
matFinal.values[0][1] = matWorld.values[0][1];
269
matFinal.values[0][2] = matWorld.values[0][2];
270
matFinal.values[0][3] = matWorld.values[0][3];
271
272
matFinal.values[1][0] = matWorld.values[1][0];
273
matFinal.values[1][1] = matWorld.values[1][1];
274
matFinal.values[1][2] = matWorld.values[1][2];
275
matFinal.values[1][3] = matWorld.values[1][3];
276
277
matFinal.values[2][0] = matWorld.values[2][0];
278
matFinal.values[2][1] = matWorld.values[2][1];
279
matFinal.values[2][2] = matWorld.values[2][2];
280
matFinal.values[2][3] = matWorld.values[2][3];
281
282
matFinal.values[3][0] = matWorld.values[3][0];
283
matFinal.values[3][1] = matWorld.values[3][1];
284
matFinal.values[3][2] = matWorld.values[3][2];
285
matFinal.values[3][3] = matWorld.values[3][3];
286
MatrixMultiply(&matFinal, &matView);
287
288
for (int v = 0; v < vertexCount; ++v) {
289
int vx = vertexBuffer[v].x;
290
int vy = vertexBuffer[v].y;
291
int vz = vertexBuffer[v].z;
292
293
vertexBufferT[v].x =
294
(vx * matFinal.values[0][0] >> 8) + (vy * matFinal.values[1][0] >> 8) + (vz * matFinal.values[2][0] >> 8) + matFinal.values[3][0];
295
vertexBufferT[v].y =
296
(vx * matFinal.values[0][1] >> 8) + (vy * matFinal.values[1][1] >> 8) + (vz * matFinal.values[2][1] >> 8) + matFinal.values[3][1];
297
vertexBufferT[v].z =
298
(vx * matFinal.values[0][2] >> 8) + (vy * matFinal.values[1][2] >> 8) + (vz * matFinal.values[2][2] >> 8) + matFinal.values[3][2];
299
}
300
}
301
void TransformVertices(Matrix *matrix, int startIndex, int endIndex)
302
{
303
for (int v = startIndex; v < endIndex; ++v) {
304
int vx = vertexBuffer[v].x;
305
int vy = vertexBuffer[v].y;
306
int vz = vertexBuffer[v].z;
307
Vertex *vert = &vertexBuffer[v];
308
vert->x = (vx * matrix->values[0][0] >> 8) + (vy * matrix->values[1][0] >> 8) + (vz * matrix->values[2][0] >> 8) + matrix->values[3][0];
309
vert->y = (vx * matrix->values[0][1] >> 8) + (vy * matrix->values[1][1] >> 8) + (vz * matrix->values[2][1] >> 8) + matrix->values[3][1];
310
vert->z = (vx * matrix->values[0][2] >> 8) + (vy * matrix->values[1][2] >> 8) + (vz * matrix->values[2][2] >> 8) + matrix->values[3][2];
311
}
312
}
313
void Sort3DDrawList()
314
{
315
for (int i = 0; i < faceCount; ++i) {
316
drawList3D[i].depth = (vertexBufferT[faceBuffer[i].d].z + vertexBufferT[faceBuffer[i].c].z + vertexBufferT[faceBuffer[i].b].z
317
+ vertexBufferT[faceBuffer[i].a].z)
318
>> 2;
319
drawList3D[i].faceID = i;
320
}
321
322
for (int i = 0; i < faceCount; ++i) {
323
for (int j = faceCount - 1; j > i; --j) {
324
if (drawList3D[j].depth > drawList3D[j - 1].depth) {
325
int faceID = drawList3D[j].faceID;
326
int depth = drawList3D[j].depth;
327
drawList3D[j].faceID = drawList3D[j - 1].faceID;
328
drawList3D[j].depth = drawList3D[j - 1].depth;
329
drawList3D[j - 1].faceID = faceID;
330
drawList3D[j - 1].depth = depth;
331
}
332
}
333
}
334
}
335
void Draw3DScene(int spriteSheetID)
336
{
337
Vertex quad[4];
338
for (int i = 0; i < faceCount; ++i) {
339
Face *face = &faceBuffer[drawList3D[i].faceID];
340
memset(quad, 0, 4 * sizeof(Vertex));
341
switch (face->flag) {
342
default: break;
343
case FACE_FLAG_TEXTURED_3D:
344
if (vertexBufferT[face->a].z > 0 && vertexBufferT[face->b].z > 0 && vertexBufferT[face->c].z > 0 && vertexBufferT[face->d].z > 0) {
345
quad[0].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->a].x / vertexBufferT[face->a].z;
346
quad[0].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->a].y / vertexBufferT[face->a].z;
347
quad[1].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->b].x / vertexBufferT[face->b].z;
348
quad[1].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->b].y / vertexBufferT[face->b].z;
349
quad[2].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->c].x / vertexBufferT[face->c].z;
350
quad[2].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->c].y / vertexBufferT[face->c].z;
351
quad[3].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->d].x / vertexBufferT[face->d].z;
352
quad[3].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->d].y / vertexBufferT[face->d].z;
353
quad[0].u = vertexBuffer[face->a].u;
354
quad[0].v = vertexBuffer[face->a].v;
355
quad[1].u = vertexBuffer[face->b].u;
356
quad[1].v = vertexBuffer[face->b].v;
357
quad[2].u = vertexBuffer[face->c].u;
358
quad[2].v = vertexBuffer[face->c].v;
359
quad[3].u = vertexBuffer[face->d].u;
360
quad[3].v = vertexBuffer[face->d].v;
361
DrawTexturedFace(quad, spriteSheetID);
362
}
363
break;
364
case FACE_FLAG_TEXTURED_2D:
365
if (vertexBufferT[face->a].z >= 0 && vertexBufferT[face->b].z >= 0 && vertexBufferT[face->c].z >= 0
366
&& vertexBufferT[face->d].z >= 0) {
367
quad[0].x = vertexBufferT[face->a].x;
368
quad[0].y = vertexBufferT[face->a].y;
369
quad[1].x = vertexBufferT[face->b].x;
370
quad[1].y = vertexBufferT[face->b].y;
371
quad[2].x = vertexBufferT[face->c].x;
372
quad[2].y = vertexBufferT[face->c].y;
373
quad[3].x = vertexBufferT[face->d].x;
374
quad[3].y = vertexBufferT[face->d].y;
375
quad[0].u = vertexBuffer[face->a].u;
376
quad[0].v = vertexBuffer[face->a].v;
377
quad[1].u = vertexBuffer[face->b].u;
378
quad[1].v = vertexBuffer[face->b].v;
379
quad[2].u = vertexBuffer[face->c].u;
380
quad[2].v = vertexBuffer[face->c].v;
381
quad[3].u = vertexBuffer[face->d].u;
382
quad[3].v = vertexBuffer[face->d].v;
383
DrawTexturedFace(quad, spriteSheetID);
384
}
385
break;
386
case FACE_FLAG_COLORED_3D:
387
if (vertexBufferT[face->a].z > 0 && vertexBufferT[face->b].z > 0 && vertexBufferT[face->c].z > 0 && vertexBufferT[face->d].z > 0) {
388
quad[0].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->a].x / vertexBufferT[face->a].z;
389
quad[0].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->a].y / vertexBufferT[face->a].z;
390
quad[1].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->b].x / vertexBufferT[face->b].z;
391
quad[1].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->b].y / vertexBufferT[face->b].z;
392
quad[2].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->c].x / vertexBufferT[face->c].z;
393
quad[2].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->c].y / vertexBufferT[face->c].z;
394
quad[3].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->d].x / vertexBufferT[face->d].z;
395
quad[3].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->d].y / vertexBufferT[face->d].z;
396
DrawFace(quad, face->color);
397
}
398
break;
399
case FACE_FLAG_COLORED_2D:
400
if (vertexBufferT[face->a].z >= 0 && vertexBufferT[face->b].z >= 0 && vertexBufferT[face->c].z >= 0
401
&& vertexBufferT[face->d].z >= 0) {
402
quad[0].x = vertexBufferT[face->a].x;
403
quad[0].y = vertexBufferT[face->a].y;
404
quad[1].x = vertexBufferT[face->b].x;
405
quad[1].y = vertexBufferT[face->b].y;
406
quad[2].x = vertexBufferT[face->c].x;
407
quad[2].y = vertexBufferT[face->c].y;
408
quad[3].x = vertexBufferT[face->d].x;
409
quad[3].y = vertexBufferT[face->d].y;
410
DrawFace(quad, face->color);
411
}
412
break;
413
case FACE_FLAG_FADED:
414
if (vertexBufferT[face->a].z > 0 && vertexBufferT[face->b].z > 0 && vertexBufferT[face->c].z > 0 && vertexBufferT[face->d].z > 0) {
415
quad[0].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->a].x / vertexBufferT[face->a].z;
416
quad[0].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->a].y / vertexBufferT[face->a].z;
417
quad[1].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->b].x / vertexBufferT[face->b].z;
418
quad[1].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->b].y / vertexBufferT[face->b].z;
419
quad[2].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->c].x / vertexBufferT[face->c].z;
420
quad[2].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->c].y / vertexBufferT[face->c].z;
421
quad[3].x = SCREEN_CENTERX + projectionX * vertexBufferT[face->d].x / vertexBufferT[face->d].z;
422
quad[3].y = SCREEN_CENTERY - projectionY * vertexBufferT[face->d].y / vertexBufferT[face->d].z;
423
424
int fogStr = 0;
425
if ((drawList3D[i].depth - 0x8000) >> 8 >= 0)
426
fogStr = (drawList3D[i].depth - 0x8000) >> 8;
427
if (fogStr > fogStrength)
428
fogStr = fogStrength;
429
430
DrawFadedFace(quad, face->color, fogColor, 0xFF - fogStr);
431
}
432
break;
433
case FACE_FLAG_TEXTURED_C:
434
if (vertexBufferT[face->a].z > 0) {
435
// [face->a].uv == sprite center
436
// [face->b].uv == ???
437
// [face->c].uv == sprite extend (how far to each edge X & Y)
438
// [face->d].uv == unused
439
440
quad[0].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x - vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
441
quad[0].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y + vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
442
quad[1].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x + vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
443
quad[1].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y + vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
444
quad[2].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x - vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
445
quad[2].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y - vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
446
quad[3].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x + vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
447
quad[3].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y - vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
448
449
quad[0].u = vertexBuffer[face->a].u - vertexBuffer[face->c].u;
450
quad[0].v = vertexBuffer[face->a].v - vertexBuffer[face->c].v;
451
quad[1].u = vertexBuffer[face->a].u + vertexBuffer[face->c].u;
452
quad[1].v = vertexBuffer[face->a].v - vertexBuffer[face->c].v;
453
quad[2].u = vertexBuffer[face->a].u - vertexBuffer[face->c].u;
454
quad[2].v = vertexBuffer[face->a].v + vertexBuffer[face->c].v;
455
quad[3].u = vertexBuffer[face->a].u + vertexBuffer[face->c].u;
456
quad[3].v = vertexBuffer[face->a].v + vertexBuffer[face->c].v;
457
458
DrawTexturedFace(quad, spriteSheetID);
459
}
460
break;
461
case FACE_FLAG_TEXTURED_C_BLEND:
462
if (vertexBufferT[face->a].z > 0) {
463
// See above, its the same just blended
464
465
quad[0].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x - vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
466
quad[0].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y + vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
467
quad[1].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x + vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
468
quad[1].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y + vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
469
quad[2].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x - vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
470
quad[2].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y - vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
471
quad[3].x = SCREEN_CENTERX + projectionX * (vertexBufferT[face->a].x + vertexBuffer[face->b].u) / vertexBufferT[face->a].z;
472
quad[3].y = SCREEN_CENTERY - projectionY * (vertexBufferT[face->a].y - vertexBuffer[face->b].v) / vertexBufferT[face->a].z;
473
474
quad[0].u = vertexBuffer[face->a].u - vertexBuffer[face->c].u;
475
quad[0].v = vertexBuffer[face->a].v - vertexBuffer[face->c].v;
476
quad[1].u = vertexBuffer[face->a].u + vertexBuffer[face->c].u;
477
quad[1].v = vertexBuffer[face->a].v - vertexBuffer[face->c].v;
478
quad[2].u = vertexBuffer[face->a].u - vertexBuffer[face->c].u;
479
quad[2].v = vertexBuffer[face->a].v + vertexBuffer[face->c].v;
480
quad[3].u = vertexBuffer[face->a].u + vertexBuffer[face->c].u;
481
quad[3].v = vertexBuffer[face->a].v + vertexBuffer[face->c].v;
482
483
DrawTexturedFaceBlended(quad, spriteSheetID);
484
}
485
break;
486
case FACE_FLAG_3DSPRITE:
487
if (vertexBufferT[face->a].z > 0) {
488
int xpos = SCREEN_CENTERX + projectionX * vertexBufferT[face->a].x / vertexBufferT[face->a].z;
489
int ypos = SCREEN_CENTERY - projectionY * vertexBufferT[face->a].y / vertexBufferT[face->a].z;
490
491
ObjectScript *scriptInfo = &objectScriptList[vertexBuffer[face->a].u];
492
SpriteFrame *frame = &scriptFrames[scriptInfo->frameListOffset + vertexBuffer[face->b].u];
493
494
switch (vertexBuffer[face->a].v) {
495
case FX_SCALE:
496
DrawSpriteScaled(vertexBuffer[face->b].v, xpos, ypos, -frame->pivotX, -frame->pivotY, vertexBuffer[face->c].u,
497
vertexBuffer[face->c].u, frame->width, frame->height, frame->sprX, frame->sprY,
498
scriptInfo->spriteSheetID);
499
break;
500
case FX_ROTATE:
501
DrawSpriteRotated(vertexBuffer[face->b].v, xpos, ypos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY,
502
frame->width, frame->height, vertexBuffer[face->c].v, scriptInfo->spriteSheetID);
503
break;
504
case FX_ROTOZOOM:
505
DrawSpriteRotozoom(vertexBuffer[face->b].v, xpos, ypos, -frame->pivotX, -frame->pivotY, frame->sprX, frame->sprY,
506
frame->width, frame->height, vertexBuffer[face->c].v, vertexBuffer[face->c].u,
507
scriptInfo->spriteSheetID);
508
break;
509
}
510
}
511
break;
512
}
513
}
514
}
515
516
void ProcessScanEdge(Vertex *vertA, Vertex *vertB)
517
{
518
int bottom, top;
519
520
if (vertA->y == vertB->y)
521
return;
522
if (vertA->y >= vertB->y) {
523
top = vertB->y;
524
bottom = vertA->y + 1;
525
}
526
else {
527
top = vertA->y;
528
bottom = vertB->y + 1;
529
}
530
if (top > SCREEN_YSIZE - 1 || bottom < 0)
531
return;
532
if (bottom > SCREEN_YSIZE)
533
bottom = SCREEN_YSIZE;
534
int fullX = vertA->x << 16;
535
int deltaX = ((vertB->x - vertA->x) << 16) / (vertB->y - vertA->y);
536
if (top < 0) {
537
fullX -= top * deltaX;
538
top = 0;
539
}
540
for (int i = top; i < bottom; ++i) {
541
int trueX = fullX >> 16;
542
if (trueX < faceLineStart[i])
543
faceLineStart[i] = trueX;
544
if (trueX > faceLineEnd[i])
545
faceLineEnd[i] = trueX;
546
fullX += deltaX;
547
}
548
}
549
void ProcessScanEdgeUV(Vertex *vertA, Vertex *vertB)
550
{
551
int bottom, top;
552
553
if (vertA->y == vertB->y)
554
return;
555
if (vertA->y >= vertB->y) {
556
top = vertB->y;
557
bottom = vertA->y + 1;
558
}
559
else {
560
top = vertA->y;
561
bottom = vertB->y + 1;
562
}
563
if (top > SCREEN_YSIZE - 1 || bottom < 0)
564
return;
565
if (bottom > SCREEN_YSIZE)
566
bottom = SCREEN_YSIZE;
567
568
int fullX = vertA->x << 16;
569
int fullU = vertA->u << 16;
570
int fullV = vertA->v << 16;
571
int deltaX = ((vertB->x - vertA->x) << 16) / (vertB->y - vertA->y);
572
573
int deltaU = 0;
574
if (vertA->u != vertB->u)
575
deltaU = ((vertB->u - vertA->u) << 16) / (vertB->y - vertA->y);
576
577
int deltaV = 0;
578
if (vertA->v != vertB->v) {
579
deltaV = ((vertB->v - vertA->v) << 16) / (vertB->y - vertA->y);
580
}
581
582
if (top < 0) {
583
fullX -= top * deltaX;
584
fullU -= top * deltaU;
585
fullV -= top * deltaV;
586
top = 0;
587
}
588
for (int i = top; i < bottom; ++i) {
589
int trueX = fullX >> 16;
590
if (trueX < faceLineStart[i]) {
591
faceLineStart[i] = trueX;
592
faceLineStartU[i] = fullU;
593
faceLineStartV[i] = fullV;
594
}
595
if (trueX > faceLineEnd[i]) {
596
faceLineEnd[i] = trueX;
597
faceLineEndU[i] = fullU;
598
faceLineEndV[i] = fullV;
599
}
600
fullX += deltaX;
601
fullU += deltaU;
602
fullV += deltaV;
603
}
604
}
605
606