Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-1-2-2013-Decompilation
Path: blob/main/RSDKv4/Renderer.cpp
817 views
1
#include "RetroEngine.hpp"
2
3
#define STB_IMAGE_IMPLEMENTATION
4
#include "stb_image.h"
5
6
float retroVertexList[40];
7
float screenBufferVertexList[40];
8
9
int vertexListSize = 0;
10
DrawVertex drawVertexList[DRAWVERTEX_COUNT];
11
ushort drawIndexList[DRAWINDEX_COUNT];
12
13
byte vertexR = 0xFF;
14
byte vertexG = 0xFF;
15
byte vertexB = 0xFF;
16
17
TextureInfo textureList[TEXTURE_COUNT];
18
MeshInfo meshList[MESH_COUNT];
19
20
int renderStateCount = 0;
21
RenderState renderStateList[RENDERSTATE_COUNT];
22
RenderState currentRenderState;
23
24
void SetIdentityMatrixF(MatrixF *matrix)
25
{
26
matrix->values[0][0] = 1.0f;
27
matrix->values[0][1] = 0.0f;
28
matrix->values[0][2] = 0.0f;
29
matrix->values[0][3] = 0.0f;
30
matrix->values[1][0] = 0.0f;
31
matrix->values[1][1] = 1.0f;
32
matrix->values[1][2] = 0.0f;
33
matrix->values[1][3] = 0.0f;
34
matrix->values[2][0] = 0.0f;
35
matrix->values[2][1] = 0.0f;
36
matrix->values[2][2] = 1.0f;
37
matrix->values[2][3] = 0.0f;
38
matrix->values[3][0] = 0.0f;
39
matrix->values[3][1] = 0.0f;
40
matrix->values[3][2] = 0.0f;
41
matrix->values[3][3] = 1.0f;
42
}
43
void MatrixMultiplyF(MatrixF *matrixA, MatrixF *matrixB)
44
{
45
float output[16];
46
47
for (int i = 0; i < 0x10; ++i) {
48
uint rowA = i / 4;
49
uint rowB = i % 4;
50
output[i] = (matrixA->values[rowA][3] * matrixB->values[3][rowB]) + (matrixA->values[rowA][2] * matrixB->values[2][rowB])
51
+ (matrixA->values[rowA][1] * matrixB->values[1][rowB]) + (matrixA->values[rowA][0] * matrixB->values[0][rowB]);
52
}
53
54
for (int i = 0; i < 0x10; ++i) matrixA->values[i / 4][i % 4] = output[i];
55
}
56
void MatrixTranslateXYZF(MatrixF *matrix, float x, float y, float z)
57
{
58
matrix->values[0][0] = 1.0f;
59
matrix->values[0][1] = 0.0f;
60
matrix->values[0][2] = 0.0f;
61
matrix->values[0][3] = 0.0f;
62
matrix->values[1][0] = 0.0f;
63
matrix->values[1][1] = 1.0f;
64
matrix->values[1][2] = 0.0f;
65
matrix->values[1][3] = 0.0f;
66
matrix->values[2][0] = 0.0f;
67
matrix->values[2][1] = 0.0f;
68
matrix->values[2][2] = 1.0f;
69
matrix->values[2][3] = 0.0f;
70
matrix->values[3][0] = x;
71
matrix->values[3][1] = y;
72
matrix->values[3][2] = z;
73
matrix->values[3][3] = 1.0f;
74
}
75
void MatrixScaleXYZF(MatrixF *matrix, float scaleX, float scaleY, float scaleZ)
76
{
77
matrix->values[0][0] = scaleX;
78
matrix->values[0][1] = 0.0f;
79
matrix->values[0][2] = 0.0f;
80
matrix->values[0][3] = 0.0f;
81
matrix->values[1][0] = 0.0f;
82
matrix->values[1][1] = scaleY;
83
matrix->values[1][2] = 0.0f;
84
matrix->values[1][3] = 0.0f;
85
matrix->values[2][0] = 0.0f;
86
matrix->values[2][1] = 0.0f;
87
matrix->values[2][2] = scaleZ;
88
matrix->values[2][3] = 0.0f;
89
matrix->values[3][0] = 0.0f;
90
matrix->values[3][1] = 0.0f;
91
matrix->values[3][2] = 0.0f;
92
matrix->values[3][3] = 1.0f;
93
}
94
void MatrixRotateXF(MatrixF *matrix, float angle)
95
{
96
float sine = sinf(angle);
97
float cosine = cosf(angle);
98
matrix->values[0][0] = 1.0f;
99
matrix->values[0][1] = 0.0f;
100
matrix->values[0][2] = 0.0f;
101
matrix->values[0][3] = 0.0f;
102
matrix->values[1][0] = 0.0f;
103
matrix->values[1][1] = cosine;
104
matrix->values[1][2] = sine;
105
matrix->values[1][3] = 0.0f;
106
matrix->values[2][0] = 0.0f;
107
matrix->values[2][1] = -sine;
108
matrix->values[2][2] = cosine;
109
matrix->values[2][3] = 0.0f;
110
matrix->values[3][0] = 0.0f;
111
matrix->values[3][1] = 0.0f;
112
matrix->values[3][2] = 0.0f;
113
matrix->values[3][3] = 1.0f;
114
}
115
void MatrixRotateYF(MatrixF *matrix, float angle)
116
{
117
float sine = sinf(angle);
118
float cosine = cosf(angle);
119
matrix->values[0][0] = cosine;
120
matrix->values[0][1] = 0.0f;
121
matrix->values[0][2] = sine;
122
matrix->values[0][3] = 0.0f;
123
matrix->values[1][0] = 0.0f;
124
matrix->values[1][1] = 1.0f;
125
matrix->values[1][2] = 0.0f;
126
matrix->values[1][3] = 0.0f;
127
matrix->values[2][0] = -sine;
128
matrix->values[2][1] = 0.0f;
129
matrix->values[2][2] = cosine;
130
matrix->values[2][3] = 0.0f;
131
matrix->values[3][0] = 0.0f;
132
matrix->values[3][1] = 0.0f;
133
matrix->values[3][2] = 0.0f;
134
matrix->values[3][3] = 1.0f;
135
}
136
void MatrixRotateZF(MatrixF *matrix, float angle)
137
{
138
float sine = sinf(angle);
139
float cosine = cosf(angle);
140
141
matrix->values[0][0] = cosine;
142
matrix->values[0][1] = -sine;
143
matrix->values[0][2] = 0.0;
144
matrix->values[0][3] = 0.0;
145
matrix->values[1][0] = sine;
146
matrix->values[1][1] = cosine;
147
matrix->values[1][2] = 0;
148
matrix->values[1][3] = 0;
149
matrix->values[2][0] = 0.0;
150
matrix->values[2][1] = 0.0;
151
matrix->values[2][2] = 1.0;
152
matrix->values[2][3] = 0.0;
153
matrix->values[3][0] = 0.0;
154
matrix->values[3][1] = 0.0;
155
matrix->values[3][3] = 1.0;
156
matrix->values[3][2] = 0.0;
157
}
158
void MatrixRotateXYZF(MatrixF *matrix, float angleX, float angleY, float angleZ)
159
{
160
float sinX = sinf(angleX);
161
float cosX = cosf(angleX);
162
float sinY = sinf(angleY);
163
float cosY = cosf(angleY);
164
float sinZ = sinf(angleZ);
165
float cosZ = cosf(angleZ);
166
167
matrix->values[0][0] = (cosZ * cosY) + (sinZ * (sinY * sinX));
168
matrix->values[0][1] = (sinZ * cosY) - (cosZ * (sinY * sinX));
169
matrix->values[0][2] = sinY * cosX;
170
matrix->values[0][3] = 0.0f;
171
matrix->values[1][0] = sinZ * -cosX;
172
matrix->values[1][1] = cosZ * cosX;
173
matrix->values[1][2] = sinX;
174
matrix->values[1][3] = 0.0f;
175
matrix->values[2][0] = (sinZ * (cosY * sinX)) - (cosZ * sinY);
176
matrix->values[2][1] = (sinZ * -sinY) - (cosZ * (cosY * sinX));
177
matrix->values[2][2] = cosY * cosX;
178
matrix->values[2][3] = 0.0f;
179
matrix->values[3][0] = 0.0f;
180
matrix->values[3][1] = 0.0f;
181
matrix->values[3][2] = 0.0f;
182
matrix->values[3][3] = 1.0f;
183
}
184
185
void MatrixInvertF(MatrixF *dstMatrix, MatrixF *matrix)
186
{
187
double inv[16], det;
188
double m[16];
189
for (int y = 0; y < 4; ++y) {
190
for (int x = 0; x < 4; ++x) {
191
m[(y << 2) + x] = matrix->values[y][x];
192
}
193
}
194
195
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];
196
197
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];
198
199
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];
200
201
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];
202
203
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];
204
205
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];
206
207
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];
208
209
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];
210
211
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];
212
213
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];
214
215
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];
216
217
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];
218
219
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];
220
221
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];
222
223
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];
224
225
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];
226
227
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
228
229
if (det == 0)
230
return;
231
232
det = 1.0 / det;
233
234
for (int i = 0; i < 0x10; ++i) dstMatrix->values[i / 4][i % 4] = inv[i] * det;
235
}
236
237
// Render States
238
void ResetRenderStates()
239
{
240
currentRenderState.renderMatrix = NULL;
241
currentRenderState.vertPtr = drawVertexList;
242
currentRenderState.indexCount = 0;
243
currentRenderState.id = 0;
244
currentRenderState.blendMode = 0;
245
currentRenderState.useColors = false;
246
currentRenderState.useTexture = false;
247
currentRenderState.depthTest = false;
248
currentRenderState.useNormals = false;
249
currentRenderState.useFilter = false;
250
currentRenderState.indexPtr = drawIndexList;
251
renderStateCount = -1;
252
vertexListSize = 0;
253
vertexR = 0xFF;
254
vertexG = 0xFF;
255
vertexB = 0xFF;
256
}
257
void SetRenderBlendMode(byte mode)
258
{
259
if (currentRenderState.blendMode != mode && currentRenderState.indexCount) {
260
RenderState *state = &renderStateList[renderStateCount++];
261
memcpy(state, &currentRenderState, sizeof(RenderState));
262
263
currentRenderState.indexCount = 0;
264
currentRenderState.id = 0;
265
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
266
}
267
currentRenderState.blendMode = mode;
268
}
269
void SetRenderVertexColor(byte r, byte g, byte b)
270
{
271
vertexR = r;
272
vertexG = g;
273
vertexB = b;
274
}
275
276
#undef near
277
#undef far
278
void SetPerspectiveMatrix(float w, float h, float near, float far)
279
{
280
float m[19];
281
282
float val = tanf((float)(0.017453292f * w) * 0.5f);
283
m[11] = 1.0;
284
m[0] = 1.0 / val;
285
m[1] = 0.0;
286
m[2] = 0.0;
287
m[3] = 0.0;
288
m[4] = 0.0;
289
m[6] = 0.0;
290
m[7] = 0.0;
291
m[8] = 0.0;
292
m[9] = 0.0;
293
m[12] = 0.0;
294
m[13] = 0.0;
295
m[15] = 0.0;
296
m[5] = 1.0 / (val * h);
297
m[10] = (far + near) / (far - near);
298
m[14] = -((far + far) * near) / (far - near);
299
#if RETRO_USING_OPENGL
300
glMultMatrixf(m);
301
#endif
302
}
303
void SetupDrawIndexList()
304
{
305
int index = 0;
306
for (int i = 0; i < DRAWINDEX_COUNT;) {
307
drawIndexList[i + 2] = index + 0;
308
drawIndexList[i + 1] = index + 1;
309
drawIndexList[i + 0] = index + 2;
310
drawIndexList[i + 5] = index + 1;
311
drawIndexList[i + 4] = index + 3;
312
drawIndexList[i + 3] = index + 2;
313
index += 4;
314
i += 6;
315
}
316
}
317
void SetRenderMatrix(MatrixF *matrix) { currentRenderState.renderMatrix = matrix; }
318
void NewRenderState()
319
{
320
if (renderStateCount < RENDERSTATE_COUNT) {
321
if (currentRenderState.indexCount) {
322
RenderState *state = &renderStateList[renderStateCount];
323
memcpy(state, &currentRenderState, sizeof(RenderState));
324
325
currentRenderState.id = 0;
326
currentRenderState.indexCount = 0;
327
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
328
currentRenderState.indexPtr = drawIndexList;
329
renderStateCount++;
330
}
331
}
332
}
333
void RenderScene()
334
{
335
#if RETRO_USING_OPENGL
336
glDisable(GL_TEXTURE_2D);
337
glDisable(GL_DEPTH_TEST);
338
glDisable(GL_LIGHTING);
339
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
340
glDisable(GL_BLEND);
341
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
342
#endif
343
if (renderStateCount == -1)
344
return;
345
346
#if !RETRO_USE_ORIGINAL_CODE
347
float dimAmount = 1.0;
348
if ((!Engine.masterPaused || Engine.frameStep) && !drawStageGFXHQ) {
349
if (Engine.dimTimer < Engine.dimLimit) {
350
if (Engine.dimPercent < 1.0) {
351
Engine.dimPercent += 0.05;
352
if (Engine.dimPercent > 1.0)
353
Engine.dimPercent = 1.0;
354
}
355
}
356
else if (Engine.dimPercent > 0.25 && Engine.dimLimit >= 0) {
357
Engine.dimPercent *= 0.9;
358
}
359
360
dimAmount = Engine.dimMax * Engine.dimPercent;
361
}
362
363
if (dimAmount < 1.0) {
364
SetRenderBlendMode(RENDER_BLEND_ALPHA);
365
RenderRect(-SCREEN_CENTERX_F, SCREEN_CENTERY_F, 160.0, SCREEN_XSIZE_F, SCREEN_YSIZE_F, 0, 0, 0, 0xFF - (dimAmount * 0xFF));
366
SetRenderBlendMode(RENDER_BLEND_NONE);
367
}
368
#endif
369
370
#if RETRO_USING_OPENGL
371
glEnableClientState(GL_VERTEX_ARRAY);
372
glLoadIdentity();
373
#endif
374
if (currentRenderState.indexCount) {
375
RenderState *state = &renderStateList[renderStateCount];
376
memcpy(state, &currentRenderState, sizeof(RenderState));
377
378
currentRenderState.indexCount = 0;
379
currentRenderState.id = 0;
380
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
381
renderStateCount++;
382
}
383
384
MatrixF *prevMat = NULL;
385
bool prevTextures = false;
386
uint prevTexID = 0;
387
bool prevColors = false;
388
bool prevNormals = false;
389
bool prevDepth = false;
390
byte prevBlendMode = 0;
391
392
for (int i = 0; i < renderStateCount; ++i) {
393
RenderState *state = &renderStateList[i];
394
395
if (state->renderMatrix != prevMat) {
396
if (state->renderMatrix) {
397
#if RETRO_USING_OPENGL
398
glLoadMatrixf((const GLfloat *)state->renderMatrix);
399
#endif
400
prevMat = state->renderMatrix;
401
}
402
else {
403
#if RETRO_USING_OPENGL
404
glLoadIdentity();
405
#endif
406
prevMat = NULL;
407
}
408
}
409
410
#if RETRO_USING_OPENGL
411
glVertexPointer(3, GL_FLOAT, sizeof(DrawVertex), &state->vertPtr->vertX);
412
#endif
413
if (state->useTexture) {
414
if (!prevTextures) {
415
#if RETRO_USING_OPENGL
416
glEnable(GL_TEXTURE_2D);
417
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
418
#endif
419
}
420
#if RETRO_USING_OPENGL
421
glTexCoordPointer(2, GL_FLOAT, sizeof(DrawVertex), &state->vertPtr->texCoordX);
422
#endif
423
prevTextures = true;
424
if (state->id != prevTexID) {
425
#if RETRO_USING_OPENGL
426
glBindTexture(GL_TEXTURE_2D, state->id);
427
#endif
428
prevTexID = state->id;
429
}
430
}
431
else {
432
if (prevTextures) {
433
#if RETRO_USING_OPENGL
434
glDisable(GL_TEXTURE_2D);
435
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
436
#endif
437
}
438
prevTextures = false;
439
}
440
441
if (state->useColors) {
442
#if RETRO_USING_OPENGL
443
if (!prevColors)
444
glEnableClientState(GL_COLOR_ARRAY);
445
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(DrawVertex), &state->vertPtr->r);
446
#endif
447
prevColors = true;
448
}
449
else {
450
#if RETRO_USING_OPENGL
451
if (prevColors)
452
glDisableClientState(GL_COLOR_ARRAY);
453
#endif
454
prevColors = false;
455
}
456
457
if (state->useNormals) {
458
if (!prevNormals) {
459
#if RETRO_USING_OPENGL
460
glEnableClientState(GL_NORMAL_ARRAY);
461
glEnable(GL_LIGHTING);
462
#endif
463
}
464
#if RETRO_USING_OPENGL
465
glNormalPointer(GL_FLOAT, sizeof(DrawVertex), &state->vertPtr->normalX);
466
#endif
467
prevNormals = true;
468
}
469
else {
470
if (prevNormals) {
471
#if RETRO_USING_OPENGL
472
glDisableClientState(GL_NORMAL_ARRAY);
473
glDisable(GL_LIGHTING);
474
#endif
475
}
476
prevNormals = false;
477
}
478
479
if (state->depthTest) {
480
#if RETRO_USING_OPENGL
481
if (!prevDepth)
482
glEnable(GL_DEPTH_TEST);
483
#endif
484
prevDepth = true;
485
}
486
else {
487
#if RETRO_USING_OPENGL
488
if (prevDepth)
489
glDisable(GL_DEPTH_TEST);
490
#endif
491
prevDepth = false;
492
}
493
494
if (state->blendMode != prevBlendMode) {
495
switch (state->blendMode) {
496
default: prevBlendMode = state->blendMode; break;
497
case 0:
498
#if RETRO_USING_OPENGL
499
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
500
glDisable(GL_BLEND);
501
#endif
502
prevBlendMode = 0;
503
break;
504
case 1:
505
#if RETRO_USING_OPENGL
506
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
507
glEnable(GL_BLEND);
508
#endif
509
prevBlendMode = 1;
510
break;
511
case 2:
512
#if RETRO_USING_OPENGL
513
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
514
glEnable(GL_BLEND);
515
#endif
516
prevBlendMode = 2;
517
break;
518
case 3:
519
#if RETRO_USING_OPENGL
520
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
521
glEnable(GL_BLEND);
522
#endif
523
prevBlendMode = 3;
524
break;
525
}
526
}
527
528
if (state->useFilter && mixFiltersOnJekyll) {
529
#if RETRO_USING_OPENGL
530
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFramebuffer);
531
glBindFramebuffer(GL_FRAMEBUFFER, framebufferHiRes);
532
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Engine.scalingMode ? GL_LINEAR : GL_NEAREST);
533
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Engine.scalingMode ? GL_LINEAR : GL_NEAREST);
534
glVertexPointer(3, GL_FLOAT, sizeof(DrawVertex), screenBufferVertexList);
535
glTexCoordPointer(2, GL_FLOAT, sizeof(DrawVertex), &screenBufferVertexList[6]);
536
glViewport(0, 0, GFX_LINESIZE_DOUBLE, SCREEN_YSIZE * 2);
537
glPushMatrix();
538
glLoadIdentity();
539
glMatrixMode(GL_PROJECTION);
540
glPushMatrix();
541
glLoadIdentity();
542
glDrawElements(GL_TRIANGLES, state->indexCount, GL_UNSIGNED_SHORT, state->indexPtr);
543
544
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
545
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
546
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
547
glBindTexture(GL_TEXTURE_2D, renderbufferHiRes);
548
glVertexPointer(3, GL_FLOAT, sizeof(DrawVertex), state->vertPtr);
549
glTexCoordPointer(2, GL_FLOAT, sizeof(DrawVertex), &state->vertPtr->texCoordX);
550
glViewport(displaySettings.offsetX, 0, displaySettings.width, displaySettings.height);
551
glPopMatrix();
552
glMatrixMode(GL_MODELVIEW);
553
glPopMatrix();
554
#endif
555
}
556
557
#if RETRO_USING_OPENGL
558
glDrawElements(GL_TRIANGLES, state->indexCount, GL_UNSIGNED_SHORT, state->indexPtr);
559
#endif
560
}
561
562
#if RETRO_USING_OPENGL
563
glDisableClientState(GL_VERTEX_ARRAY);
564
if (prevTextures)
565
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
566
if (prevColors)
567
glDisableClientState(GL_COLOR_ARRAY);
568
#endif
569
}
570
571
int stb_read_cb(void *user, char *data, int size)
572
{
573
FileRead(data, size);
574
return size;
575
}
576
void stb_skip_cb(void *user, int n) { FileSkip(n); }
577
int stb_eof_cb(void *user) { return ReachedEndOfFile(); }
578
579
// Textures
580
int LoadTexture(const char *filePath, int format)
581
{
582
int texID = 0;
583
for (int i = 0; i < TEXTURE_COUNT; ++i) {
584
if (StrComp(textureList[texID].fileName, filePath))
585
return texID;
586
if (!StrLength(textureList[texID].fileName))
587
break;
588
texID++;
589
}
590
if (texID == TEXTURE_COUNT)
591
return 0;
592
593
FileInfo info;
594
if (LoadFile(filePath, &info)) {
595
596
stbi_io_callbacks callbacks;
597
callbacks.read = stb_read_cb;
598
callbacks.skip = stb_skip_cb;
599
callbacks.eof = stb_eof_cb;
600
601
int width = 0;
602
int height = 0;
603
int channels = 0;
604
stbi_uc *data = stbi_load_from_callbacks(&callbacks, NULL, &width, &height, &channels, 4);
605
606
if (width > 0 && height > 0) {
607
TextureInfo *texture = &textureList[texID];
608
texture->width = width;
609
texture->height = height;
610
texture->format = format;
611
StrCopy(texture->fileName, filePath);
612
613
float normalize = 0;
614
if (FindStringToken(fileName, "@2", 1) > 0)
615
normalize = 2.0;
616
else if (FindStringToken(fileName, "@1", 1) > 0)
617
normalize = 0.5;
618
else
619
normalize = 1.0;
620
texture->widthN = normalize / width;
621
texture->heightN = normalize / height;
622
623
#if RETRO_USING_OPENGL
624
glGenTextures(1, &texture->id);
625
glBindTexture(GL_TEXTURE_2D, texture->id);
626
#endif
627
628
int id = 0;
629
switch (format) {
630
default: break;
631
case TEXFMT_RGBA4444: {
632
ushort *pixels = (ushort *)malloc(width * height * sizeof(ushort));
633
634
for (int y = 0; y < height; ++y) {
635
for (int x = 0; x < width; ++x) {
636
int r = (data[id++] >> 4) << 12;
637
int g = (data[id++] >> 4) << 8;
638
int b = (data[id++]) & 0xF0;
639
int a = (data[id++] >> 4);
640
pixels[x + (y * width)] = a | r | g | b;
641
}
642
}
643
644
#if RETRO_USING_OPENGL
645
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels);
646
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
647
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
648
glBindTexture(GL_TEXTURE_2D, 0);
649
#endif
650
651
free(pixels);
652
break;
653
}
654
case TEXFMT_RGBA5551: {
655
ushort *pixels = (ushort *)malloc(width * height * sizeof(ushort));
656
657
for (int y = 0; y < height; ++y) {
658
for (int x = 0; x < width; ++x) {
659
int r = data[id++];
660
int g = data[id++];
661
int b = data[id++];
662
int a = data[id++];
663
pixels[x + (y * width)] = RGB888_TO_RGB5551(r, g, b) | (a ? 1 : 0);
664
}
665
}
666
667
#if RETRO_USING_OPENGL
668
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels);
669
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
670
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
671
glBindTexture(GL_TEXTURE_2D, 0);
672
#endif
673
674
free(pixels);
675
break;
676
}
677
case TEXFMT_RGBA8888: {
678
uint *pixels = (uint *)malloc(width * height * sizeof(uint));
679
680
for (int y = 0; y < height; ++y) {
681
for (int x = 0; x < width; ++x) {
682
int r = data[id++];
683
int g = data[id++];
684
int b = data[id++];
685
int a = data[id++];
686
pixels[x + (y * width)] = (a << 24) | (b << 16) | (g << 8) | (r << 0);
687
}
688
}
689
690
#if RETRO_USING_OPENGL
691
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
692
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
693
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
694
glBindTexture(GL_TEXTURE_2D, 0);
695
#endif
696
697
free(pixels);
698
break;
699
}
700
}
701
}
702
703
CloseFile();
704
stbi_image_free(data);
705
706
return texID;
707
}
708
return 0;
709
}
710
void ReplaceTexture(const char *filePath, int texID)
711
{
712
FileInfo info;
713
if (LoadFile(filePath, &info)) {
714
715
stbi_io_callbacks callbacks;
716
callbacks.read = stb_read_cb;
717
callbacks.skip = stb_skip_cb;
718
callbacks.eof = stb_eof_cb;
719
720
int width = 0;
721
int height = 0;
722
int channels = 0;
723
stbi_uc *data = stbi_load_from_callbacks(&callbacks, NULL, &width, &height, &channels, 4);
724
725
if (width > 0 && height > 0) {
726
TextureInfo *texture = &textureList[texID];
727
StrCopy(texture->fileName, filePath);
728
729
float normalize = 0;
730
if (FindStringToken(fileName, "@2", 1) > 0)
731
normalize = 2.0;
732
else if (FindStringToken(fileName, "@1", 1) > 0)
733
normalize = 0.5;
734
else
735
normalize = 1.0;
736
texture->widthN = normalize / width;
737
texture->heightN = normalize / height;
738
739
#if RETRO_USING_OPENGL
740
glBindTexture(GL_TEXTURE_2D, texture->id);
741
#endif
742
743
int id = 0;
744
switch (texture->format) {
745
default: break;
746
case TEXFMT_RGBA4444: {
747
ushort *pixels = (ushort *)malloc(width * height * sizeof(ushort));
748
749
for (int y = 0; y < height; ++y) {
750
for (int x = 0; x < width; ++x) {
751
int r = (data[id++] >> 4) << 12;
752
int g = (data[id++] >> 4) << 8;
753
int b = (data[id++]) & 0xF0;
754
int a = (data[id++] >> 4);
755
pixels[x + (y * width)] = a | r | g | b;
756
}
757
}
758
759
#if RETRO_USING_OPENGL
760
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->width, texture->height, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels);
761
glBindTexture(GL_TEXTURE_2D, 0);
762
#endif
763
764
free(pixels);
765
break;
766
}
767
case TEXFMT_RGBA5551: {
768
ushort *pixels = (ushort *)malloc(width * height * sizeof(ushort));
769
770
for (int y = 0; y < height; ++y) {
771
for (int x = 0; x < width; ++x) {
772
int r = data[id++];
773
int g = data[id++];
774
int b = data[id++];
775
int a = data[id++];
776
pixels[x + (y * width)] = RGB888_TO_RGB5551(r, g, b) | (a ? 1 : 0);
777
}
778
}
779
#if RETRO_USING_OPENGL
780
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->width, texture->height, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels);
781
glBindTexture(GL_TEXTURE_2D, 0);
782
#endif
783
784
free(pixels);
785
break;
786
}
787
case TEXFMT_RGBA8888: {
788
uint *pixels = (uint *)malloc(width * height * sizeof(uint));
789
790
for (int y = 0; y < height; ++y) {
791
for (int x = 0; x < width; ++x) {
792
int r = data[id++];
793
int g = data[id++];
794
int b = data[id++];
795
int a = data[id++];
796
pixels[x + (y * width)] = (a << 24) | (b << 16) | (g << 8) | (r << 0);
797
}
798
}
799
800
#if RETRO_USING_OPENGL
801
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->width, texture->height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
802
glBindTexture(GL_TEXTURE_2D, 0);
803
#endif
804
805
free(pixels);
806
break;
807
}
808
}
809
}
810
811
CloseFile();
812
stbi_image_free(data);
813
}
814
}
815
void ClearTextures(bool keepBuffer)
816
{
817
for (int i = (keepBuffer ? 1 : 0); i < TEXTURE_COUNT; ++i) {
818
#if RETRO_USING_OPENGL
819
glDeleteTextures(1, &textureList[i].id);
820
#endif
821
StrCopy(textureList[i].fileName, "");
822
}
823
}
824
825
// Meshes
826
MeshInfo *LoadMesh(const char *filePath, byte textureID)
827
{
828
int meshID = 0;
829
for (int i = 0; i < MESH_COUNT; ++i) {
830
if (StrComp(meshList[meshID].fileName, filePath) && meshList[meshID].textureID == textureID)
831
return &meshList[meshID];
832
if (!StrLength(meshList[meshID].fileName))
833
break;
834
meshID++;
835
}
836
if (meshID == MESH_COUNT)
837
return 0;
838
839
FileInfo info;
840
if (LoadFile(filePath, &info)) {
841
byte buffer[4];
842
FileRead(buffer, 4 * sizeof(byte));
843
if (buffer[0] == 'R' && buffer[1] == '3' && buffer[2] == 'D' && buffer[3] == '\0') {
844
MeshInfo *mesh = &meshList[meshID];
845
846
StrCopy(mesh->fileName, filePath);
847
mesh->textureID = textureID;
848
849
FileRead(buffer, sizeof(ushort));
850
mesh->vertexCount = buffer[0] + (buffer[1] << 8);
851
mesh->vertices = (DrawVertex *)malloc(sizeof(DrawVertex) * mesh->vertexCount);
852
853
for (int v = 0; v < mesh->vertexCount; ++v) {
854
float buf = 0;
855
FileRead(&buf, sizeof(float));
856
mesh->vertices[v].texCoordX = buf;
857
858
FileRead(&buf, sizeof(float));
859
mesh->vertices[v].texCoordY = buf;
860
861
mesh->vertices[v].r = 0xFF;
862
mesh->vertices[v].g = 0xFF;
863
mesh->vertices[v].b = 0xFF;
864
mesh->vertices[v].a = 0xFF;
865
}
866
867
FileRead(buffer, sizeof(ushort));
868
mesh->indexCount = buffer[0] + (buffer[1] << 8);
869
mesh->indices = (ushort *)malloc(sizeof(ushort) * (3 * mesh->indexCount));
870
871
int id = 0;
872
for (int i = 0; i < mesh->indexCount; ++i) {
873
FileRead(buffer, sizeof(ushort));
874
mesh->indices[id + 2] = buffer[0] + (buffer[1] << 8);
875
876
FileRead(buffer, sizeof(ushort));
877
mesh->indices[id + 1] = buffer[0] + (buffer[1] << 8);
878
879
FileRead(buffer, sizeof(ushort));
880
mesh->indices[id + 0] = buffer[0] + (buffer[1] << 8);
881
882
id += 3;
883
}
884
885
FileRead(buffer, sizeof(ushort));
886
mesh->frameCount = buffer[0] + (buffer[1] << 8);
887
888
if (mesh->frameCount <= 1) {
889
for (int v = 0; v < mesh->vertexCount; ++v) {
890
float buf = 0;
891
FileRead(&buf, sizeof(float));
892
mesh->vertices[v].vertX = buf;
893
894
FileRead(&buf, sizeof(float));
895
mesh->vertices[v].vertY = buf;
896
897
FileRead(&buf, sizeof(float));
898
mesh->vertices[v].vertZ = buf;
899
900
FileRead(&buf, sizeof(float));
901
mesh->vertices[v].normalX = buf;
902
903
FileRead(&buf, sizeof(float));
904
mesh->vertices[v].normalY = buf;
905
906
FileRead(&buf, sizeof(float));
907
mesh->vertices[v].normalZ = buf;
908
}
909
}
910
else {
911
mesh->frames = (MeshVertex *)malloc(mesh->frameCount * mesh->vertexCount * sizeof(MeshVertex));
912
for (int f = 0; f < mesh->frameCount; ++f) {
913
int frameOff = (f * mesh->vertexCount);
914
for (int v = 0; v < mesh->vertexCount; ++v) {
915
float buf = 0;
916
FileRead(&buf, sizeof(float));
917
mesh->frames[frameOff + v].vertX = buf;
918
919
FileRead(&buf, sizeof(float));
920
mesh->frames[frameOff + v].vertY = buf;
921
922
FileRead(&buf, sizeof(float));
923
mesh->frames[frameOff + v].vertZ = buf;
924
925
FileRead(&buf, sizeof(float));
926
mesh->frames[frameOff + v].normalX = buf;
927
928
FileRead(&buf, sizeof(float));
929
mesh->frames[frameOff + v].normalY = buf;
930
931
FileRead(&buf, sizeof(float));
932
mesh->frames[frameOff + v].normalZ = buf;
933
}
934
}
935
}
936
CloseFile();
937
938
return mesh;
939
}
940
else {
941
CloseFile();
942
}
943
}
944
return NULL;
945
}
946
void ClearMeshData()
947
{
948
for (int i = 0; i < MESH_COUNT; ++i) {
949
MeshInfo *mesh = &meshList[i];
950
if (StrLength(mesh->fileName)) {
951
if (mesh->frameCount > 1)
952
free(mesh->frames);
953
if (mesh->indexCount)
954
free(mesh->indices);
955
if (mesh->vertexCount)
956
free(mesh->vertices);
957
958
mesh->frameCount = 0;
959
mesh->indexCount = 0;
960
mesh->vertexCount = 0;
961
962
StrCopy(meshList[i].fileName, "");
963
}
964
}
965
}
966
void SetMeshAnimation(MeshInfo *mesh, MeshAnimator *animator, ushort frameID, ushort frameCount, float speed)
967
{
968
animator->frameCount = frameCount;
969
if (frameCount >= mesh->frameCount)
970
animator->frameCount = mesh->frameCount - 1;
971
if (frameID < mesh->frameCount) {
972
animator->loopIndex = frameID;
973
animator->frameID = frameID;
974
}
975
else {
976
animator->loopIndex = 0;
977
animator->frameID = 0;
978
}
979
animator->animationSpeed = speed;
980
}
981
void AnimateMesh(MeshInfo *mesh, MeshAnimator *animator)
982
{
983
if (mesh->frameCount > 1) {
984
if (!animator->animationFinished) {
985
animator->animationTimer += animator->animationSpeed;
986
987
while (animator->animationTimer > 1.0f) { // new frame (forwards)
988
animator->animationTimer -= 1.0f;
989
animator->frameID++;
990
991
if (animator->loopAnimation) {
992
if (animator->frameID >= animator->frameCount)
993
animator->frameID = animator->loopIndex;
994
}
995
else if (animator->frameID >= animator->frameCount) {
996
animator->frameID = animator->frameCount;
997
animator->animationFinished = true;
998
animator->animationTimer = 0.0f;
999
}
1000
}
1001
while (animator->animationTimer < 0.0f) { // new frame (backwards)
1002
animator->animationTimer += 1.0f;
1003
animator->frameID--;
1004
1005
if (animator->frameID < animator->loopIndex || animator->frameID >= animator->frameCount) {
1006
if (animator->loopAnimation) {
1007
animator->frameID = animator->frameCount;
1008
}
1009
else {
1010
animator->frameID = animator->loopIndex;
1011
animator->animationTimer = 0.0f;
1012
animator->animationFinished = true;
1013
}
1014
}
1015
}
1016
1017
ushort frameID = animator->frameID;
1018
ushort nextFrame = animator->frameID + 1;
1019
if (nextFrame >= animator->frameCount && animator->animationSpeed >= 0)
1020
nextFrame = animator->loopIndex;
1021
if (frameID >= animator->frameCount && animator->animationSpeed < 0)
1022
frameID = animator->loopIndex;
1023
1024
float interp2 = animator->animationTimer;
1025
float interp = 1.0 - animator->animationTimer;
1026
1027
MeshVertex *vert = &mesh->frames[frameID * mesh->vertexCount];
1028
MeshVertex *nextVert = &mesh->frames[nextFrame * mesh->vertexCount];
1029
for (int v = 0; v < mesh->vertexCount; ++v) {
1030
mesh->vertices[v].vertX = (vert->vertX * interp) + (nextVert->vertX * interp2);
1031
mesh->vertices[v].vertY = (vert->vertY * interp) + (nextVert->vertY * interp2);
1032
mesh->vertices[v].vertZ = (vert->vertZ * interp) + (nextVert->vertZ * interp2);
1033
mesh->vertices[v].normalX = (vert->normalX * interp) + (nextVert->normalX * interp2);
1034
mesh->vertices[v].normalY = (vert->normalY * interp) + (nextVert->normalY * interp2);
1035
mesh->vertices[v].normalZ = (vert->normalZ * interp) + (nextVert->normalZ * interp2);
1036
1037
vert++;
1038
nextVert++;
1039
}
1040
}
1041
else if (animator->loopAnimation)
1042
animator->animationFinished = false;
1043
}
1044
}
1045
1046
void SetMeshVertexColors(MeshInfo *mesh, byte r, byte g, byte b, byte a)
1047
{
1048
for (int v = 0; v < mesh->vertexCount; ++v) {
1049
mesh->vertices[v].r = r;
1050
mesh->vertices[v].g = g;
1051
mesh->vertices[v].b = b;
1052
mesh->vertices[v].a = a;
1053
}
1054
}
1055
1056
// Rendering
1057
void TransferRetroBuffer()
1058
{
1059
#if RETRO_USING_OPENGL
1060
glBindTexture(GL_TEXTURE_2D, textureList[0].id);
1061
if (convertTo32Bit) {
1062
ushort *frameBufferPtr = Engine.frameBuffer;
1063
uint *texBufferPtr = Engine.texBuffer;
1064
for (int y = 0; y < SCREEN_YSIZE; ++y) {
1065
for (int x = 0; x < GFX_LINESIZE; ++x) {
1066
texBufferPtr[x] = gfxPalette16to32[frameBufferPtr[x]];
1067
}
1068
texBufferPtr += GFX_LINESIZE;
1069
frameBufferPtr += GFX_LINESIZE;
1070
}
1071
1072
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX_LINESIZE, SCREEN_YSIZE, GL_RGBA, GL_UNSIGNED_BYTE, Engine.texBuffer);
1073
}
1074
else {
1075
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GFX_LINESIZE, SCREEN_YSIZE, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, Engine.frameBuffer);
1076
}
1077
glBindTexture(GL_TEXTURE_2D, 0);
1078
#endif
1079
}
1080
void RenderRetroBuffer(int alpha, float z)
1081
{
1082
if (vertexListSize < DRAWVERTEX_COUNT && textureList[0].format) {
1083
if (renderStateCount < 0 || currentRenderState.id != textureList[0].id) {
1084
if (renderStateCount >= 0) {
1085
RenderState *state = &renderStateList[renderStateCount];
1086
memcpy(state, &currentRenderState, sizeof(RenderState));
1087
}
1088
currentRenderState.indexCount = 0;
1089
currentRenderState.id = textureList[0].id;
1090
currentRenderState.useColors = true;
1091
currentRenderState.useTexture = true;
1092
currentRenderState.useFilter = true;
1093
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1094
currentRenderState.indexPtr = drawIndexList;
1095
renderStateCount++;
1096
}
1097
1098
if (renderStateCount < RENDERSTATE_COUNT) {
1099
int a = 0;
1100
if (alpha >= 0)
1101
a = alpha;
1102
if (a > 0xFF)
1103
a = 0xFF;
1104
1105
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1106
vertex1->vertX = retroVertexList[0];
1107
vertex1->vertY = retroVertexList[1];
1108
vertex1->vertZ = z;
1109
vertex1->texCoordX = retroVertexList[6];
1110
vertex1->texCoordY = retroVertexList[7];
1111
vertex1->r = vertexR;
1112
vertex1->g = vertexG;
1113
vertex1->b = vertexB;
1114
vertex1->a = a;
1115
1116
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1117
vertex2->vertX = retroVertexList[9];
1118
vertex2->vertY = retroVertexList[10];
1119
vertex2->vertZ = z;
1120
vertex2->texCoordX = retroVertexList[15];
1121
vertex2->texCoordY = retroVertexList[16];
1122
vertex2->r = vertexR;
1123
vertex2->g = vertexG;
1124
vertex2->b = vertexB;
1125
vertex2->a = a;
1126
1127
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1128
vertex3->vertX = retroVertexList[18];
1129
vertex3->vertY = retroVertexList[19];
1130
vertex3->vertZ = z;
1131
vertex3->texCoordX = retroVertexList[24];
1132
vertex3->texCoordY = retroVertexList[25];
1133
vertex3->r = vertexR;
1134
vertex3->b = vertexB;
1135
vertex3->g = vertexG;
1136
vertex3->a = a;
1137
1138
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1139
vertex4->vertX = retroVertexList[27];
1140
vertex4->vertY = retroVertexList[28];
1141
vertex4->vertZ = z;
1142
vertex4->texCoordX = retroVertexList[33];
1143
vertex4->texCoordY = retroVertexList[34];
1144
vertex4->r = vertexR;
1145
vertex4->g = vertexG;
1146
vertex4->b = vertexB;
1147
vertex4->a = a;
1148
1149
currentRenderState.indexCount += 6;
1150
vertexListSize += 4;
1151
}
1152
}
1153
}
1154
1155
void RenderImage(float x, float y, float z, float scaleX, float scaleY, float pivotX, float pivotY, float sprW, float sprH, float sprX, float sprY,
1156
int alpha, byte texture)
1157
{
1158
if (vertexListSize < DRAWVERTEX_COUNT && textureList[texture].format) {
1159
if (renderStateCount < 0) {
1160
currentRenderState.indexCount = 0;
1161
currentRenderState.id = textureList[texture].id;
1162
currentRenderState.useColors = true;
1163
currentRenderState.useTexture = true;
1164
currentRenderState.useFilter = false;
1165
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1166
currentRenderState.indexPtr = drawIndexList;
1167
renderStateCount++;
1168
}
1169
else {
1170
bool flag = false;
1171
if (currentRenderState.useTexture)
1172
flag = currentRenderState.id == textureList[texture].id;
1173
1174
if (!flag) {
1175
RenderState *state = &renderStateList[renderStateCount];
1176
memcpy(state, &currentRenderState, sizeof(RenderState));
1177
1178
currentRenderState.indexCount = 0;
1179
currentRenderState.id = textureList[texture].id;
1180
currentRenderState.useColors = true;
1181
currentRenderState.useTexture = true;
1182
currentRenderState.useFilter = false;
1183
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1184
currentRenderState.indexPtr = drawIndexList;
1185
renderStateCount++;
1186
}
1187
}
1188
1189
if (renderStateCount < RENDERSTATE_COUNT) {
1190
int a = 0;
1191
if (alpha >= 0)
1192
a = alpha;
1193
if (a > 0xFF)
1194
a = 0xFF;
1195
1196
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1197
vertex1->vertX = x - (pivotX * scaleX);
1198
vertex1->vertY = (pivotY * scaleY) + y;
1199
vertex1->vertZ = z;
1200
vertex1->texCoordX = sprX * textureList[texture].widthN;
1201
vertex1->texCoordY = sprY * textureList[texture].heightN;
1202
vertex1->r = vertexR;
1203
vertex1->g = vertexG;
1204
vertex1->b = vertexB;
1205
vertex1->a = a;
1206
1207
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1208
vertex2->vertX = ((sprW - pivotX) * scaleX) + x;
1209
vertex2->vertY = vertex1->vertY;
1210
vertex2->vertZ = z;
1211
vertex2->texCoordX = (sprX + sprW) * textureList[texture].widthN;
1212
vertex2->texCoordY = vertex1->texCoordY;
1213
vertex2->r = vertexR;
1214
vertex2->g = vertexG;
1215
vertex2->b = vertexB;
1216
vertex2->a = a;
1217
1218
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1219
vertex3->vertX = vertex1->vertX;
1220
vertex3->vertY = y - ((sprH - pivotY) * scaleY);
1221
vertex3->vertZ = z;
1222
vertex3->texCoordX = vertex1->texCoordX;
1223
vertex3->texCoordY = (sprY + sprH) * textureList[texture].heightN;
1224
vertex3->r = vertexR;
1225
vertex3->g = vertexG;
1226
vertex3->b = vertexB;
1227
vertex3->a = a;
1228
1229
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1230
vertex4->vertX = vertex2->vertX;
1231
vertex4->vertY = vertex3->vertY;
1232
vertex4->vertZ = z;
1233
vertex4->texCoordX = vertex2->texCoordX;
1234
vertex4->texCoordY = vertex3->texCoordY;
1235
vertex4->r = vertexR;
1236
vertex4->g = vertexG;
1237
vertex4->b = vertexB;
1238
vertex4->a = a;
1239
vertexListSize += 4;
1240
currentRenderState.indexCount += 6;
1241
}
1242
}
1243
}
1244
void RenderImageClipped(float x, float y, float z, float scaleX, float scaleY, float pivotX, float pivotY, float sprW, float sprH, float sprX,
1245
float sprY, int alpha, byte texture)
1246
{
1247
if (vertexListSize < DRAWVERTEX_COUNT && textureList[texture].format) {
1248
if (renderStateCount < 0) {
1249
currentRenderState.indexCount = 0;
1250
currentRenderState.id = textureList[texture].id;
1251
currentRenderState.useColors = true;
1252
currentRenderState.useTexture = true;
1253
currentRenderState.useFilter = false;
1254
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1255
currentRenderState.indexPtr = drawIndexList;
1256
renderStateCount++;
1257
}
1258
else {
1259
bool flag = false;
1260
if (currentRenderState.useTexture)
1261
flag = currentRenderState.id == textureList[texture].id;
1262
1263
if (!flag) {
1264
RenderState *state = &renderStateList[renderStateCount];
1265
memcpy(state, &currentRenderState, sizeof(RenderState));
1266
1267
currentRenderState.indexCount = 0;
1268
currentRenderState.id = textureList[texture].id;
1269
currentRenderState.useColors = true;
1270
currentRenderState.useTexture = true;
1271
currentRenderState.useFilter = false;
1272
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1273
currentRenderState.indexPtr = drawIndexList;
1274
renderStateCount++;
1275
}
1276
}
1277
1278
if (renderStateCount < RENDERSTATE_COUNT) {
1279
int a = 0;
1280
if (alpha >= 0)
1281
a = alpha;
1282
if (a > 0xFF)
1283
a = 0xFF;
1284
1285
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1286
vertex1->vertX = x - (pivotX * scaleX);
1287
vertex1->vertY = (pivotY * scaleY) + y;
1288
vertex1->vertZ = z;
1289
vertex1->texCoordX = sprX * textureList[texture].widthN;
1290
vertex1->texCoordY = sprY * textureList[texture].heightN;
1291
vertex1->r = vertexR;
1292
vertex1->g = vertexG;
1293
vertex1->b = vertexB;
1294
vertex1->a = a;
1295
if (vertex1->vertY > 76.0) {
1296
vertex1->texCoordY = (((vertex1->vertY - 76.0) / scaleY) + sprY) * textureList[texture].heightN;
1297
vertex1->vertY = 76.0;
1298
}
1299
1300
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1301
vertex2->vertX = ((sprW - pivotX) * scaleX) + x;
1302
vertex2->vertY = vertex1->vertY;
1303
vertex2->vertZ = z;
1304
vertex2->texCoordX = (sprX + sprW) * textureList[texture].widthN;
1305
vertex2->texCoordY = vertex1->texCoordY;
1306
vertex2->r = vertexR;
1307
vertex2->g = vertexG;
1308
vertex2->b = vertexB;
1309
vertex2->a = a;
1310
1311
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1312
vertex3->vertX = vertex1->vertX;
1313
vertex3->vertY = y - ((sprH - pivotY) * scaleY);
1314
vertex3->vertZ = z;
1315
vertex3->texCoordX = vertex1->texCoordX;
1316
vertex3->texCoordY = (sprY + sprH) * textureList[texture].heightN;
1317
vertex3->r = vertexR;
1318
vertex3->g = vertexG;
1319
vertex3->b = vertexB;
1320
vertex3->a = a;
1321
if (vertex3->vertY < -76.0) {
1322
vertex3->texCoordY = (((vertex3->vertY + 76.0) / scaleY) + (sprY + sprH)) * textureList[texture].heightN;
1323
vertex3->vertY = -76.0;
1324
}
1325
1326
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1327
vertex4->vertX = vertex2->vertX;
1328
vertex4->vertY = vertex3->vertY;
1329
vertex4->vertZ = z;
1330
vertex4->texCoordX = vertex2->texCoordX;
1331
vertex4->texCoordY = vertex3->texCoordY;
1332
vertex4->r = vertexR;
1333
vertex4->g = vertexG;
1334
vertex4->b = vertexB;
1335
vertex4->a = a;
1336
vertexListSize += 4;
1337
currentRenderState.indexCount += 6;
1338
}
1339
}
1340
}
1341
1342
void RenderImageFlipH(float x, float y, float z, float scaleX, float scaleY, float pivotX, float pivotY, float sprW, float sprH, float sprX,
1343
float sprY, int alpha, byte texture)
1344
{
1345
if (vertexListSize < DRAWVERTEX_COUNT && textureList[texture].format) {
1346
if (renderStateCount < 0) {
1347
currentRenderState.indexCount = 0;
1348
currentRenderState.id = textureList[texture].id;
1349
currentRenderState.useColors = true;
1350
currentRenderState.useTexture = true;
1351
currentRenderState.useFilter = false;
1352
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1353
currentRenderState.indexPtr = drawIndexList;
1354
renderStateCount++;
1355
}
1356
else {
1357
bool flag = false;
1358
if (currentRenderState.useTexture)
1359
flag = currentRenderState.id == textureList[texture].id;
1360
1361
if (!flag) {
1362
RenderState *state = &renderStateList[renderStateCount];
1363
memcpy(state, &currentRenderState, sizeof(RenderState));
1364
1365
currentRenderState.indexCount = 0;
1366
currentRenderState.id = textureList[texture].id;
1367
currentRenderState.useColors = true;
1368
currentRenderState.useTexture = true;
1369
currentRenderState.useFilter = false;
1370
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1371
currentRenderState.indexPtr = drawIndexList;
1372
renderStateCount++;
1373
}
1374
}
1375
1376
if (renderStateCount < RENDERSTATE_COUNT) {
1377
int a = 0;
1378
if (alpha >= 0)
1379
a = alpha;
1380
if (a > 0xFF)
1381
a = 0xFF;
1382
1383
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1384
vertex1->vertX = x - (pivotX * scaleX);
1385
vertex1->vertY = (pivotY * scaleY) + y;
1386
vertex1->vertZ = z;
1387
vertex1->texCoordX = (sprX + sprW) * textureList[texture].widthN;
1388
vertex1->texCoordY = sprY * textureList[texture].heightN;
1389
vertex1->r = vertexR;
1390
vertex1->g = vertexG;
1391
vertex1->b = vertexB;
1392
vertex1->a = a;
1393
1394
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1395
vertex2->vertX = ((sprW - pivotX) * scaleX) + x;
1396
vertex2->vertY = vertex1->vertY;
1397
vertex2->vertZ = z;
1398
vertex2->texCoordX = sprX * textureList[texture].widthN;
1399
vertex2->texCoordY = vertex1->texCoordY;
1400
vertex2->r = vertexR;
1401
vertex2->g = vertexG;
1402
vertex2->b = vertexB;
1403
vertex2->a = a;
1404
1405
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1406
vertex3->vertX = vertex1->vertX;
1407
vertex3->vertY = y - ((sprH - pivotY) * scaleY);
1408
vertex3->vertZ = z;
1409
vertex3->texCoordX = vertex1->texCoordX;
1410
vertex3->texCoordY = (sprY + sprH) * textureList[texture].heightN;
1411
vertex3->r = vertexR;
1412
vertex3->g = vertexG;
1413
vertex3->b = vertexB;
1414
vertex3->a = a;
1415
1416
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1417
vertex4->vertX = vertex2->vertX;
1418
vertex4->vertY = vertex3->vertY;
1419
vertex4->vertZ = z;
1420
vertex4->texCoordX = vertex2->texCoordX;
1421
vertex4->texCoordY = vertex3->texCoordY;
1422
vertex4->r = vertexR;
1423
vertex4->g = vertexG;
1424
vertex4->b = vertexB;
1425
vertex4->a = a;
1426
vertexListSize += 4;
1427
currentRenderState.indexCount += 6;
1428
}
1429
}
1430
}
1431
1432
void RenderText(ushort *text, int fontID, float x, float y, int z, float scale, int alpha)
1433
{
1434
BitmapFont *font = &fontList[fontID];
1435
float posX = x;
1436
float posY = (font->base * scale) + y;
1437
1438
if (vertexListSize < DRAWVERTEX_COUNT) {
1439
if (renderStateCount < 0 || (!currentRenderState.useTexture || currentRenderState.useColors)) {
1440
if (renderStateCount >= 0) {
1441
RenderState *state = &renderStateList[renderStateCount];
1442
memcpy(state, &currentRenderState, sizeof(RenderState));
1443
}
1444
currentRenderState.indexCount = 0;
1445
currentRenderState.id = textureList[font->characters[*text].textureID].id;
1446
currentRenderState.useColors = true;
1447
currentRenderState.useTexture = true;
1448
currentRenderState.useFilter = false;
1449
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1450
currentRenderState.indexPtr = drawIndexList;
1451
renderStateCount++;
1452
}
1453
1454
if (renderStateCount < RENDERSTATE_COUNT) {
1455
int a = 0;
1456
if (alpha >= 0)
1457
a = alpha;
1458
if (a > 0xFF)
1459
a = 0xFF;
1460
1461
ushort character = *text++;
1462
while (character && vertexListSize < DRAWVERTEX_COUNT) {
1463
BitmapFontCharacter *fontChar = &font->characters[character];
1464
TextureInfo *texture = &textureList[fontChar->textureID];
1465
1466
if (texture->format) {
1467
if (character == 1) {
1468
posX = x;
1469
posY -= (font->lineHeight * scale);
1470
}
1471
else {
1472
if (currentRenderState.id != texture->id && renderStateCount < RENDERSTATE_COUNT) {
1473
currentRenderState.indexCount = 0;
1474
memcpy(&renderStateList[renderStateCount++], &currentRenderState, sizeof(RenderState));
1475
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1476
currentRenderState.indexPtr = drawIndexList;
1477
currentRenderState.id = texture->id;
1478
}
1479
1480
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1481
vertex1->vertX = posX + (fontChar->xOffset * scale);
1482
vertex1->vertY = posY - (fontChar->yOffset * scale);
1483
vertex1->vertZ = z;
1484
vertex1->texCoordX = fontChar->x * texture->widthN;
1485
vertex1->texCoordY = fontChar->y * texture->heightN;
1486
vertex1->r = vertexR;
1487
vertex1->g = vertexG;
1488
vertex1->b = vertexB;
1489
vertex1->a = a;
1490
1491
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1492
vertex2->vertX = posX + ((fontChar->width + fontChar->xOffset) * scale);
1493
vertex2->vertY = vertex1->vertY;
1494
vertex2->vertZ = z;
1495
vertex2->texCoordX = (fontChar->x + fontChar->width) * texture->widthN;
1496
vertex2->texCoordY = vertex1->texCoordY;
1497
vertex2->r = vertexR;
1498
vertex2->g = vertexG;
1499
vertex2->b = vertexB;
1500
vertex2->a = a;
1501
1502
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1503
vertex3->vertX = vertex1->vertX;
1504
vertex3->vertY = posY - ((fontChar->height + fontChar->yOffset) * scale);
1505
vertex3->vertZ = z;
1506
vertex3->texCoordX = vertex1->texCoordX;
1507
vertex3->texCoordY = (fontChar->y + fontChar->height) * texture->heightN;
1508
vertex3->r = vertexR;
1509
vertex3->g = vertexG;
1510
vertex3->b = vertexB;
1511
vertex3->a = a;
1512
1513
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1514
vertex4->vertX = vertex2->vertX;
1515
vertex4->vertY = vertex3->vertY;
1516
vertex4->vertZ = z;
1517
vertex4->texCoordX = vertex2->texCoordX;
1518
vertex4->texCoordY = vertex3->texCoordY;
1519
vertex4->r = vertexR;
1520
vertex4->g = vertexG;
1521
vertex4->b = vertexB;
1522
vertex4->a = a;
1523
vertexListSize += 4;
1524
currentRenderState.indexCount += 6;
1525
}
1526
}
1527
posX += (fontChar->xAdvance * scale);
1528
character = *text++;
1529
}
1530
}
1531
}
1532
}
1533
void RenderTextClipped(ushort *text, int fontID, float x, float y, int z, float scale, int alpha)
1534
{
1535
BitmapFont *font = &fontList[fontID];
1536
float posX = x;
1537
float posY = (font->base * scale) + y;
1538
1539
if (vertexListSize < DRAWVERTEX_COUNT) {
1540
if (renderStateCount < 0 || (!currentRenderState.useTexture || currentRenderState.useColors)) {
1541
if (renderStateCount >= 0) {
1542
RenderState *state = &renderStateList[renderStateCount];
1543
memcpy(state, &currentRenderState, sizeof(RenderState));
1544
}
1545
currentRenderState.indexCount = 0;
1546
currentRenderState.id = textureList[font->characters[*text].textureID].id;
1547
currentRenderState.useColors = true;
1548
currentRenderState.useTexture = true;
1549
currentRenderState.useFilter = false;
1550
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1551
currentRenderState.indexPtr = drawIndexList;
1552
renderStateCount++;
1553
}
1554
1555
if (renderStateCount < RENDERSTATE_COUNT) {
1556
int a = 0;
1557
if (alpha >= 0)
1558
a = alpha;
1559
if (a > 0xFF)
1560
a = 0xFF;
1561
1562
ushort character = *text++;
1563
while (character && vertexListSize < DRAWVERTEX_COUNT) {
1564
BitmapFontCharacter *fontChar = &font->characters[character];
1565
TextureInfo *texture = &textureList[fontChar->textureID];
1566
1567
if (texture->format) {
1568
if (character == 1) {
1569
posX = x;
1570
posY -= (font->lineHeight * scale);
1571
}
1572
else {
1573
if (currentRenderState.id != texture->id && renderStateCount < RENDERSTATE_COUNT) {
1574
currentRenderState.indexCount = 0;
1575
memcpy(&renderStateList[renderStateCount++], &currentRenderState, sizeof(RenderState));
1576
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1577
currentRenderState.indexPtr = drawIndexList;
1578
currentRenderState.id = texture->id;
1579
}
1580
1581
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1582
vertex1->vertX = posX + (fontChar->xOffset * scale);
1583
vertex1->vertY = posY - (fontChar->yOffset * scale);
1584
vertex1->vertZ = z;
1585
vertex1->texCoordX = fontChar->x * texture->widthN;
1586
vertex1->texCoordY = fontChar->y * texture->heightN;
1587
vertex1->r = vertexR;
1588
vertex1->g = vertexG;
1589
vertex1->b = vertexB;
1590
vertex1->a = a;
1591
if (vertex1->vertY > 76.0) {
1592
vertex1->texCoordY = (((vertex1->vertY - 76.0) / scale) + fontChar->y) * texture->heightN;
1593
vertex1->vertY = 76.0;
1594
}
1595
1596
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1597
vertex2->vertX = posX + ((fontChar->width + fontChar->xOffset) * scale);
1598
vertex2->vertY = vertex1->vertY;
1599
vertex2->vertZ = z;
1600
vertex2->texCoordX = (fontChar->x + fontChar->width) * texture->widthN;
1601
vertex2->texCoordY = vertex1->texCoordY;
1602
vertex2->r = vertexR;
1603
vertex2->g = vertexG;
1604
vertex2->b = vertexB;
1605
vertex2->a = a;
1606
1607
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1608
vertex3->vertX = vertex1->vertX;
1609
vertex3->vertY = posY - ((fontChar->height + fontChar->yOffset) * scale);
1610
vertex3->vertZ = z;
1611
vertex3->texCoordX = vertex1->texCoordX;
1612
vertex3->texCoordY = (fontChar->y + fontChar->height) * texture->heightN;
1613
vertex3->r = vertexR;
1614
vertex3->g = vertexG;
1615
vertex3->b = vertexB;
1616
vertex3->a = a;
1617
if (vertex3->vertY < -76.0) {
1618
vertex3->texCoordY = (((vertex3->vertY + 76.0) / scale) + (fontChar->y + fontChar->height)) * texture->heightN;
1619
vertex3->vertY = -76.0;
1620
}
1621
1622
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1623
vertex4->vertX = vertex2->vertX;
1624
vertex4->vertY = vertex3->vertY;
1625
vertex4->vertZ = z;
1626
vertex4->texCoordX = vertex2->texCoordX;
1627
vertex4->texCoordY = vertex3->texCoordY;
1628
vertex4->r = vertexR;
1629
vertex4->g = vertexG;
1630
vertex4->b = vertexB;
1631
vertex4->a = a;
1632
vertexListSize += 4;
1633
currentRenderState.indexCount += 6;
1634
}
1635
}
1636
posX += (fontChar->xAdvance * scale);
1637
character = *text++;
1638
}
1639
}
1640
}
1641
}
1642
1643
void RenderRect(float x, float y, float z, float w, float h, byte r, byte g, byte b, int alpha)
1644
{
1645
if (vertexListSize < DRAWVERTEX_COUNT) {
1646
if (renderStateCount < 0 || (currentRenderState.useTexture || !currentRenderState.useColors)) {
1647
if (renderStateCount >= 0) {
1648
RenderState *state = &renderStateList[renderStateCount];
1649
memcpy(state, &currentRenderState, sizeof(RenderState));
1650
}
1651
1652
currentRenderState.indexCount = 0;
1653
currentRenderState.id = 0;
1654
currentRenderState.useColors = true;
1655
currentRenderState.useTexture = false;
1656
currentRenderState.useFilter = false;
1657
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1658
currentRenderState.indexPtr = drawIndexList;
1659
renderStateCount++;
1660
}
1661
1662
if (renderStateCount < RENDERSTATE_COUNT) {
1663
int a = 0;
1664
if (alpha >= 0)
1665
a = alpha;
1666
if (a > 0xFF)
1667
a = 0xFF;
1668
1669
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1670
vertex1->vertX = x;
1671
vertex1->vertY = y;
1672
vertex1->vertZ = z;
1673
vertex1->r = r;
1674
vertex1->g = g;
1675
vertex1->b = b;
1676
vertex1->a = a;
1677
1678
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1679
vertex2->vertX = w + x;
1680
vertex2->vertY = y;
1681
vertex2->vertZ = z;
1682
vertex2->r = r;
1683
vertex2->g = g;
1684
vertex2->b = b;
1685
vertex2->a = a;
1686
1687
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1688
vertex3->vertX = x;
1689
vertex3->vertY = y - h;
1690
vertex3->vertZ = z;
1691
vertex3->r = r;
1692
vertex3->g = g;
1693
vertex3->b = b;
1694
vertex3->a = a;
1695
1696
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1697
vertex4->vertX = vertex2->vertX;
1698
vertex4->vertY = y - h;
1699
vertex4->vertZ = z;
1700
vertex4->r = r;
1701
vertex4->g = g;
1702
vertex4->b = b;
1703
vertex4->a = a;
1704
1705
vertexListSize += 4;
1706
currentRenderState.indexCount += 6;
1707
}
1708
}
1709
}
1710
1711
#if !RETRO_USE_ORIGINAL_CODE
1712
void RenderRectClipped(float x, float y, float z, float w, float h, byte r, byte g, byte b, int alpha)
1713
{
1714
if (vertexListSize < DRAWVERTEX_COUNT) {
1715
if (renderStateCount < 0 || (currentRenderState.useTexture || !currentRenderState.useColors)) {
1716
if (renderStateCount >= 0) {
1717
RenderState *state = &renderStateList[renderStateCount];
1718
memcpy(state, &currentRenderState, sizeof(RenderState));
1719
}
1720
1721
currentRenderState.indexCount = 0;
1722
currentRenderState.id = 0;
1723
currentRenderState.useColors = true;
1724
currentRenderState.useTexture = false;
1725
currentRenderState.useFilter = false;
1726
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1727
currentRenderState.indexPtr = drawIndexList;
1728
renderStateCount++;
1729
}
1730
1731
if (renderStateCount < RENDERSTATE_COUNT) {
1732
int a = 0;
1733
if (alpha >= 0)
1734
a = alpha;
1735
if (a > 0xFF)
1736
a = 0xFF;
1737
1738
DrawVertex *vertex1 = &drawVertexList[vertexListSize];
1739
vertex1->vertX = x;
1740
vertex1->vertY = y;
1741
vertex1->vertZ = z;
1742
vertex1->r = r;
1743
vertex1->g = g;
1744
vertex1->b = b;
1745
vertex1->a = a;
1746
if (vertex1->vertY > 76.0)
1747
vertex1->vertY = 76.0;
1748
1749
DrawVertex *vertex2 = &drawVertexList[vertexListSize + 1];
1750
vertex2->vertX = w + x;
1751
vertex2->vertY = y;
1752
vertex2->vertZ = z;
1753
vertex2->r = r;
1754
vertex2->g = g;
1755
vertex2->b = b;
1756
vertex2->a = a;
1757
if (vertex2->vertY > 76.0)
1758
vertex2->vertY = 76.0;
1759
1760
DrawVertex *vertex3 = &drawVertexList[vertexListSize + 2];
1761
vertex3->vertX = x;
1762
vertex3->vertY = y - h;
1763
vertex3->vertZ = z;
1764
vertex3->r = r;
1765
vertex3->g = g;
1766
vertex3->b = b;
1767
vertex3->a = a;
1768
if (vertex3->vertY < -76.0)
1769
vertex3->vertY = -76.0;
1770
1771
DrawVertex *vertex4 = &drawVertexList[vertexListSize + 3];
1772
vertex4->vertX = vertex2->vertX;
1773
vertex4->vertY = y - h;
1774
vertex4->vertZ = z;
1775
vertex4->r = r;
1776
vertex4->g = g;
1777
vertex4->b = b;
1778
vertex4->a = a;
1779
if (vertex4->vertY < -76.0)
1780
vertex4->vertY = -76.0;
1781
1782
vertexListSize += 4;
1783
currentRenderState.indexCount += 6;
1784
}
1785
}
1786
}
1787
#endif
1788
1789
void RenderMesh(MeshInfo *mesh, byte type, byte depthTest)
1790
{
1791
if (!mesh)
1792
return;
1793
1794
if (renderStateCount < RENDERSTATE_COUNT) {
1795
if (currentRenderState.indexCount) {
1796
RenderState *state = &renderStateList[renderStateCount++];
1797
memcpy(state, &currentRenderState, sizeof(RenderState));
1798
}
1799
1800
currentRenderState.vertPtr = mesh->vertices;
1801
currentRenderState.indexPtr = mesh->indices;
1802
currentRenderState.indexCount = mesh->indexCount * 3;
1803
if (mesh->textureID >= TEXTURE_COUNT) {
1804
currentRenderState.useTexture = false;
1805
currentRenderState.id = 0;
1806
}
1807
else {
1808
currentRenderState.useTexture = true;
1809
currentRenderState.id = textureList[mesh->textureID].id;
1810
}
1811
1812
switch (type) {
1813
case MESH_COLORS:
1814
currentRenderState.useColors = true;
1815
currentRenderState.useNormals = false;
1816
break;
1817
case MESH_NORMALS:
1818
currentRenderState.useColors = false;
1819
currentRenderState.useNormals = true;
1820
break;
1821
case MESH_COLORS_NORMALS:
1822
currentRenderState.useColors = true;
1823
currentRenderState.useNormals = true;
1824
break;
1825
}
1826
currentRenderState.depthTest = depthTest;
1827
1828
RenderState *state = &renderStateList[renderStateCount];
1829
memcpy(state, &currentRenderState, sizeof(RenderState));
1830
1831
currentRenderState.indexCount = 0;
1832
currentRenderState.id = 0;
1833
currentRenderState.useColors = true;
1834
currentRenderState.useTexture = false;
1835
currentRenderState.useNormals = false;
1836
currentRenderState.depthTest = false;
1837
currentRenderState.useFilter = false;
1838
currentRenderState.vertPtr = &drawVertexList[vertexListSize];
1839
currentRenderState.indexPtr = drawIndexList;
1840
1841
renderStateCount++;
1842
}
1843
}
1844