Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Rubberduckycooly
GitHub Repository: Rubberduckycooly/RSDKv5-Decompilation
Path: blob/master/RSDKv5/RSDK/Graphics/Scene3D.cpp
1163 views
1
#include "RSDK/Core/RetroEngine.hpp"
2
3
using namespace RSDK;
4
5
#if RETRO_REV0U
6
#include "Legacy/Scene3DLegacy.cpp"
7
#endif
8
9
Model RSDK::modelList[MODEL_COUNT];
10
Scene3D RSDK::scene3DList[SCENE3D_COUNT];
11
12
ScanEdge RSDK::scanEdgeBuffer[SCREEN_YSIZE * 2];
13
14
enum ModelFlags {
15
MODEL_NOFLAGS = 0,
16
MODEL_USENORMALS = 1 << 0,
17
MODEL_USETEXTURES = 1 << 1,
18
MODEL_USECOLOURS = 1 << 2,
19
};
20
21
void RSDK::ProcessScanEdge(int32 x1, int32 y1, int32 x2, int32 y2)
22
{
23
int32 ix1 = FROM_FIXED(x1);
24
int32 iy1 = FROM_FIXED(y1);
25
int32 ix2 = FROM_FIXED(x2);
26
int32 iy2 = FROM_FIXED(y2);
27
28
int32 top = FROM_FIXED(y1);
29
if (iy1 != iy2) {
30
if (iy1 > iy2) {
31
top = FROM_FIXED(y2);
32
ix1 = FROM_FIXED(x2);
33
ix2 = FROM_FIXED(x1);
34
iy1 = FROM_FIXED(y2);
35
iy2 = FROM_FIXED(y1);
36
}
37
38
int32 bottom = iy2 + 1;
39
if (top < currentScreen->clipBound_Y2 && bottom >= currentScreen->clipBound_Y1) {
40
if (bottom > currentScreen->clipBound_Y2)
41
bottom = currentScreen->clipBound_Y2;
42
int32 scanPos = TO_FIXED(ix1);
43
int32 delta = TO_FIXED(ix2 - ix1) / (iy2 - iy1);
44
if (top < 0) {
45
scanPos -= top * delta;
46
top = 0;
47
}
48
49
ScanEdge *edge = &scanEdgeBuffer[top];
50
for (int32 i = top; i < bottom; ++i) {
51
int32 scanX = scanPos >> 16;
52
if (scanX < edge->start)
53
edge->start = scanX;
54
if (scanX > edge->end)
55
edge->end = scanX;
56
scanPos += delta;
57
++edge;
58
}
59
}
60
}
61
}
62
63
void RSDK::ProcessScanEdgeClr(uint32 c1, uint32 c2, int32 x1, int32 y1, int32 x2, int32 y2)
64
{
65
int32 iy1 = FROM_FIXED(y1);
66
int32 iy2 = FROM_FIXED(y2);
67
int32 ix1 = FROM_FIXED(x1);
68
int32 ix2 = FROM_FIXED(x2);
69
70
int32 top = FROM_FIXED(y1);
71
uint32 color1 = c1;
72
uint32 color2 = c2;
73
if (iy1 != iy2) {
74
if (iy1 > iy2) {
75
top = FROM_FIXED(y2);
76
ix1 = FROM_FIXED(x2);
77
ix2 = FROM_FIXED(x1);
78
iy1 = FROM_FIXED(y2);
79
iy2 = FROM_FIXED(y1);
80
color1 = c2;
81
color2 = c1;
82
}
83
84
int32 bottom = iy2 + 1;
85
if (top < currentScreen->clipBound_Y2 && bottom >= currentScreen->clipBound_Y1) {
86
if (bottom > currentScreen->clipBound_Y2)
87
bottom = currentScreen->clipBound_Y2;
88
89
int32 size = iy2 - iy1;
90
int32 scanX = TO_FIXED(ix1);
91
int32 deltaX = TO_FIXED(ix2 - ix1) / size;
92
93
int32 c1R = (color1 & 0xFF0000);
94
int32 c2R = (color2 & 0xFF0000);
95
int32 scanR = c1R;
96
97
int32 deltaR = 0;
98
if (c1R != c2R)
99
deltaR = (c2R - c1R) / size;
100
101
int32 c1G = (color1 & 0x00FF00) << 8;
102
int32 c2G = (color2 & 0x00FF00) << 8;
103
int32 scanG = c1G;
104
105
int32 deltaG = 0;
106
if (c1G != c2G)
107
deltaG = (c2G - c1G) / size;
108
109
int32 c1B = (color1 & 0x0000FF) << 16;
110
int32 c2B = (color2 & 0x0000FF) << 16;
111
int32 scanB = c1B;
112
113
int32 deltaB = 0;
114
if (c1B != c2B)
115
deltaB = (c2B - c1B) / size;
116
117
if (top < 0) {
118
scanX -= top * deltaX;
119
120
scanR -= top * deltaR;
121
scanG -= top * deltaG;
122
scanB -= top * deltaB;
123
124
top = 0;
125
}
126
127
ScanEdge *edge = &scanEdgeBuffer[top];
128
for (int32 i = top; i < bottom; ++i) {
129
if (FROM_FIXED(scanX) < edge->start) {
130
edge->start = FROM_FIXED(scanX);
131
132
edge->startR = scanR;
133
edge->startG = scanG;
134
edge->startB = scanB;
135
}
136
137
if (FROM_FIXED(scanX) > edge->end) {
138
edge->end = FROM_FIXED(scanX);
139
140
edge->endR = scanR;
141
edge->endG = scanG;
142
edge->endB = scanB;
143
}
144
145
scanX += deltaX;
146
147
scanR += deltaR;
148
scanG += deltaG;
149
scanB += deltaB;
150
151
++edge;
152
}
153
}
154
}
155
}
156
157
void RSDK::SetIdentityMatrix(Matrix *matrix)
158
{
159
matrix->values[0][0] = 0x100;
160
matrix->values[1][0] = 0;
161
matrix->values[2][0] = 0;
162
matrix->values[3][0] = 0;
163
matrix->values[0][1] = 0;
164
matrix->values[1][1] = 0x100;
165
matrix->values[2][1] = 0;
166
matrix->values[3][1] = 0;
167
matrix->values[0][2] = 0;
168
matrix->values[1][2] = 0;
169
matrix->values[2][2] = 0x100;
170
matrix->values[3][2] = 0;
171
matrix->values[0][3] = 0;
172
matrix->values[1][3] = 0;
173
matrix->values[2][3] = 0;
174
matrix->values[3][3] = 0x100;
175
}
176
void RSDK::MatrixMultiply(Matrix *dest, Matrix *matrixA, Matrix *matrixB)
177
{
178
int32 result[4][4];
179
memset(result, 0, 4 * 4 * sizeof(int32));
180
181
for (int32 i = 0; i < 0x10; ++i) {
182
uint32 rowA = i / 4;
183
uint32 rowB = i % 4;
184
result[rowB][rowA] = (matrixA->values[3][rowA] * matrixB->values[rowB][3] >> 8) + (matrixA->values[2][rowA] * matrixB->values[rowB][2] >> 8)
185
+ (matrixA->values[1][rowA] * matrixB->values[rowB][1] >> 8)
186
+ (matrixA->values[0][rowA] * matrixB->values[rowB][0] >> 8);
187
}
188
189
for (int32 i = 0; i < 0x10; ++i) {
190
uint32 rowA = i / 4;
191
uint32 rowB = i % 4;
192
dest->values[rowB][rowA] = result[rowB][rowA];
193
}
194
}
195
void RSDK::MatrixTranslateXYZ(Matrix *matrix, int32 x, int32 y, int32 z, bool32 setIdentity)
196
{
197
if (setIdentity) {
198
matrix->values[0][0] = 0x100;
199
matrix->values[1][0] = 0;
200
matrix->values[2][0] = 0;
201
matrix->values[0][1] = 0;
202
matrix->values[1][1] = 0x100;
203
matrix->values[2][1] = 0;
204
matrix->values[0][2] = 0;
205
matrix->values[1][2] = 0;
206
matrix->values[2][2] = 0x100;
207
matrix->values[3][0] = 0;
208
matrix->values[3][1] = 0;
209
matrix->values[3][2] = 0;
210
matrix->values[3][3] = 0x100;
211
}
212
213
matrix->values[0][3] = x >> 8;
214
matrix->values[1][3] = y >> 8;
215
matrix->values[2][3] = z >> 8;
216
}
217
void RSDK::MatrixScaleXYZ(Matrix *matrix, int32 scaleX, int32 scaleY, int32 scaleZ)
218
{
219
matrix->values[0][0] = scaleX;
220
matrix->values[1][0] = 0;
221
matrix->values[2][0] = 0;
222
matrix->values[3][0] = 0;
223
matrix->values[0][1] = 0;
224
matrix->values[1][1] = scaleY;
225
matrix->values[2][1] = 0;
226
matrix->values[3][1] = 0;
227
matrix->values[0][2] = 0;
228
matrix->values[1][2] = 0;
229
matrix->values[2][2] = scaleZ;
230
matrix->values[3][2] = 0;
231
matrix->values[0][3] = 0;
232
matrix->values[1][3] = 0;
233
matrix->values[2][3] = 0;
234
matrix->values[3][3] = 0x100;
235
}
236
void RSDK::MatrixRotateX(Matrix *matrix, int16 rotationX)
237
{
238
int32 sine = sin1024LookupTable[rotationX & 0x3FF] >> 2;
239
int32 cosine = cos1024LookupTable[rotationX & 0x3FF] >> 2;
240
241
matrix->values[0][0] = 0x100;
242
matrix->values[1][0] = 0;
243
matrix->values[2][0] = 0;
244
matrix->values[3][0] = 0;
245
matrix->values[0][1] = 0;
246
matrix->values[1][1] = cosine;
247
matrix->values[2][1] = sine;
248
matrix->values[3][1] = 0;
249
matrix->values[0][2] = 0;
250
matrix->values[1][2] = -sine;
251
matrix->values[2][2] = cosine;
252
matrix->values[3][2] = 0;
253
matrix->values[0][3] = 0;
254
matrix->values[1][3] = 0;
255
matrix->values[2][3] = 0;
256
matrix->values[3][3] = 0x100;
257
}
258
void RSDK::MatrixRotateY(Matrix *matrix, int16 rotationY)
259
{
260
int32 sine = sin1024LookupTable[rotationY & 0x3FF] >> 2;
261
int32 cosine = cos1024LookupTable[rotationY & 0x3FF] >> 2;
262
matrix->values[0][0] = cosine;
263
matrix->values[1][0] = 0;
264
matrix->values[2][0] = sine;
265
matrix->values[3][0] = 0;
266
matrix->values[0][1] = 0;
267
matrix->values[1][1] = 0x100;
268
matrix->values[2][1] = 0;
269
matrix->values[3][1] = 0;
270
matrix->values[0][2] = -sine;
271
matrix->values[1][2] = 0;
272
matrix->values[2][2] = cosine;
273
matrix->values[3][2] = 0;
274
matrix->values[0][3] = 0;
275
matrix->values[1][3] = 0;
276
matrix->values[2][3] = 0;
277
matrix->values[3][3] = 0x100;
278
}
279
void RSDK::MatrixRotateZ(Matrix *matrix, int16 rotationZ)
280
{
281
int32 sine = sin1024LookupTable[rotationZ & 0x3FF] >> 2;
282
int32 cosine = cos1024LookupTable[rotationZ & 0x3FF] >> 2;
283
matrix->values[0][0] = cosine;
284
matrix->values[1][0] = -sine;
285
matrix->values[2][0] = 0;
286
matrix->values[3][0] = 0;
287
matrix->values[0][1] = sine;
288
matrix->values[1][1] = cosine;
289
matrix->values[2][1] = 0;
290
matrix->values[3][1] = 0;
291
matrix->values[0][2] = 0;
292
matrix->values[1][2] = 0;
293
matrix->values[2][2] = 0x100;
294
matrix->values[3][2] = 0;
295
matrix->values[0][3] = 0;
296
matrix->values[1][3] = 0;
297
matrix->values[2][3] = 0;
298
matrix->values[3][3] = 0x100;
299
}
300
void RSDK::MatrixRotateXYZ(Matrix *matrix, int16 rotationX, int16 rotationY, int16 rotationZ)
301
{
302
int32 sinX = sin1024LookupTable[rotationX & 0x3FF] >> 2;
303
int32 cosX = cos1024LookupTable[rotationX & 0x3FF] >> 2;
304
int32 sinY = sin1024LookupTable[rotationY & 0x3FF] >> 2;
305
int32 cosY = cos1024LookupTable[rotationY & 0x3FF] >> 2;
306
int32 sinZ = sin1024LookupTable[rotationZ & 0x3FF] >> 2;
307
int32 cosZ = cos1024LookupTable[rotationZ & 0x3FF] >> 2;
308
309
matrix->values[0][0] = (cosZ * cosY >> 8) + (sinZ * (sinY * sinX >> 8) >> 8);
310
matrix->values[0][1] = -(sinZ * cosX) >> 8;
311
matrix->values[0][2] = (sinZ * (cosY * sinX >> 8) >> 8) - (cosZ * sinY >> 8);
312
matrix->values[0][3] = 0;
313
matrix->values[1][0] = (sinZ * cosY >> 8) - (cosZ * (sinY * sinX >> 8) >> 8);
314
matrix->values[1][1] = cosZ * cosX >> 8;
315
matrix->values[1][2] = (-(sinZ * sinY) >> 8) - (cosZ * (cosY * sinX >> 8) >> 8);
316
matrix->values[1][3] = 0;
317
matrix->values[2][0] = sinY * cosX >> 8;
318
matrix->values[2][1] = sinX;
319
matrix->values[2][2] = cosY * cosX >> 8;
320
matrix->values[2][3] = 0;
321
matrix->values[3][0] = 0;
322
matrix->values[3][1] = 0;
323
matrix->values[3][2] = 0;
324
matrix->values[3][3] = 0x100;
325
}
326
void RSDK::MatrixInverse(Matrix *dest, Matrix *matrix)
327
{
328
double inv[16], det;
329
double m[16];
330
for (int32 y = 0; y < 4; ++y) {
331
for (int32 x = 0; x < 4; ++x) {
332
m[(y << 2) + x] = matrix->values[y][x] / 256.0;
333
}
334
}
335
336
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];
337
338
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];
339
340
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];
341
342
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];
343
344
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];
345
346
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];
347
348
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];
349
350
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];
351
352
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];
353
354
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];
355
356
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];
357
358
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];
359
360
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];
361
362
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];
363
364
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];
365
366
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];
367
368
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
369
370
if (det == 0)
371
return;
372
373
det = 1.0 / det;
374
375
for (int32 i = 0; i < 0x10; ++i) inv[i] = (int32)((inv[i] * det) * 256);
376
for (int32 i = 0; i < 0x10; ++i) dest->values[i / 4][i % 4] = (int32)inv[i];
377
}
378
379
uint16 RSDK::LoadMesh(const char *filename, uint8 scope)
380
{
381
if (!scope || scope > SCOPE_STAGE)
382
return -1;
383
384
char fullFilePath[0x100];
385
sprintf_s(fullFilePath, sizeof(fullFilePath), "Data/Meshes/%s", filename);
386
387
RETRO_HASH_MD5(hash);
388
GEN_HASH_MD5(fullFilePath, hash);
389
390
for (int32 i = 0; i < MODEL_COUNT; ++i) {
391
if (HASH_MATCH_MD5(hash, modelList[i].hash)) {
392
return i;
393
}
394
}
395
396
uint16 id = -1;
397
for (id = 0; id < MODEL_COUNT; ++id) {
398
if (modelList[id].scope == SCOPE_NONE)
399
break;
400
}
401
402
if (id >= MODEL_COUNT)
403
return -1;
404
405
Model *model = &modelList[id];
406
FileInfo info;
407
InitFileInfo(&info);
408
if (LoadFile(&info, fullFilePath, FMODE_RB)) {
409
uint32 sig = ReadInt32(&info, false);
410
411
if (sig != RSDK_SIGNATURE_MDL) {
412
CloseFile(&info);
413
return -1;
414
}
415
416
model->scope = scope;
417
HASH_COPY_MD5(model->hash, hash);
418
419
model->flags = ReadInt8(&info);
420
model->faceVertCount = ReadInt8(&info);
421
422
model->vertCount = ReadInt16(&info);
423
model->frameCount = ReadInt16(&info);
424
425
AllocateStorage((void **)&model->vertices, sizeof(ModelVertex) * model->vertCount * model->frameCount, DATASET_STG, true);
426
if (model->flags & MODEL_USETEXTURES)
427
AllocateStorage((void **)&model->texCoords, sizeof(TexCoord) * model->vertCount, DATASET_STG, true);
428
if (model->flags & MODEL_USECOLOURS)
429
AllocateStorage((void **)&model->colors, sizeof(Color) * model->vertCount, DATASET_STG, true);
430
431
if (model->flags & MODEL_USETEXTURES) {
432
for (int32 v = 0; v < model->vertCount; ++v) {
433
model->texCoords[v].x = ReadSingle(&info);
434
model->texCoords[v].y = ReadSingle(&info);
435
}
436
}
437
438
if (model->flags & MODEL_USECOLOURS) {
439
for (int32 v = 0; v < model->vertCount; ++v) {
440
model->colors[v].color = ReadInt32(&info, false);
441
}
442
}
443
444
model->indexCount = ReadInt16(&info);
445
AllocateStorage((void **)&model->indices, sizeof(uint16) * model->indexCount, DATASET_STG, true);
446
for (int32 i = 0; i < model->indexCount; ++i) model->indices[i] = ReadInt16(&info);
447
448
for (int32 f = 0; f < model->frameCount; ++f) {
449
for (int32 v = 0; v < model->vertCount; ++v) {
450
model->vertices[(f * model->vertCount) + v].x = (int32)(ReadSingle(&info) * 0x100);
451
model->vertices[(f * model->vertCount) + v].y = (int32)(ReadSingle(&info) * 0x100);
452
model->vertices[(f * model->vertCount) + v].z = (int32)(ReadSingle(&info) * 0x100);
453
454
model->vertices[(f * model->vertCount) + v].nx = 0;
455
model->vertices[(f * model->vertCount) + v].ny = 0;
456
model->vertices[(f * model->vertCount) + v].nz = 0;
457
if (model->flags & MODEL_USENORMALS) {
458
model->vertices[(f * model->vertCount) + v].nx = (int32)(ReadSingle(&info) * 0x10000);
459
model->vertices[(f * model->vertCount) + v].ny = (int32)(ReadSingle(&info) * 0x10000);
460
model->vertices[(f * model->vertCount) + v].nz = (int32)(ReadSingle(&info) * 0x10000);
461
}
462
}
463
}
464
465
CloseFile(&info);
466
return id;
467
}
468
return -1;
469
}
470
uint16 RSDK::Create3DScene(const char *name, uint16 vertexLimit, uint8 scope)
471
{
472
if (!scope || scope > SCOPE_STAGE)
473
return -1;
474
475
RETRO_HASH_MD5(hash);
476
GEN_HASH_MD5(name, hash);
477
478
for (int32 i = 0; i < SCENE3D_COUNT; ++i) {
479
if (HASH_MATCH_MD5(hash, scene3DList[i].hash)) {
480
return i;
481
}
482
}
483
484
uint16 id = -1;
485
for (id = 0; id < SCENE3D_COUNT; ++id) {
486
if (scene3DList[id].scope == SCOPE_NONE)
487
break;
488
}
489
490
if (id >= SCENE3D_COUNT)
491
return -1;
492
493
Scene3D *scene = &scene3DList[id];
494
495
if (vertexLimit > SCENE3D_VERT_COUNT || !vertexLimit)
496
vertexLimit = SCENE3D_VERT_COUNT;
497
498
scene->scope = scope;
499
HASH_COPY_MD5(scene->hash, hash);
500
scene->vertLimit = vertexLimit;
501
scene->faceCount = 6;
502
503
scene->projectionX = 8;
504
scene->projectionY = 8;
505
AllocateStorage((void **)&scene->vertices, sizeof(Scene3DVertex) * vertexLimit, DATASET_STG, true);
506
AllocateStorage((void **)&scene->normals, sizeof(Scene3DVertex) * vertexLimit, DATASET_STG, true);
507
AllocateStorage((void **)&scene->faceVertCounts, sizeof(uint8) * vertexLimit, DATASET_STG, true);
508
AllocateStorage((void **)&scene->faceBuffer, sizeof(Scene3DFace) * vertexLimit, DATASET_STG, true);
509
510
return id;
511
}
512
void RSDK::AddModelToScene(uint16 modelFrames, uint16 sceneIndex, uint8 drawMode, Matrix *matWorld, Matrix *matNormals, color color)
513
{
514
if (modelFrames < MODEL_COUNT && sceneIndex < SCENE3D_COUNT) {
515
if (matWorld) {
516
Model *mdl = &modelList[modelFrames];
517
Scene3D *scn = &scene3DList[sceneIndex];
518
uint16 *indices = mdl->indices;
519
int32 vertID = scn->vertexCount;
520
uint8 *faceVertCounts = &scn->faceVertCounts[scn->faceCount];
521
int32 indCnt = mdl->indexCount;
522
if (scn->vertLimit - vertID >= indCnt) {
523
scn->vertexCount += mdl->indexCount;
524
scn->drawMode = drawMode;
525
scn->faceCount += indCnt / mdl->faceVertCount;
526
527
int32 i = 0;
528
int32 f = 0;
529
switch (mdl->flags) {
530
default:
531
case MODEL_NOFLAGS:
532
case MODEL_USECOLOURS:
533
for (; i < mdl->indexCount;) {
534
faceVertCounts[f++] = mdl->faceVertCount;
535
536
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
537
ModelVertex *modelVert = &mdl->vertices[indices[i++]];
538
Scene3DVertex *vertex = &scn->vertices[vertID++];
539
540
vertex->x = matWorld->values[0][3] + (modelVert->z * matWorld->values[0][2] >> 8)
541
+ (matWorld->values[0][0] * modelVert->x >> 8) + (matWorld->values[0][1] * modelVert->y >> 8);
542
vertex->y = matWorld->values[1][3] + (modelVert->y * matWorld->values[1][1] >> 8)
543
+ (modelVert->z * matWorld->values[1][2] >> 8) + (matWorld->values[1][0] * modelVert->x >> 8);
544
vertex->z = matWorld->values[2][3] + ((modelVert->x * matWorld->values[2][0]) >> 8)
545
+ ((matWorld->values[2][2] * modelVert->z >> 8) + (matWorld->values[2][1] * modelVert->y >> 8));
546
547
vertex->color = color;
548
}
549
}
550
break;
551
552
case MODEL_USENORMALS:
553
if (matNormals) {
554
for (; i < mdl->indexCount;) {
555
faceVertCounts[f++] = mdl->faceVertCount;
556
557
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
558
ModelVertex *modelVert = &mdl->vertices[indices[i++]];
559
Scene3DVertex *vertex = &scn->vertices[vertID++];
560
561
vertex->x = matWorld->values[0][3] + (modelVert->z * matWorld->values[0][2] >> 8)
562
+ (modelVert->x * matWorld->values[0][0] >> 8) + (modelVert->y * matWorld->values[0][1] >> 8);
563
vertex->y = matWorld->values[1][3] + (modelVert->y * matWorld->values[1][1] >> 8)
564
+ (matWorld->values[1][0] * modelVert->x >> 8) + (modelVert->z * matWorld->values[1][2] >> 8);
565
vertex->z = matWorld->values[2][3] + (modelVert->x * matWorld->values[2][0] >> 8)
566
+ (matWorld->values[2][2] * modelVert->z >> 8) + (matWorld->values[2][1] * modelVert->y >> 8);
567
568
vertex->nx = (modelVert->nz * matNormals->values[0][2] >> 8) + (modelVert->nx * matNormals->values[0][0] >> 8)
569
+ (matNormals->values[0][1] * modelVert->ny >> 8);
570
vertex->ny = (modelVert->ny * matNormals->values[1][1] >> 8) + (modelVert->nz * matNormals->values[1][2] >> 8)
571
+ (modelVert->nx * matNormals->values[1][0] >> 8);
572
vertex->nz =
573
((modelVert->ny * matNormals->values[2][1]) >> 8)
574
+ ((matNormals->values[2][0] * modelVert->nx >> 8) + (modelVert->nz * matNormals->values[2][2] >> 8));
575
576
vertex->color = color;
577
}
578
}
579
}
580
else {
581
for (; i < mdl->indexCount;) {
582
faceVertCounts[f++] = mdl->faceVertCount;
583
584
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
585
ModelVertex *modelVert = &mdl->vertices[indices[i++]];
586
Scene3DVertex *vertex = &scn->vertices[vertID++];
587
588
vertex->x = matWorld->values[0][3] + (modelVert->z * matWorld->values[0][2] >> 8)
589
+ (matWorld->values[0][0] * modelVert->x >> 8) + (matWorld->values[0][1] * modelVert->y >> 8);
590
vertex->y = matWorld->values[1][3] + (modelVert->y * matWorld->values[1][1] >> 8)
591
+ (modelVert->z * matWorld->values[1][2] >> 8) + (matWorld->values[1][0] * modelVert->x >> 8);
592
vertex->z = matWorld->values[2][3] + ((matWorld->values[2][2] * modelVert->z) >> 8)
593
+ ((matWorld->values[2][0] * modelVert->x >> 8) + (matWorld->values[2][1] * modelVert->y >> 8));
594
595
vertex->color = color;
596
}
597
}
598
}
599
break;
600
601
case MODEL_USENORMALS | MODEL_USECOLOURS:
602
if (matNormals) {
603
for (; i < mdl->indexCount;) {
604
faceVertCounts[f++] = mdl->faceVertCount;
605
606
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
607
ModelVertex *modelVert = &mdl->vertices[indices[i]];
608
Color *modelColor = &mdl->colors[indices[i++]];
609
Scene3DVertex *vertex = &scn->vertices[vertID++];
610
611
vertex->x = matWorld->values[0][3] + (matWorld->values[0][2] * modelVert->z >> 8)
612
+ (modelVert->y * matWorld->values[0][1] >> 8) + (matWorld->values[0][0] * modelVert->x >> 8);
613
vertex->y = matWorld->values[1][3] + (matWorld->values[1][2] * modelVert->z >> 8)
614
+ (modelVert->y * matWorld->values[1][1] >> 8) + (matWorld->values[1][0] * modelVert->x >> 8);
615
vertex->z = matWorld->values[2][3] + (modelVert->x * matWorld->values[2][0] >> 8)
616
+ (modelVert->y * matWorld->values[2][1] >> 8) + (matWorld->values[2][2] * modelVert->z >> 8);
617
618
vertex->nx = (matNormals->values[0][0] * modelVert->nx >> 8) + (modelVert->ny * matNormals->values[0][1] >> 8)
619
+ (matNormals->values[0][2] * modelVert->nz >> 8);
620
vertex->ny = (matNormals->values[1][0] * modelVert->nx >> 8) + (modelVert->ny * matNormals->values[1][1] >> 8)
621
+ (matNormals->values[1][2] * modelVert->nz >> 8);
622
vertex->nz =
623
((matNormals->values[2][2] * modelVert->nz) >> 8)
624
+ ((modelVert->ny * matNormals->values[2][1] >> 8) + (matNormals->values[2][0] * modelVert->nx >> 8));
625
626
vertex->color = modelColor->color;
627
}
628
}
629
}
630
else {
631
for (; i < mdl->indexCount;) {
632
faceVertCounts[f++] = mdl->faceVertCount;
633
634
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
635
ModelVertex *modelVert = &mdl->vertices[indices[i]];
636
Color *modelColor = &mdl->colors[indices[i++]];
637
Scene3DVertex *vertex = &scn->vertices[vertID++];
638
639
vertex->x = matWorld->values[0][3] + (matWorld->values[0][0] * modelVert->x >> 8)
640
+ (modelVert->y * matWorld->values[0][1] >> 8) + (modelVert->z * matWorld->values[0][2] >> 8);
641
vertex->y = matWorld->values[1][3] + (modelVert->z * matWorld->values[1][2] >> 8)
642
+ (matWorld->values[1][0] * modelVert->x >> 8) + (modelVert->y * matWorld->values[1][1] >> 8);
643
vertex->z = matWorld->values[2][3] + (matWorld->values[2][2] * modelVert->z >> 8)
644
+ (modelVert->y * matWorld->values[2][1] >> 8) + (modelVert->x * matWorld->values[2][0] >> 8);
645
646
vertex->color = modelColor->color;
647
}
648
}
649
}
650
break;
651
}
652
}
653
}
654
}
655
}
656
void RSDK::AddMeshFrameToScene(uint16 modelFrames, uint16 sceneIndex, Animator *animator, uint8 drawMode, Matrix *matWorld, Matrix *matNormals,
657
color color)
658
{
659
if (modelFrames < MODEL_COUNT && sceneIndex < SCENE3D_COUNT) {
660
if (matWorld && animator) {
661
Model *mdl = &modelList[modelFrames];
662
Scene3D *scn = &scene3DList[sceneIndex];
663
uint16 *indices = mdl->indices;
664
int32 vertID = scn->vertexCount;
665
uint8 *faceVertCounts = &scn->faceVertCounts[scn->faceCount];
666
int32 indCnt = mdl->indexCount;
667
if (scn->vertLimit - vertID >= indCnt) {
668
scn->vertexCount += mdl->indexCount;
669
scn->drawMode = drawMode;
670
scn->faceCount += indCnt / mdl->faceVertCount;
671
672
int32 nextFrame = animator->frameID + 1;
673
if (nextFrame >= animator->frameCount)
674
nextFrame = animator->loopIndex;
675
int32 frameOffset = animator->frameID * mdl->vertCount;
676
int32 nextFrameOffset = nextFrame * mdl->vertCount;
677
678
int32 i = 0;
679
int32 f = 0;
680
int32 interpolate = animator->timer;
681
switch (mdl->flags) {
682
default:
683
case MODEL_NOFLAGS:
684
case MODEL_USECOLOURS:
685
for (; i < mdl->indexCount;) {
686
faceVertCounts[f++] = mdl->faceVertCount;
687
688
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
689
ModelVertex *frameVert = &mdl->vertices[frameOffset + indices[i]];
690
ModelVertex *nextFrameVert = &mdl->vertices[nextFrameOffset + indices[i]];
691
int32 x = frameVert->x + ((interpolate * (nextFrameVert->x - frameVert->x)) >> 8);
692
int32 y = frameVert->y + ((interpolate * (nextFrameVert->y - frameVert->y)) >> 8);
693
int32 z = frameVert->z + ((interpolate * (nextFrameVert->z - frameVert->z)) >> 8);
694
i++;
695
Scene3DVertex *vertex = &scn->vertices[vertID++];
696
vertex->x = matWorld->values[0][3] + (z * matWorld->values[0][2] >> 8) + (matWorld->values[0][0] * x >> 8)
697
+ (matWorld->values[0][1] * y >> 8);
698
vertex->y = matWorld->values[1][3] + (y * matWorld->values[1][1] >> 8) + (z * matWorld->values[1][2] >> 8)
699
+ (matWorld->values[1][0] * x >> 8);
700
vertex->z = matWorld->values[2][3] + ((x * matWorld->values[2][0]) >> 8)
701
+ ((matWorld->values[2][2] * z >> 8) + (matWorld->values[2][1] * y >> 8));
702
vertex->color = color;
703
}
704
}
705
break;
706
707
case MODEL_USENORMALS:
708
if (matNormals) {
709
for (; i < mdl->indexCount;) {
710
faceVertCounts[f++] = mdl->faceVertCount;
711
712
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
713
ModelVertex *frameVert = &mdl->vertices[frameOffset + indices[i]];
714
ModelVertex *nextFrameVert = &mdl->vertices[nextFrameOffset + indices[i]];
715
int32 x = frameVert->x + ((interpolate * (nextFrameVert->x - frameVert->x)) >> 8);
716
int32 y = frameVert->y + ((interpolate * (nextFrameVert->y - frameVert->y)) >> 8);
717
int32 z = frameVert->z + ((interpolate * (nextFrameVert->z - frameVert->z)) >> 8);
718
int32 nx = frameVert->nx + ((interpolate * (nextFrameVert->nx - frameVert->nx)) >> 8);
719
int32 ny = frameVert->ny + ((interpolate * (nextFrameVert->ny - frameVert->ny)) >> 8);
720
int32 nz = frameVert->nz + ((interpolate * (nextFrameVert->nz - frameVert->nz)) >> 8);
721
i++;
722
723
Scene3DVertex *vertex = &scn->vertices[vertID++];
724
vertex->x = matWorld->values[0][3] + (z * matWorld->values[0][2] >> 8) + (x * matWorld->values[0][0] >> 8)
725
+ (y * matWorld->values[0][1] >> 8);
726
vertex->y = matWorld->values[1][3] + (y * matWorld->values[1][1] >> 8) + (matWorld->values[1][0] * x >> 8)
727
+ (z * matWorld->values[1][2] >> 8);
728
vertex->z = matWorld->values[2][3] + (x * matWorld->values[2][0] >> 8) + (matWorld->values[2][2] * z >> 8)
729
+ (matWorld->values[2][1] * y >> 8);
730
vertex->nx = (nz * matNormals->values[0][2] >> 8) + (nx * matNormals->values[0][0] >> 8)
731
+ (matNormals->values[0][1] * ny >> 8);
732
vertex->ny = (ny * matNormals->values[1][1] >> 8) + (nz * matNormals->values[1][2] >> 8)
733
+ (nx * matNormals->values[1][0] >> 8);
734
vertex->nz = ((ny * matNormals->values[2][1]) >> 8)
735
+ ((matNormals->values[2][0] * nx >> 8) + (nz * matNormals->values[2][2] >> 8));
736
vertex->color = color;
737
}
738
}
739
}
740
else {
741
for (; i < mdl->indexCount;) {
742
faceVertCounts[f++] = mdl->faceVertCount;
743
744
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
745
ModelVertex *frameVert = &mdl->vertices[frameOffset + indices[i]];
746
ModelVertex *nextFrameVert = &mdl->vertices[nextFrameOffset + indices[i]];
747
int32 x = frameVert->x + ((interpolate * (nextFrameVert->x - frameVert->x)) >> 8);
748
int32 y = frameVert->y + ((interpolate * (nextFrameVert->y - frameVert->y)) >> 8);
749
int32 z = frameVert->z + ((interpolate * (nextFrameVert->z - frameVert->z)) >> 8);
750
i++;
751
Scene3DVertex *vertex = &scn->vertices[vertID++];
752
vertex->x = matWorld->values[0][3] + (z * matWorld->values[0][2] >> 8) + (matWorld->values[0][0] * x >> 8)
753
+ (matWorld->values[0][1] * y >> 8);
754
vertex->y = matWorld->values[1][3] + (y * matWorld->values[1][1] >> 8) + (z * matWorld->values[1][2] >> 8)
755
+ (matWorld->values[1][0] * x >> 8);
756
vertex->z = matWorld->values[2][3] + ((matWorld->values[2][2] * z) >> 8)
757
+ ((matWorld->values[2][0] * x >> 8) + (matWorld->values[2][1] * y >> 8));
758
vertex->color = color;
759
}
760
}
761
}
762
break;
763
764
case MODEL_USENORMALS | MODEL_USECOLOURS:
765
if (matNormals) {
766
for (; i < mdl->indexCount;) {
767
faceVertCounts[f++] = mdl->faceVertCount;
768
769
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
770
ModelVertex *frameVert = &mdl->vertices[frameOffset + indices[i]];
771
ModelVertex *nextFrameVert = &mdl->vertices[nextFrameOffset + indices[i]];
772
int32 x = frameVert->x + ((interpolate * (nextFrameVert->x - frameVert->x)) >> 8);
773
int32 y = frameVert->y + ((interpolate * (nextFrameVert->y - frameVert->y)) >> 8);
774
int32 z = frameVert->z + ((interpolate * (nextFrameVert->z - frameVert->z)) >> 8);
775
int32 nx = frameVert->nx + ((interpolate * (nextFrameVert->nx - frameVert->nx)) >> 8);
776
int32 ny = frameVert->ny + ((interpolate * (nextFrameVert->ny - frameVert->ny)) >> 8);
777
int32 nz = frameVert->nz + ((interpolate * (nextFrameVert->nz - frameVert->nz)) >> 8);
778
779
Color *modelColor = &mdl->colors[indices[i++]];
780
Scene3DVertex *vertex = &scn->vertices[vertID++];
781
vertex->x = matWorld->values[0][3] + (matWorld->values[0][2] * z >> 8) + (y * matWorld->values[0][1] >> 8)
782
+ (matWorld->values[0][0] * x >> 8);
783
vertex->y = matWorld->values[1][3] + (matWorld->values[1][2] * z >> 8) + (y * matWorld->values[1][1] >> 8)
784
+ (matWorld->values[1][0] * x >> 8);
785
vertex->z = matWorld->values[2][3] + (x * matWorld->values[2][0] >> 8) + (y * matWorld->values[2][1] >> 8)
786
+ (matWorld->values[2][2] * z >> 8);
787
vertex->nx = (matNormals->values[0][0] * nx >> 8) + (ny * matNormals->values[0][1] >> 8)
788
+ (matNormals->values[0][2] * nz >> 8);
789
vertex->ny = (matNormals->values[1][0] * nx >> 8) + (ny * matNormals->values[1][1] >> 8)
790
+ (matNormals->values[1][2] * nz >> 8);
791
vertex->nz = ((matNormals->values[2][2] * nz) >> 8)
792
+ ((ny * matNormals->values[2][1] >> 8) + (matNormals->values[2][0] * nx >> 8));
793
vertex->color = modelColor->color;
794
}
795
}
796
}
797
else {
798
for (; i < mdl->indexCount;) {
799
faceVertCounts[f++] = mdl->faceVertCount;
800
801
for (int32 c = 0; c < mdl->faceVertCount; ++c) {
802
ModelVertex *frameVert = &mdl->vertices[frameOffset + indices[i]];
803
ModelVertex *nextFrameVert = &mdl->vertices[nextFrameOffset + indices[i]];
804
int32 x = frameVert->x + ((interpolate * (nextFrameVert->x - frameVert->x)) >> 8);
805
int32 y = frameVert->y + ((interpolate * (nextFrameVert->y - frameVert->y)) >> 8);
806
int32 z = frameVert->z + ((interpolate * (nextFrameVert->z - frameVert->z)) >> 8);
807
Color *modelColor = &mdl->colors[indices[i++]];
808
Scene3DVertex *vertex = &scn->vertices[vertID++];
809
vertex->x = matWorld->values[0][3] + (matWorld->values[0][0] * x >> 8) + (y * matWorld->values[0][1] >> 8)
810
+ (z * matWorld->values[0][2] >> 8);
811
vertex->y = matWorld->values[1][3] + (z * matWorld->values[1][2] >> 8) + (matWorld->values[1][0] * x >> 8)
812
+ (y * matWorld->values[1][1] >> 8);
813
vertex->z = matWorld->values[2][3] + (matWorld->values[2][2] * z >> 8) + (y * matWorld->values[2][1] >> 8)
814
+ (x * matWorld->values[2][0] >> 8);
815
vertex->color = modelColor->color;
816
}
817
}
818
}
819
break;
820
}
821
}
822
}
823
}
824
}
825
826
void RSDK::Draw3DScene(uint16 sceneID)
827
{
828
if (sceneID < SCENE3D_COUNT) {
829
Entity *entity = sceneInfo.entity;
830
Scene3D *scn = &scene3DList[sceneID];
831
832
// Setup face buffer.
833
// Each face's depth is an average of the depth of its vertices.
834
Scene3DVertex *vertices = scn->vertices;
835
Scene3DFace *faceBuffer = scn->faceBuffer;
836
uint8 *faceVertCounts = scn->faceVertCounts;
837
838
int32 vertIndex = 0;
839
for (int32 i = 0; i < scn->faceCount; ++i) {
840
switch (*faceVertCounts) {
841
default:
842
case 1:
843
faceBuffer->depth = vertices[0].z;
844
vertices += *faceVertCounts;
845
break;
846
847
case 2:
848
faceBuffer->depth = vertices[0].z >> 1;
849
faceBuffer->depth += vertices[1].z >> 1;
850
vertices += 2;
851
break;
852
853
case 3:
854
faceBuffer->depth = vertices[0].z >> 1;
855
faceBuffer->depth = (faceBuffer->depth + (vertices[1].z >> 1)) >> 1;
856
faceBuffer->depth += vertices[2].z >> 1;
857
vertices += 3;
858
break;
859
860
case 4:
861
faceBuffer->depth = vertices[0].z >> 2;
862
faceBuffer->depth += vertices[1].z >> 2;
863
faceBuffer->depth += vertices[2].z >> 2;
864
faceBuffer->depth += vertices[3].z >> 2;
865
vertices += 4;
866
break;
867
}
868
869
faceBuffer->index = vertIndex;
870
vertIndex += *faceVertCounts;
871
872
++faceBuffer;
873
++faceVertCounts;
874
}
875
876
// Sort the face buffer. This is needed so that the faces don't overlap each other incorrectly when they're rendered.
877
// This is an insertion sort, taken from here:
878
// https://web.archive.org/web/20110108233032/http://rosettacode.org/wiki/Sorting_algorithms/Insertion_sort#C
879
880
Scene3DFace *a = scn->faceBuffer;
881
882
int i, j;
883
Scene3DFace temp;
884
885
for(i=1; i<scn->faceCount; i++)
886
{
887
temp = a[i];
888
j = i-1;
889
while(j>=0 && a[j].depth < temp.depth)
890
{
891
a[j+1] = a[j];
892
j -= 1;
893
}
894
a[j+1] = temp;
895
}
896
897
// Finally, display the faces.
898
899
uint8 *vertCnt = scn->faceVertCounts;
900
Vector2 vertPos[4];
901
uint32 vertClrs[4];
902
903
switch (scn->drawMode) {
904
default: break;
905
906
case S3D_WIREFRAME:
907
for (int32 f = 0; f < scn->faceCount; ++f) {
908
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
909
for (int32 v = 0; v < *vertCnt - 1; ++v) {
910
DrawLine(drawVert[v + 0].x << 8, drawVert[v + 0].y << 8, drawVert[v + 1].x << 8, drawVert[v + 1].y << 8, drawVert[0].color,
911
entity->alpha, entity->inkEffect, false);
912
}
913
DrawLine(drawVert[0].x << 8, drawVert[0].y << 8, drawVert[*vertCnt - 1].x << 8, drawVert[*vertCnt - 1].y << 8, drawVert[0].color,
914
entity->alpha, entity->inkEffect, false);
915
vertCnt++;
916
}
917
break;
918
919
case S3D_SOLIDCOLOR:
920
for (int32 f = 0; f < scn->faceCount; ++f) {
921
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
922
for (int32 v = 0; v < *vertCnt; ++v) {
923
vertPos[v].x = (drawVert[v].x << 8) - (currentScreen->position.x << 16);
924
vertPos[v].y = (drawVert[v].y << 8) - (currentScreen->position.y << 16);
925
}
926
DrawFace(vertPos, *vertCnt, (drawVert->color >> 16) & 0xFF, (drawVert->color >> 8) & 0xFF, (drawVert->color >> 0) & 0xFF,
927
entity->alpha, entity->inkEffect);
928
vertCnt++;
929
}
930
break;
931
932
// Might have been reserved for textures?
933
// not sure about this, just a guess based on tex coords existing in the model format spec
934
case S3D_UNUSED_1: break;
935
case S3D_UNUSED_2: break;
936
937
case S3D_WIREFRAME_SHADED:
938
for (int32 f = 0; f < scn->faceCount; ++f) {
939
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
940
int32 vertCount = *vertCnt;
941
942
int32 ny1 = 0;
943
for (int32 v = 0; v < vertCount; ++v) {
944
ny1 += drawVert[v].ny;
945
}
946
947
int32 normal = ny1 / vertCount;
948
int32 normalVal = (normal >> 2) * (abs(normal) >> 2);
949
950
int32 specular = normalVal >> 6 >> scn->specularIntensityX;
951
specular = CLAMP(specular, 0x00, 0xFF);
952
int32 r = specular + ((int32)((drawVert->color >> 16) & 0xFF) * ((normal >> 10) + scn->diffuseX) >> scn->diffuseIntensityX);
953
954
specular = normalVal >> 6 >> scn->specularIntensityY;
955
specular = CLAMP(specular, 0x00, 0xFF);
956
int32 g = specular + ((int32)((drawVert->color >> 8) & 0xFF) * ((normal >> 10) + scn->diffuseY) >> scn->diffuseIntensityY);
957
958
specular = normalVal >> 6 >> scn->specularIntensityZ;
959
specular = CLAMP(specular, 0x00, 0xFF);
960
int32 b = specular + ((int32)((drawVert->color >> 0) & 0xFF) * ((normal >> 10) + scn->diffuseZ) >> scn->diffuseIntensityZ);
961
962
r = CLAMP(r, 0x00, 0xFF);
963
g = CLAMP(g, 0x00, 0xFF);
964
b = CLAMP(b, 0x00, 0xFF);
965
966
uint32 color = (r << 16) | (g << 8) | (b << 0);
967
968
for (int32 v = 0; v < vertCount - 1; ++v) {
969
DrawLine(drawVert[v + 0].x << 8, drawVert[v + 0].y << 8, drawVert[v + 1].x << 8, drawVert[v + 1].y << 8, color, entity->alpha,
970
entity->inkEffect, false);
971
}
972
DrawLine(drawVert[vertCount - 1].x << 8, drawVert[vertCount - 1].y << 8, drawVert[0].x << 8, drawVert[0].y << 8, color,
973
entity->alpha, entity->inkEffect, false);
974
975
vertCnt++;
976
}
977
break;
978
979
case S3D_SOLIDCOLOR_SHADED:
980
for (int32 f = 0; f < scn->faceCount; ++f) {
981
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
982
int32 vertCount = *vertCnt;
983
984
int32 ny = 0;
985
for (int32 v = 0; v < vertCount; ++v) {
986
ny += drawVert[v].ny;
987
vertPos[v].x = (drawVert[v].x << 8) - (currentScreen->position.x << 16);
988
vertPos[v].y = (drawVert[v].y << 8) - (currentScreen->position.y << 16);
989
}
990
991
int32 normal = ny / vertCount;
992
int32 normalVal = (normal >> 2) * (abs(normal) >> 2);
993
994
int32 specular = normalVal >> 6 >> scn->specularIntensityX;
995
specular = CLAMP(specular, 0x00, 0xFF);
996
int32 r = specular + ((int32)((drawVert->color >> 16) & 0xFF) * ((normal >> 10) + scn->diffuseX) >> scn->diffuseIntensityX);
997
998
specular = normalVal >> 6 >> scn->specularIntensityY;
999
specular = CLAMP(specular, 0x00, 0xFF);
1000
int32 g = specular + ((int32)((drawVert->color >> 8) & 0xFF) * ((normal >> 10) + scn->diffuseY) >> scn->diffuseIntensityY);
1001
1002
specular = normalVal >> 6 >> scn->specularIntensityZ;
1003
specular = CLAMP(specular, 0x00, 0xFF);
1004
int32 b = specular + ((int32)((drawVert->color >> 0) & 0xFF) * ((normal >> 10) + scn->diffuseZ) >> scn->diffuseIntensityZ);
1005
1006
r = CLAMP(r, 0x00, 0xFF);
1007
g = CLAMP(g, 0x00, 0xFF);
1008
b = CLAMP(b, 0x00, 0xFF);
1009
1010
uint32 color = (r << 16) | (g << 8) | (b << 0);
1011
1012
drawVert = &scn->vertices[scn->faceBuffer[f].index];
1013
DrawFace(vertPos, *vertCnt, (color >> 16) & 0xFF, (color >> 8) & 0xFF, (color >> 0) & 0xFF, entity->alpha, entity->inkEffect);
1014
1015
vertCnt++;
1016
}
1017
break;
1018
1019
case S3D_SOLIDCOLOR_SHADED_BLENDED:
1020
for (int32 f = 0; f < scn->faceCount; ++f) {
1021
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
1022
int32 vertCount = *vertCnt;
1023
1024
for (int32 v = 0; v < vertCount; ++v) {
1025
vertPos[v].x = (drawVert[v].x << 8) - (currentScreen->position.x << 16);
1026
vertPos[v].y = (drawVert[v].y << 8) - (currentScreen->position.y << 16);
1027
1028
int32 normal = drawVert[v].ny;
1029
int32 normalVal = (normal >> 2) * (abs(normal) >> 2);
1030
1031
int32 specular = (normalVal >> 6) >> scn->specularIntensityX;
1032
specular = CLAMP(specular, 0x00, 0xFF);
1033
int32 r = specular + ((int32)((drawVert->color >> 16) & 0xFF) * ((normal >> 10) + scn->diffuseX) >> scn->diffuseIntensityX);
1034
1035
specular = (normalVal >> 6) >> scn->specularIntensityY;
1036
specular = CLAMP(specular, 0x00, 0xFF);
1037
int32 g = specular + ((int32)((drawVert->color >> 8) & 0xFF) * ((normal >> 10) + scn->diffuseY) >> scn->diffuseIntensityY);
1038
1039
specular = (normalVal >> 6) >> scn->specularIntensityZ;
1040
specular = CLAMP(specular, 0x00, 0xFF);
1041
int32 b = specular + ((int32)((drawVert->color >> 0) & 0xFF) * ((normal >> 10) + scn->diffuseZ) >> scn->diffuseIntensityZ);
1042
1043
r = CLAMP(r, 0x00, 0xFF);
1044
g = CLAMP(g, 0x00, 0xFF);
1045
b = CLAMP(b, 0x00, 0xFF);
1046
1047
vertClrs[v] = (r << 16) | (g << 8) | (b << 0);
1048
}
1049
1050
DrawBlendedFace(vertPos, vertClrs, *vertCnt, entity->alpha, entity->inkEffect);
1051
1052
vertCnt++;
1053
}
1054
break;
1055
1056
case S3D_WIREFRAME_SCREEN:
1057
for (int32 f = 0; f < scn->faceCount; ++f) {
1058
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
1059
1060
int32 v = 0;
1061
for (; v < *vertCnt && v < 0xFF; ++v) {
1062
int32 vertZ = drawVert[v].z;
1063
if (vertZ < 0x100) {
1064
v = 0xFF;
1065
}
1066
else {
1067
vertPos[v].x = currentScreen->center.x + (drawVert[v].x << scn->projectionX) / vertZ;
1068
vertPos[v].y = currentScreen->center.y - (drawVert[v].y << scn->projectionY) / vertZ;
1069
}
1070
}
1071
1072
if (v < 0xFF) {
1073
for (int32 v = 0; v < *vertCnt - 1; ++v) {
1074
DrawLine(vertPos[v + 0].x, vertPos[v + 0].y, vertPos[v + 1].x, vertPos[v + 1].y, drawVert[0].color, entity->alpha,
1075
entity->inkEffect, true);
1076
}
1077
DrawLine(vertPos[0].x, vertPos[0].y, vertPos[*vertCnt - 1].x, vertPos[*vertCnt - 1].y, drawVert[0].color, entity->alpha,
1078
entity->inkEffect, true);
1079
}
1080
1081
vertCnt++;
1082
}
1083
break;
1084
1085
case S3D_SOLIDCOLOR_SCREEN:
1086
for (int32 f = 0; f < scn->faceCount; ++f) {
1087
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
1088
int32 vertCount = *vertCnt;
1089
1090
int32 v = 0;
1091
for (; v < vertCount && v < 0xFF; ++v) {
1092
int32 vertZ = drawVert[v].z;
1093
if (vertZ < 0x100) {
1094
v = 0xFF;
1095
}
1096
else {
1097
vertPos[v].x = (currentScreen->center.x << 16) + ((drawVert[v].x << scn->projectionX) / vertZ << 16);
1098
vertPos[v].y = (currentScreen->center.y << 16) - ((drawVert[v].y << scn->projectionY) / vertZ << 16);
1099
}
1100
}
1101
1102
if (v < 0xFF) {
1103
DrawFace(vertPos, *vertCnt, (drawVert[0].color >> 16) & 0xFF, (drawVert[0].color >> 8) & 0xFF,
1104
(drawVert[0].color >> 0) & 0xFF, entity->alpha, entity->inkEffect);
1105
}
1106
vertCnt++;
1107
}
1108
break;
1109
1110
case S3D_WIREFRAME_SHADED_SCREEN:
1111
for (int32 f = 0; f < scn->faceCount; ++f) {
1112
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
1113
int32 vertCount = *vertCnt;
1114
1115
int32 v = 0;
1116
int32 ny1 = 0;
1117
for (; v < *vertCnt && v < 0xFF; ++v) {
1118
int32 vertZ = drawVert[v].z;
1119
if (vertZ < 0x100) {
1120
v = 0xFF;
1121
}
1122
else {
1123
vertPos[v].x = currentScreen->center.x + (drawVert[v].x << scn->projectionX) / vertZ;
1124
vertPos[v].y = currentScreen->center.y - (drawVert[v].y << scn->projectionY) / vertZ;
1125
ny1 += drawVert[v].ny;
1126
}
1127
}
1128
1129
if (v < 0xFF) {
1130
int32 normal = ny1 / vertCount;
1131
int32 normalVal = (normal >> 2) * (abs(normal) >> 2);
1132
1133
int32 specular = normalVal >> 6 >> scn->specularIntensityX;
1134
specular = CLAMP(specular, 0x00, 0xFF);
1135
int32 r = specular + ((int32)((drawVert[0].color >> 16) & 0xFF) * ((normal >> 10) + scn->diffuseX) >> scn->diffuseIntensityX);
1136
1137
specular = normalVal >> 6 >> scn->specularIntensityY;
1138
specular = CLAMP(specular, 0x00, 0xFF);
1139
int32 g = specular + ((int32)((drawVert[0].color >> 8) & 0xFF) * ((normal >> 10) + scn->diffuseY) >> scn->diffuseIntensityY);
1140
1141
specular = normalVal >> 6 >> scn->specularIntensityZ;
1142
specular = CLAMP(specular, 0x00, 0xFF);
1143
int32 b = specular + ((int32)((drawVert[0].color >> 0) & 0xFF) * ((normal >> 10) + scn->diffuseZ) >> scn->diffuseIntensityZ);
1144
1145
r = CLAMP(r, 0x00, 0xFF);
1146
g = CLAMP(g, 0x00, 0xFF);
1147
b = CLAMP(b, 0x00, 0xFF);
1148
1149
uint32 color = (r << 16) | (g << 8) | (b << 0);
1150
1151
for (int32 v = 0; v < *vertCnt - 1; ++v) {
1152
DrawLine(vertPos[v + 0].x, vertPos[v + 0].y, vertPos[v + 1].x, vertPos[v + 1].y, color, entity->alpha, entity->inkEffect,
1153
true);
1154
}
1155
DrawLine(vertPos[*vertCnt - 1].x, vertPos[*vertCnt - 1].y, vertPos[0].x, vertPos[0].y, color, entity->alpha,
1156
entity->inkEffect, true);
1157
}
1158
1159
vertCnt++;
1160
}
1161
break;
1162
1163
case S3D_SOLIDCOLOR_SHADED_SCREEN:
1164
for (int32 f = 0; f < scn->faceCount; ++f) {
1165
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
1166
int32 vertCount = *vertCnt;
1167
1168
int32 v = 0;
1169
int32 ny = 0;
1170
for (; v < vertCount && v < 0xFF; ++v) {
1171
int32 vertZ = drawVert[v].z;
1172
if (vertZ < 0x100) {
1173
v = 0xFF;
1174
}
1175
else {
1176
vertPos[v].x = (currentScreen->center.x << 16) + ((drawVert[v].x << scn->projectionX) / vertZ << 16);
1177
vertPos[v].y = (currentScreen->center.y << 16) - ((drawVert[v].y << scn->projectionY) / vertZ << 16);
1178
ny += drawVert[v].ny;
1179
}
1180
}
1181
1182
if (v < 0xFF) {
1183
int32 normal = ny / vertCount;
1184
int32 normalVal = (normal >> 2) * (abs(normal) >> 2);
1185
1186
int32 specular = normalVal >> 6 >> scn->specularIntensityX;
1187
specular = CLAMP(specular, 0x00, 0xFF);
1188
int32 r = specular + ((int32)((drawVert[0].color >> 16) & 0xFF) * ((normal >> 10) + scn->diffuseX) >> scn->diffuseIntensityX);
1189
1190
specular = normalVal >> 6 >> scn->specularIntensityY;
1191
specular = CLAMP(specular, 0x00, 0xFF);
1192
int32 g = specular + ((int32)((drawVert[0].color >> 8) & 0xFF) * ((normal >> 10) + scn->diffuseY) >> scn->diffuseIntensityY);
1193
1194
specular = normalVal >> 6 >> scn->specularIntensityZ;
1195
specular = CLAMP(specular, 0x00, 0xFF);
1196
int32 b = specular + ((int32)((drawVert[0].color >> 0) & 0xFF) * ((normal >> 10) + scn->diffuseZ) >> scn->diffuseIntensityZ);
1197
1198
r = CLAMP(r, 0x00, 0xFF);
1199
g = CLAMP(g, 0x00, 0xFF);
1200
b = CLAMP(b, 0x00, 0xFF);
1201
1202
uint32 color = (r << 16) | (g << 8) | (b << 0);
1203
1204
drawVert = &scn->vertices[scn->faceBuffer[f].index];
1205
DrawFace(vertPos, *vertCnt, (color >> 16) & 0xFF, (color >> 8) & 0xFF, (color >> 0) & 0xFF, entity->alpha, entity->inkEffect);
1206
}
1207
1208
vertCnt++;
1209
}
1210
break;
1211
1212
case S3D_SOLIDCOLOR_SHADED_BLENDED_SCREEN:
1213
for (int32 f = 0; f < scn->faceCount; ++f) {
1214
Scene3DVertex *drawVert = &scn->vertices[scn->faceBuffer[f].index];
1215
int32 vertCount = *vertCnt;
1216
1217
int32 v = 0;
1218
for (; v < vertCount && v < 0xFF; ++v) {
1219
int32 vertZ = drawVert[v].z;
1220
if (vertZ < 0x100) {
1221
v = 0xFF;
1222
}
1223
else {
1224
vertPos[v].x = (currentScreen->center.x << 16) + ((drawVert[v].x << scn->projectionX) / vertZ << 16);
1225
vertPos[v].y = (currentScreen->center.y << 16) - ((drawVert[v].y << scn->projectionY) / vertZ << 16);
1226
1227
int32 normal = drawVert[v].ny;
1228
int32 normalVal = (normal >> 2) * (abs(normal) >> 2);
1229
1230
int32 specular = normalVal >> 6 >> scn->specularIntensityX;
1231
specular = CLAMP(specular, 0x00, 0xFF);
1232
int32 r =
1233
specular + ((int32)((drawVert[v].color >> 16) & 0xFF) * ((normal >> 10) + scn->diffuseX) >> scn->diffuseIntensityX);
1234
1235
specular = normalVal >> 6 >> scn->specularIntensityY;
1236
specular = CLAMP(specular, 0x00, 0xFF);
1237
int32 g =
1238
specular + ((int32)((drawVert[v].color >> 8) & 0xFF) * ((normal >> 10) + scn->diffuseY) >> scn->diffuseIntensityY);
1239
1240
specular = normalVal >> 6 >> scn->specularIntensityZ;
1241
specular = CLAMP(specular, 0x00, 0xFF);
1242
int32 b =
1243
specular + ((int32)((drawVert[v].color >> 0) & 0xFF) * ((normal >> 10) + scn->diffuseZ) >> scn->diffuseIntensityZ);
1244
1245
r = CLAMP(r, 0x00, 0xFF);
1246
g = CLAMP(g, 0x00, 0xFF);
1247
b = CLAMP(b, 0x00, 0xFF);
1248
1249
vertClrs[v] = (r << 16) | (g << 8) | (b << 0);
1250
}
1251
}
1252
1253
if (v < 0xFF) {
1254
drawVert = &scn->vertices[scn->faceBuffer[f].index];
1255
DrawBlendedFace(vertPos, vertClrs, *vertCnt, entity->alpha, entity->inkEffect);
1256
}
1257
1258
vertCnt++;
1259
}
1260
break;
1261
}
1262
}
1263
}
1264
1265