Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-glide64mk2/src/Glitch64/glitchmain.cpp
2 views
1
/*
2
* Glide64 - Glide video plugin for Nintendo 64 emulators.
3
* Copyright (c) 2002 Dave2001
4
* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*/
20
21
#define SAVE_CBUFFER
22
23
#ifdef _WIN32
24
#include <windows.h>
25
#include <commctrl.h>
26
#else
27
#include <stdint.h>
28
#include <stdarg.h>
29
#include <string.h>
30
#include <SDL.h>
31
#endif // _WIN32
32
#include <stdlib.h>
33
#include <stdio.h>
34
#include <iostream>
35
#include <fstream>
36
#include <math.h>
37
#include "glide.h"
38
#include "g3ext.h"
39
#include "main.h"
40
#include "m64p.h"
41
42
#ifdef VPDEBUG
43
#include <IL/il.h>
44
#endif
45
46
extern void (*renderCallback)(int);
47
48
wrapper_config config = {0, 0, 0, 0};
49
int screen_width, screen_height;
50
51
static inline void opt_glCopyTexImage2D( GLenum target,
52
GLint level,
53
GLenum internalFormat,
54
GLint x,
55
GLint y,
56
GLsizei width,
57
GLsizei height,
58
GLint border )
59
60
{
61
int w, h, fmt;
62
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
63
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
64
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
65
//printf("copyteximage %dx%d fmt %x oldfmt %x\n", width, height, internalFormat, fmt);
66
if (w == (int) width && h == (int) height && fmt == (int) internalFormat) {
67
if (x+width >= screen_width) {
68
width = screen_width - x;
69
//printf("resizing w --> %d\n", width);
70
}
71
if (y+height >= screen_height+viewport_offset) {
72
height = screen_height+viewport_offset - y;
73
//printf("resizing h --> %d\n", height);
74
}
75
glCopyTexSubImage2D(target, level, 0, 0, x, y, width, height);
76
} else {
77
//printf("copyteximage %dx%d fmt %x old %dx%d oldfmt %x\n", width, height, internalFormat, w, h, fmt);
78
// glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, internalFormat, GL_UNSIGNED_BYTE, 0);
79
// glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
80
// printf("--> %dx%d newfmt %x\n", width, height, fmt);
81
glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
82
}
83
}
84
#define glCopyTexImage2D opt_glCopyTexImage2D
85
86
87
#ifdef _WIN32
88
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
89
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
90
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
91
PFNGLFOGCOORDFPROC glFogCoordfEXT;
92
93
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
94
95
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
96
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
97
PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
98
PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL;
99
PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL;
100
PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL;
101
PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL;
102
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
103
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
104
PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
105
106
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
107
PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
108
PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
109
PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
110
PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
111
PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
112
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
113
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
114
PFNGLUNIFORM1IARBPROC glUniform1iARB;
115
PFNGLUNIFORM4IARBPROC glUniform4iARB;
116
PFNGLUNIFORM4FARBPROC glUniform4fARB;
117
PFNGLUNIFORM1FARBPROC glUniform1fARB;
118
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
119
PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
120
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
121
PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f;
122
123
// FXT1,DXT1,DXT5 support - Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
124
// NOTE: Glide64 + GlideHQ use the following formats
125
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT
126
// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
127
// GL_COMPRESSED_RGB_FXT1_3DFX
128
// GL_COMPRESSED_RGBA_FXT1_3DFX
129
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DARB;
130
#endif // _WIN32
131
132
133
134
typedef struct
135
{
136
unsigned int address;
137
int width;
138
int height;
139
unsigned int fbid;
140
unsigned int zbid;
141
unsigned int texid;
142
int buff_clear;
143
} fb;
144
145
int nbTextureUnits;
146
int nbAuxBuffers, current_buffer;
147
int width, widtho, heighto, height;
148
int saved_width, saved_height;
149
int blend_func_separate_support;
150
int npot_support;
151
int fog_coord_support;
152
int render_to_texture = 0;
153
int texture_unit;
154
int use_fbo;
155
int buffer_cleared;
156
// ZIGGY
157
// to allocate a new static texture name, take the value (free_texture++)
158
int free_texture;
159
int default_texture; // the infamous "32*1024*1024" is now configurable
160
int current_texture;
161
int depth_texture, color_texture;
162
int glsl_support = 1;
163
int viewport_width, viewport_height, viewport_offset = 0, nvidia_viewport_hack = 0;
164
int save_w, save_h;
165
int lfb_color_fmt;
166
float invtex[2];
167
//Gonetz
168
int UMAmode = 0; //support for VSA-100 UMA mode;
169
170
#ifdef _WIN32
171
static HDC hDC = NULL;
172
static HGLRC hGLRC = NULL;
173
static HWND hToolBar = NULL;
174
static HWND hwnd_win = NULL;
175
static unsigned long windowedExStyle, windowedStyle;
176
#endif // _WIN32
177
static unsigned long fullscreen;
178
#ifdef _WIN32
179
static RECT windowedRect;
180
static HMENU windowedMenu;
181
#endif // _WIN32
182
183
static int savedWidtho, savedHeighto;
184
static int savedWidth, savedHeight;
185
unsigned int pBufferAddress;
186
static int pBufferFmt;
187
static int pBufferWidth, pBufferHeight;
188
static fb fbs[100];
189
static int nb_fb = 0;
190
static unsigned int curBufferAddr = 0;
191
192
struct TMU_USAGE { int min, max; } tmu_usage[2] = { {0xfffffff, 0}, {0xfffffff, 0} };
193
194
struct texbuf_t {
195
FxU32 start, end;
196
int fmt;
197
};
198
#define NB_TEXBUFS 128 // MUST be a power of two
199
static texbuf_t texbufs[NB_TEXBUFS];
200
static int texbuf_i;
201
202
unsigned short *frameBuffer = NULL;
203
unsigned short *depthBuffer = NULL;
204
205
//#define VOODOO1
206
207
void display_warning(const char *text, ...)
208
{
209
static int first_message = 100;
210
if (first_message)
211
{
212
char buf[1000];
213
214
va_list ap;
215
216
va_start(ap, text);
217
vsprintf(buf, text, ap);
218
va_end(ap);
219
first_message--;
220
}
221
}
222
223
#ifdef _WIN32
224
void display_error()
225
{
226
LPVOID lpMsgBuf;
227
if (!FormatMessage(
228
FORMAT_MESSAGE_ALLOCATE_BUFFER |
229
FORMAT_MESSAGE_FROM_SYSTEM |
230
FORMAT_MESSAGE_IGNORE_INSERTS,
231
NULL,
232
GetLastError(),
233
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
234
(LPTSTR) &lpMsgBuf,
235
0,
236
NULL ))
237
{
238
// Handle the error.
239
return;
240
}
241
// Process any inserts in lpMsgBuf.
242
// ...
243
// Display the string.
244
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
245
246
// Free the buffer.
247
LocalFree( lpMsgBuf );
248
}
249
#endif // _WIN32
250
251
#ifdef LOGGING
252
char out_buf[256];
253
bool log_open = false;
254
std::ofstream log_file;
255
256
void OPEN_LOG()
257
{
258
if (!log_open)
259
{
260
log_file.open ("wrapper_log.txt", std::ios_base::out|std::ios_base::app);
261
log_open = true;
262
}
263
}
264
265
void CLOSE_LOG()
266
{
267
if (log_open)
268
{
269
log_file.close();
270
log_open = false;
271
}
272
}
273
274
void LOG(const char *text, ...)
275
{
276
#ifdef VPDEBUG
277
if (!dumping) return;
278
#endif
279
if (!log_open)
280
return;
281
va_list ap;
282
va_start(ap, text);
283
vsprintf(out_buf, text, ap);
284
log_file << out_buf;
285
log_file.flush();
286
va_end(ap);
287
}
288
289
class LogManager {
290
public:
291
LogManager() {
292
OPEN_LOG();
293
}
294
~LogManager() {
295
CLOSE_LOG();
296
}
297
};
298
299
LogManager logManager;
300
301
#else // LOGGING
302
#define OPEN_LOG()
303
#define CLOSE_LOG()
304
//#define LOG
305
#endif // LOGGING
306
307
FX_ENTRY void FX_CALL
308
grSstOrigin(GrOriginLocation_t origin)
309
{
310
LOG("grSstOrigin(%d)\r\n", origin);
311
if (origin != GR_ORIGIN_UPPER_LEFT)
312
display_warning("grSstOrigin : %x", origin);
313
}
314
315
FX_ENTRY void FX_CALL
316
grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy )
317
{
318
LOG("grClipWindow(%d,%d,%d,%d)\r\n", minx, miny, maxx, maxy);
319
320
if (use_fbo && render_to_texture) {
321
if (int(minx) < 0) minx = 0;
322
if (int(miny) < 0) miny = 0;
323
if (maxx < minx) maxx = minx;
324
if (maxy < miny) maxy = miny;
325
glScissor(minx, miny, maxx - minx, maxy - miny);
326
glEnable(GL_SCISSOR_TEST);
327
return;
328
}
329
330
if (!use_fbo) {
331
int th = height;
332
if (th > screen_height)
333
th = screen_height;
334
maxy = th - maxy;
335
miny = th - miny;
336
FxU32 tmp = maxy; maxy = miny; miny = tmp;
337
if (maxx > (FxU32) width) maxx = width;
338
if (maxy > (FxU32) height) maxy = height;
339
if (int(minx) < 0) minx = 0;
340
if (int(miny) < 0) miny = 0;
341
if (maxx < minx) maxx = minx;
342
if (maxy < miny) maxy = miny;
343
glScissor(minx, miny+viewport_offset, maxx - minx, maxy - miny);
344
//printf("gl scissor %d %d %d %d\n", minx, miny, maxx, maxy);
345
} else {
346
glScissor(minx, (viewport_offset)+height-maxy, maxx - minx, maxy - miny);
347
}
348
glEnable(GL_SCISSOR_TEST);
349
}
350
351
FX_ENTRY void FX_CALL
352
grColorMask( FxBool rgb, FxBool a )
353
{
354
LOG("grColorMask(%d, %d)\r\n", rgb, a);
355
glColorMask(rgb, rgb, rgb, a);
356
}
357
358
FX_ENTRY void FX_CALL
359
grGlideInit( void )
360
{
361
LOG("grGlideInit()\r\n");
362
}
363
364
FX_ENTRY void FX_CALL
365
grSstSelect( int which_sst )
366
{
367
LOG("grSstSelect(%d)\r\n", which_sst);
368
}
369
370
int isExtensionSupported(const char *extension)
371
{
372
const GLubyte *extensions = NULL;
373
const GLubyte *start;
374
GLubyte *where, *terminator;
375
376
where = (GLubyte *)strchr(extension, ' ');
377
if (where || *extension == '\0')
378
return 0;
379
380
extensions = glGetString(GL_EXTENSIONS);
381
382
start = extensions;
383
for (;;)
384
{
385
where = (GLubyte *) strstr((const char *) start, extension);
386
if (!where)
387
break;
388
389
terminator = where + strlen(extension);
390
if (where == start || *(where - 1) == ' ')
391
if (*terminator == ' ' || *terminator == '\0')
392
return 1;
393
394
start = terminator;
395
}
396
397
return 0;
398
}
399
400
#ifdef _WIN32
401
int isWglExtensionSupported(const char *extension)
402
{
403
const GLubyte *extensions = NULL;
404
const GLubyte *start;
405
GLubyte *where, *terminator;
406
407
where = (GLubyte *)strchr(extension, ' ');
408
if (where || *extension == '\0')
409
return 0;
410
411
extensions = (GLubyte*)wglGetExtensionsStringARB(wglGetCurrentDC());
412
413
start = extensions;
414
for (;;)
415
{
416
where = (GLubyte *) strstr((const char *) start, extension);
417
if (!where)
418
break;
419
420
terminator = where + strlen(extension);
421
if (where == start || *(where - 1) == ' ')
422
if (*terminator == ' ' || *terminator == '\0')
423
return 1;
424
425
start = terminator;
426
}
427
428
return 0;
429
}
430
#endif // _WIN32
431
432
#define GrPixelFormat_t int
433
434
FX_ENTRY GrContext_t FX_CALL
435
grSstWinOpenExt(
436
HWND hWnd,
437
GrScreenResolution_t screen_resolution,
438
GrScreenRefresh_t refresh_rate,
439
GrColorFormat_t color_format,
440
GrOriginLocation_t origin_location,
441
GrPixelFormat_t pixelformat,
442
int nColBuffers,
443
int nAuxBuffers)
444
{
445
LOG("grSstWinOpenExt(%d, %d, %d, %d, %d, %d %d)\r\n", hWnd, screen_resolution, refresh_rate, color_format, origin_location, nColBuffers, nAuxBuffers);
446
return grSstWinOpen(hWnd, screen_resolution, refresh_rate, color_format,
447
origin_location, nColBuffers, nAuxBuffers);
448
}
449
450
#ifdef WIN32
451
# include <fcntl.h>
452
# ifndef ATTACH_PARENT_PROCESS
453
# define ATTACH_PARENT_PROCESS ((FxU32)-1)
454
# endif
455
#endif
456
457
FX_ENTRY GrContext_t FX_CALL
458
grSstWinOpen(
459
HWND hWnd,
460
GrScreenResolution_t screen_resolution,
461
GrScreenRefresh_t refresh_rate,
462
GrColorFormat_t color_format,
463
GrOriginLocation_t origin_location,
464
int nColBuffers,
465
int nAuxBuffers)
466
{
467
static int show_warning = 1;
468
469
// ZIGGY
470
// allocate static texture names
471
// the initial value should be big enough to support the maximal resolution
472
free_texture = 32*2048*2048;
473
default_texture = free_texture++;
474
color_texture = free_texture++;
475
depth_texture = free_texture++;
476
477
LOG("grSstWinOpen(%08lx, %d, %d, %d, %d, %d %d)\r\n", hWnd, screen_resolution&~0x80000000, refresh_rate, color_format, origin_location, nColBuffers, nAuxBuffers);
478
479
#ifdef _WIN32
480
if ((HWND)hWnd == NULL) hWnd = GetActiveWindow();
481
hwnd_win = (HWND)hWnd;
482
#endif // _WIN32
483
width = height = 0;
484
485
m64p_handle video_general_section;
486
printf("&ConfigOpenSection is %p\n", &ConfigOpenSection);
487
if (ConfigOpenSection("Video-General", &video_general_section) != M64ERR_SUCCESS)
488
{
489
printf("Could not open video settings");
490
return false;
491
}
492
width = ConfigGetParamInt(video_general_section, "ScreenWidth");
493
height = ConfigGetParamInt(video_general_section, "ScreenHeight");
494
fullscreen = ConfigGetParamBool(video_general_section, "Fullscreen");
495
int vsync = ConfigGetParamBool(video_general_section, "VerticalSync");
496
//viewport_offset = ((screen_resolution>>2) > 20) ? screen_resolution >> 2 : 20;
497
// ZIGGY viewport_offset is WIN32 specific, with SDL just set it to zero
498
viewport_offset = 0; //-10 //-20;
499
500
frameBuffer = (unsigned short *)_aligned_malloc(height*width*4, 256);
501
depthBuffer = (unsigned short *)_aligned_malloc(height*width*2, 256);
502
503
// ZIGGY not sure, but it might be better to let the system choose
504
CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1);
505
CoreVideo_GL_SetAttribute(M64P_GL_SWAP_CONTROL, vsync);
506
CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 16);
507
// SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
508
// SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
509
// SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
510
// SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
511
// SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
512
CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 16);
513
514
printf("(II) Setting video mode %dx%d...\n", width, height);
515
if(CoreVideo_SetVideoMode(width, height, 0, fullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, (m64p_video_flags) 0) != M64ERR_SUCCESS)
516
{
517
printf("(EE) Error setting videomode %dx%d\n", width, height);
518
return false;
519
}
520
521
char caption[500];
522
# ifdef _DEBUG
523
sprintf(caption, "Glide64mk2 debug");
524
# else // _DEBUG
525
sprintf(caption, "Glide64mk2");
526
# endif // _DEBUG
527
CoreVideo_SetCaption(caption);
528
529
glViewport(0, viewport_offset, width, height);
530
lfb_color_fmt = color_format;
531
if (origin_location != GR_ORIGIN_UPPER_LEFT) display_warning("origin must be in upper left corner");
532
if (nColBuffers != 2) display_warning("number of color buffer is not 2");
533
if (nAuxBuffers != 1) display_warning("number of auxiliary buffer is not 1");
534
535
if (isExtensionSupported("GL_ARB_texture_env_combine") == 0 &&
536
isExtensionSupported("GL_EXT_texture_env_combine") == 0 &&
537
show_warning)
538
display_warning("Your video card doesn't support GL_ARB_texture_env_combine extension");
539
if (isExtensionSupported("GL_ARB_multitexture") == 0 && show_warning)
540
display_warning("Your video card doesn't support GL_ARB_multitexture extension");
541
if (isExtensionSupported("GL_ARB_texture_mirrored_repeat") == 0 && show_warning)
542
display_warning("Your video card doesn't support GL_ARB_texture_mirrored_repeat extension");
543
show_warning = 0;
544
545
#ifdef _WIN32
546
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
547
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB");
548
#endif // _WIN32
549
550
nbTextureUnits = 0;
551
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &nbTextureUnits);
552
if (nbTextureUnits == 1) display_warning("You need a video card that has at least 2 texture units");
553
554
nbAuxBuffers = 0;
555
glGetIntegerv(GL_AUX_BUFFERS, &nbAuxBuffers);
556
if (nbAuxBuffers > 0)
557
printf("Congratulations, you have %d auxilliary buffers, we'll use them wisely !\n", nbAuxBuffers);
558
559
#ifdef VOODOO1
560
nbTextureUnits = 2;
561
#endif
562
563
if (isExtensionSupported("GL_EXT_blend_func_separate") == 0)
564
blend_func_separate_support = 0;
565
else
566
blend_func_separate_support = 1;
567
568
if (isExtensionSupported("GL_EXT_packed_pixels") == 0)
569
packed_pixels_support = 0;
570
else {
571
printf("packed pixels extension used\n");
572
packed_pixels_support = 1;
573
}
574
575
if (isExtensionSupported("GL_ARB_texture_non_power_of_two") == 0)
576
npot_support = 0;
577
else {
578
printf("NPOT extension used\n");
579
npot_support = 1;
580
}
581
582
#ifdef _WIN32
583
glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)wglGetProcAddress("glBlendFuncSeparateEXT");
584
#endif // _WIN32
585
586
if (isExtensionSupported("GL_EXT_fog_coord") == 0)
587
fog_coord_support = 0;
588
else
589
fog_coord_support = 1;
590
591
#ifdef _WIN32
592
glFogCoordfEXT = (PFNGLFOGCOORDFPROC)wglGetProcAddress("glFogCoordfEXT");
593
#endif // _WIN32
594
595
#ifdef _WIN32
596
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
597
#endif // _WIN32
598
599
#ifdef _WIN32
600
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
601
glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
602
glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");
603
glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
604
glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT");
605
606
glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)wglGetProcAddress("glBindRenderbufferEXT");
607
glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT");
608
glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT");
609
glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT");
610
glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT");
611
use_fbo = config.fbo && (glFramebufferRenderbufferEXT != NULL);
612
#else
613
use_fbo = config.fbo;
614
#endif // _WIN32
615
616
printf("use_fbo %d\n", use_fbo);
617
618
if (isExtensionSupported("GL_ARB_shading_language_100") &&
619
isExtensionSupported("GL_ARB_shader_objects") &&
620
isExtensionSupported("GL_ARB_fragment_shader") &&
621
isExtensionSupported("GL_ARB_vertex_shader"))
622
{
623
624
#ifdef _WIN32
625
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
626
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
627
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
628
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
629
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
630
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
631
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
632
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)wglGetProcAddress("glGetUniformLocationARB");
633
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)wglGetProcAddress("glUniform1iARB");
634
glUniform4iARB = (PFNGLUNIFORM4IARBPROC)wglGetProcAddress("glUniform4iARB");
635
glUniform4fARB = (PFNGLUNIFORM4FARBPROC)wglGetProcAddress("glUniform4fARB");
636
glUniform1fARB = (PFNGLUNIFORM1FARBPROC)wglGetProcAddress("glUniform1fARB");
637
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)wglGetProcAddress("glDeleteObjectARB");
638
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
639
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
640
641
glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)wglGetProcAddress("glSecondaryColor3f");
642
#endif // _WIN32
643
}
644
645
if (isExtensionSupported("GL_EXT_texture_compression_s3tc") == 0 && show_warning)
646
display_warning("Your video card doesn't support GL_EXT_texture_compression_s3tc extension");
647
if (isExtensionSupported("GL_3DFX_texture_compression_FXT1") == 0 && show_warning)
648
display_warning("Your video card doesn't support GL_3DFX_texture_compression_FXT1 extension");
649
650
#ifdef _WIN32
651
glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)wglGetProcAddress("glCompressedTexImage2DARB");
652
#endif
653
654
655
#ifdef _WIN32
656
glViewport(0, viewport_offset, width, height);
657
viewport_width = width;
658
viewport_height = height;
659
nvidia_viewport_hack = 1;
660
#else
661
glViewport(0, viewport_offset, width, height);
662
viewport_width = width;
663
viewport_height = height;
664
#endif // _WIN32
665
666
// void do_benchmarks();
667
// do_benchmarks();
668
669
// VP try to resolve z precision issues
670
glMatrixMode(GL_MODELVIEW);
671
glLoadIdentity();
672
glTranslatef(0, 0, 1-zscale);
673
glScalef(1, 1, zscale);
674
675
widtho = width/2;
676
heighto = height/2;
677
678
pBufferWidth = pBufferHeight = -1;
679
680
current_buffer = GL_BACK;
681
682
texture_unit = GL_TEXTURE0_ARB;
683
684
{
685
int i;
686
for (i=0; i<NB_TEXBUFS; i++)
687
texbufs[i].start = texbufs[i].end = 0xffffffff;
688
}
689
690
if (!use_fbo && nbAuxBuffers == 0) {
691
// create the framebuffer saving texture
692
int w = width, h = height;
693
glBindTexture(GL_TEXTURE_2D, color_texture);
694
if (!npot_support) {
695
w = h = 1;
696
while (w<width) w*=2;
697
while (h<height) h*=2;
698
}
699
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
700
glBindTexture(GL_TEXTURE_2D, 0);
701
save_w = save_h = 0;
702
}
703
704
void FindBestDepthBias();
705
FindBestDepthBias();
706
707
init_geometry();
708
init_textures();
709
init_combiner();
710
711
// Aniso filter check
712
if (config.anisofilter > 0 )
713
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
714
715
// ATI hack - certain texture formats are slow on ATI?
716
// Hmm, perhaps the internal format need to be specified explicitly...
717
{
718
GLint ifmt;
719
glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL);
720
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &ifmt);
721
if (ifmt != GL_RGB5_A1) {
722
display_warning("ATI SUCKS %x\n", ifmt);
723
ati_sucks = 1;
724
} else
725
ati_sucks = 0;
726
}
727
728
return 1;
729
}
730
731
FX_ENTRY void FX_CALL
732
grGlideShutdown( void )
733
{
734
LOG("grGlideShutdown\r\n");
735
}
736
737
FX_ENTRY FxBool FX_CALL
738
grSstWinClose( GrContext_t context )
739
{
740
int i, clear_texbuff = use_fbo;
741
LOG("grSstWinClose(%d)\r\n", context);
742
743
for (i=0; i<2; i++) {
744
tmu_usage[i].min = 0xfffffff;
745
tmu_usage[i].max = 0;
746
invtex[i] = 0;
747
}
748
749
if (frameBuffer)
750
_aligned_free(frameBuffer);
751
if (depthBuffer)
752
_aligned_free(depthBuffer);
753
frameBuffer = depthBuffer = NULL;
754
755
free_combiners();
756
#ifndef WIN32
757
try // I don't know why, but opengl can be killed before this function call when emulator is closed (Gonetz).
758
// ZIGGY : I found the problem : it is a function pointer, when the extension isn't supported , it is then zero, so just need to check the pointer prior to do the call.
759
{
760
if (use_fbo)
761
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
762
}
763
catch (...)
764
{
765
clear_texbuff = 0;
766
}
767
768
if (clear_texbuff)
769
{
770
for (i=0; i<nb_fb; i++)
771
{
772
glDeleteTextures( 1, &(fbs[i].texid) );
773
glDeleteFramebuffersEXT( 1, &(fbs[i].fbid) );
774
glDeleteRenderbuffersEXT( 1, &(fbs[i].zbid) );
775
}
776
}
777
#endif
778
nb_fb = 0;
779
780
free_textures();
781
#ifndef WIN32
782
// ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
783
remove_tex(0, 0xfffffff);
784
#endif
785
786
//*/
787
#ifdef _WIN32
788
if (hGLRC)
789
{
790
wglMakeCurrent(hDC,NULL);
791
wglDeleteContext(hGLRC);
792
hGLRC = NULL;
793
}
794
if (fullscreen)
795
{
796
ChangeDisplaySettings(NULL, 0);
797
SetWindowPos(hwnd_win, NULL,
798
windowedRect.left, windowedRect.top,
799
0, 0,
800
SWP_NOZORDER | SWP_NOSIZE);
801
SetWindowLong(hwnd_win, GWL_STYLE, windowedStyle);
802
SetWindowLong(hwnd_win, GWL_EXSTYLE, windowedExStyle);
803
if (windowedMenu) SetMenu(hwnd_win, windowedMenu);
804
fullscreen = 0;
805
}
806
#else
807
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
808
//sleep(2);
809
#endif
810
return FXTRUE;
811
}
812
813
FX_ENTRY void FX_CALL grTextureBufferExt( GrChipID_t tmu,
814
FxU32 startAddress,
815
GrLOD_t lodmin,
816
GrLOD_t lodmax,
817
GrAspectRatio_t aspect,
818
GrTextureFormat_t fmt,
819
FxU32 evenOdd)
820
{
821
int i;
822
static int fbs_init = 0;
823
824
//printf("grTextureBufferExt(%d, %d, %d, %d, %d, %d, %d)\r\n", tmu, startAddress, lodmin, lodmax, aspect, fmt, evenOdd);
825
LOG("grTextureBufferExt(%d, %d, %d, %d %d, %d, %d)\r\n", tmu, startAddress, lodmin, lodmax, aspect, fmt, evenOdd);
826
if (lodmin != lodmax) display_warning("grTextureBufferExt : loading more than one LOD");
827
if (!use_fbo) {
828
829
if (!render_to_texture) { //initialization
830
return;
831
}
832
833
render_to_texture = 2;
834
835
if (aspect < 0)
836
{
837
pBufferHeight = 1 << lodmin;
838
pBufferWidth = pBufferHeight >> -aspect;
839
}
840
else
841
{
842
pBufferWidth = 1 << lodmin;
843
pBufferHeight = pBufferWidth >> aspect;
844
}
845
846
if (curBufferAddr && startAddress+1 != curBufferAddr)
847
updateTexture();
848
#ifdef SAVE_CBUFFER
849
//printf("saving %dx%d\n", pBufferWidth, pBufferHeight);
850
// save color buffer
851
if (nbAuxBuffers > 0) {
852
glDrawBuffer(GL_AUX0);
853
current_buffer = GL_AUX0;
854
} else {
855
int tw, th;
856
if (pBufferWidth < screen_width)
857
tw = pBufferWidth;
858
else
859
tw = screen_width;
860
if (pBufferHeight < screen_height)
861
th = pBufferHeight;
862
else
863
th = screen_height;
864
glReadBuffer(GL_BACK);
865
glActiveTextureARB(texture_unit);
866
glBindTexture(GL_TEXTURE_2D, color_texture);
867
// save incrementally the framebuffer
868
if (save_w) {
869
if (tw > save_w && th > save_h) {
870
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, save_h,
871
0, viewport_offset+save_h, tw, th-save_h);
872
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, save_w, 0,
873
save_w, viewport_offset, tw-save_w, save_h);
874
save_w = tw;
875
save_h = th;
876
} else if (tw > save_w) {
877
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, save_w, 0,
878
save_w, viewport_offset, tw-save_w, save_h);
879
save_w = tw;
880
} else if (th > save_h) {
881
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, save_h,
882
0, viewport_offset+save_h, save_w, th-save_h);
883
save_h = th;
884
}
885
} else {
886
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
887
0, viewport_offset, tw, th);
888
save_w = tw;
889
save_h = th;
890
}
891
glBindTexture(GL_TEXTURE_2D, default_texture);
892
}
893
#endif
894
895
if (startAddress+1 != curBufferAddr ||
896
(curBufferAddr == 0L && nbAuxBuffers == 0))
897
buffer_cleared = 0;
898
899
curBufferAddr = pBufferAddress = startAddress+1;
900
pBufferFmt = fmt;
901
902
int rtmu = startAddress < grTexMinAddress(GR_TMU1)? 0 : 1;
903
int size = pBufferWidth*pBufferHeight*2; //grTexFormatSize(fmt);
904
if ((unsigned int) tmu_usage[rtmu].min > pBufferAddress)
905
tmu_usage[rtmu].min = pBufferAddress;
906
if ((unsigned int) tmu_usage[rtmu].max < pBufferAddress+size)
907
tmu_usage[rtmu].max = pBufferAddress+size;
908
// printf("tmu %d usage now %gMb - %gMb\n",
909
// rtmu, tmu_usage[rtmu].min/1024.0f, tmu_usage[rtmu].max/1024.0f);
910
911
912
width = pBufferWidth;
913
height = pBufferHeight;
914
915
widtho = width/2;
916
heighto = height/2;
917
918
// this could be improved, but might be enough as long as the set of
919
// texture buffer addresses stay small
920
for (i=(texbuf_i-1)&(NB_TEXBUFS-1) ; i!=texbuf_i; i=(i-1)&(NB_TEXBUFS-1))
921
if (texbufs[i].start == pBufferAddress)
922
break;
923
texbufs[i].start = pBufferAddress;
924
texbufs[i].end = pBufferAddress + size;
925
texbufs[i].fmt = fmt;
926
if (i == texbuf_i)
927
texbuf_i = (texbuf_i+1)&(NB_TEXBUFS-1);
928
//printf("texbuf %x fmt %x\n", pBufferAddress, fmt);
929
930
// ZIGGY it speeds things up to not delete the buffers
931
// a better thing would be to delete them *sometimes*
932
// remove_tex(pBufferAddress+1, pBufferAddress + size);
933
add_tex(pBufferAddress);
934
935
//printf("viewport %dx%d\n", width, height);
936
if (height > screen_height) {
937
glViewport( 0, viewport_offset + screen_height - height, width, height);
938
} else
939
glViewport( 0, viewport_offset, width, height);
940
941
glScissor(0, viewport_offset, width, height);
942
943
944
} else {
945
if (!render_to_texture) //initialization
946
{
947
if(!fbs_init)
948
{
949
for(i=0; i<100; i++) fbs[i].address = 0;
950
fbs_init = 1;
951
nb_fb = 0;
952
}
953
return; //no need to allocate FBO if render buffer is not texture buffer
954
}
955
956
render_to_texture = 2;
957
958
if (aspect < 0)
959
{
960
pBufferHeight = 1 << lodmin;
961
pBufferWidth = pBufferHeight >> -aspect;
962
}
963
else
964
{
965
pBufferWidth = 1 << lodmin;
966
pBufferHeight = pBufferWidth >> aspect;
967
}
968
pBufferAddress = startAddress+1;
969
970
width = pBufferWidth;
971
height = pBufferHeight;
972
973
widtho = width/2;
974
heighto = height/2;
975
976
for (i=0; i<nb_fb; i++)
977
{
978
if (fbs[i].address == pBufferAddress)
979
{
980
if (fbs[i].width == width && fbs[i].height == height) //select already allocated FBO
981
{
982
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
983
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbs[i].fbid );
984
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbs[i].texid, 0 );
985
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, fbs[i].zbid );
986
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbs[i].zbid );
987
glViewport( 0, 0, width, height);
988
glScissor( 0, 0, width, height);
989
if (fbs[i].buff_clear)
990
{
991
glDepthMask(1);
992
glClear( GL_DEPTH_BUFFER_BIT ); //clear z-buffer only. we may need content, stored in the frame buffer
993
fbs[i].buff_clear = 0;
994
}
995
CHECK_FRAMEBUFFER_STATUS();
996
curBufferAddr = pBufferAddress;
997
return;
998
}
999
else //create new FBO at the same address, delete old one
1000
{
1001
glDeleteFramebuffersEXT( 1, &(fbs[i].fbid) );
1002
glDeleteRenderbuffersEXT( 1, &(fbs[i].zbid) );
1003
if (nb_fb > 1)
1004
memmove(&(fbs[i]), &(fbs[i+1]), sizeof(fb)*(nb_fb-i));
1005
nb_fb--;
1006
break;
1007
}
1008
}
1009
}
1010
1011
remove_tex(pBufferAddress, pBufferAddress + width*height*2/*grTexFormatSize(fmt)*/);
1012
//create new FBO
1013
glGenFramebuffersEXT( 1, &(fbs[nb_fb].fbid) );
1014
glGenRenderbuffersEXT( 1, &(fbs[nb_fb].zbid) );
1015
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, fbs[nb_fb].zbid );
1016
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
1017
fbs[nb_fb].address = pBufferAddress;
1018
fbs[nb_fb].width = width;
1019
fbs[nb_fb].height = height;
1020
fbs[nb_fb].texid = pBufferAddress;
1021
fbs[nb_fb].buff_clear = 0;
1022
add_tex(fbs[nb_fb].texid);
1023
glBindTexture(GL_TEXTURE_2D, fbs[nb_fb].texid);
1024
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
1025
GL_RGB, GL_UNSIGNED_BYTE, NULL);
1026
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1027
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
1028
1029
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbs[nb_fb].fbid);
1030
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
1031
GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbs[nb_fb].texid, 0);
1032
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbs[nb_fb].zbid );
1033
glViewport(0,0,width,height);
1034
glScissor(0,0,width,height);
1035
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
1036
glDepthMask(1);
1037
glClear( GL_DEPTH_BUFFER_BIT );
1038
CHECK_FRAMEBUFFER_STATUS();
1039
curBufferAddr = pBufferAddress;
1040
nb_fb++;
1041
}
1042
}
1043
1044
int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info )
1045
{
1046
int found, i;
1047
if (!use_fbo) {
1048
for (found=i=0; i<2; i++)
1049
if ((FxU32) tmu_usage[i].min <= startAddress && (FxU32) tmu_usage[i].max > startAddress) {
1050
//printf("tmu %d == framebuffer %x\n", tmu, startAddress);
1051
found = 1;
1052
break;
1053
}
1054
} else {
1055
found = i = 0;
1056
while (i < nb_fb)
1057
{
1058
unsigned int end = fbs[i].address + fbs[i].width*fbs[i].height*2;
1059
if (startAddress >= fbs[i].address && startAddress < end)
1060
{
1061
found = 1;
1062
break;
1063
}
1064
i++;
1065
}
1066
}
1067
1068
if (!use_fbo && found) {
1069
int tw, th, rh, cw, ch;
1070
if (info->aspectRatioLog2 < 0)
1071
{
1072
th = 1 << info->largeLodLog2;
1073
tw = th >> -info->aspectRatioLog2;
1074
}
1075
else
1076
{
1077
tw = 1 << info->largeLodLog2;
1078
th = tw >> info->aspectRatioLog2;
1079
}
1080
1081
if (info->aspectRatioLog2 < 0)
1082
{
1083
ch = 256;
1084
cw = ch >> -info->aspectRatioLog2;
1085
}
1086
else
1087
{
1088
cw = 256;
1089
ch = cw >> info->aspectRatioLog2;
1090
}
1091
1092
if (use_fbo || th < screen_height)
1093
rh = th;
1094
else
1095
rh = screen_height;
1096
1097
//printf("th %d rh %d ch %d\n", th, rh, ch);
1098
1099
invtex[tmu] = 1.0f - (th - rh) / (float)th;
1100
} else
1101
invtex[tmu] = 0;
1102
1103
if (info->format == GR_TEXFMT_ALPHA_INTENSITY_88 ) {
1104
if (!found) {
1105
return 0;
1106
}
1107
if(tmu == 0)
1108
{
1109
if(blackandwhite1 != found)
1110
{
1111
blackandwhite1 = found;
1112
need_to_compile = 1;
1113
}
1114
}
1115
else
1116
{
1117
if(blackandwhite0 != found)
1118
{
1119
blackandwhite0 = found;
1120
need_to_compile = 1;
1121
}
1122
}
1123
return 1;
1124
}
1125
return 0;
1126
1127
}
1128
1129
1130
FX_ENTRY void FX_CALL
1131
grTextureAuxBufferExt( GrChipID_t tmu,
1132
FxU32 startAddress,
1133
GrLOD_t thisLOD,
1134
GrLOD_t largeLOD,
1135
GrAspectRatio_t aspectRatio,
1136
GrTextureFormat_t format,
1137
FxU32 odd_even_mask )
1138
{
1139
LOG("grTextureAuxBufferExt(%d, %d, %d, %d %d, %d, %d)\r\n", tmu, startAddress, thisLOD, largeLOD, aspectRatio, format, odd_even_mask);
1140
//display_warning("grTextureAuxBufferExt");
1141
}
1142
1143
FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );
1144
1145
FX_ENTRY GrProc FX_CALL
1146
grGetProcAddress( char *procName )
1147
{
1148
LOG("grGetProcAddress(%s)\r\n", procName);
1149
if(!strcmp(procName, "grSstWinOpenExt"))
1150
return (GrProc)grSstWinOpenExt;
1151
if(!strcmp(procName, "grTextureBufferExt"))
1152
return (GrProc)grTextureBufferExt;
1153
if(!strcmp(procName, "grChromaRangeExt"))
1154
return (GrProc)grChromaRangeExt;
1155
if(!strcmp(procName, "grChromaRangeModeExt"))
1156
return (GrProc)grChromaRangeModeExt;
1157
if(!strcmp(procName, "grTexChromaRangeExt"))
1158
return (GrProc)grTexChromaRangeExt;
1159
if(!strcmp(procName, "grTexChromaModeExt"))
1160
return (GrProc)grTexChromaModeExt;
1161
// ZIGGY framebuffer copy extension
1162
if(!strcmp(procName, "grFramebufferCopyExt"))
1163
return (GrProc)grFramebufferCopyExt;
1164
if(!strcmp(procName, "grColorCombineExt"))
1165
return (GrProc)grColorCombineExt;
1166
if(!strcmp(procName, "grAlphaCombineExt"))
1167
return (GrProc)grAlphaCombineExt;
1168
if(!strcmp(procName, "grTexColorCombineExt"))
1169
return (GrProc)grTexColorCombineExt;
1170
if(!strcmp(procName, "grTexAlphaCombineExt"))
1171
return (GrProc)grTexAlphaCombineExt;
1172
if(!strcmp(procName, "grConstantColorValueExt"))
1173
return (GrProc)grConstantColorValueExt;
1174
if(!strcmp(procName, "grTextureAuxBufferExt"))
1175
return (GrProc)grTextureAuxBufferExt;
1176
if(!strcmp(procName, "grAuxBufferExt"))
1177
return (GrProc)grAuxBufferExt;
1178
if(!strcmp(procName, "grWrapperFullScreenResolutionExt"))
1179
return (GrProc)grWrapperFullScreenResolutionExt;
1180
if(!strcmp(procName, "grConfigWrapperExt"))
1181
return (GrProc)grConfigWrapperExt;
1182
if(!strcmp(procName, "grKeyPressedExt"))
1183
return (GrProc)grKeyPressedExt;
1184
if(!strcmp(procName, "grQueryResolutionsExt"))
1185
return (GrProc)grQueryResolutionsExt;
1186
if(!strcmp(procName, "grGetGammaTableExt"))
1187
return (GrProc)grGetGammaTableExt;
1188
display_warning("grGetProcAddress : %s", procName);
1189
return 0;
1190
}
1191
1192
FX_ENTRY FxU32 FX_CALL
1193
grGet( FxU32 pname, FxU32 plength, FxI32 *params )
1194
{
1195
LOG("grGet(%d,%d)\r\n", pname, plength);
1196
switch(pname)
1197
{
1198
case GR_MAX_TEXTURE_SIZE:
1199
if (plength < 4 || params == NULL) return 0;
1200
params[0] = 2048;
1201
return 4;
1202
break;
1203
case GR_NUM_TMU:
1204
if (plength < 4 || params == NULL) return 0;
1205
if (!nbTextureUnits)
1206
{
1207
grSstWinOpen((unsigned long)NULL, GR_RESOLUTION_640x480 | 0x80000000, 0, GR_COLORFORMAT_ARGB,
1208
GR_ORIGIN_UPPER_LEFT, 2, 1);
1209
grSstWinClose(0);
1210
}
1211
#ifdef VOODOO1
1212
params[0] = 1;
1213
#else
1214
if (nbTextureUnits > 2)
1215
params[0] = 2;
1216
else
1217
params[0] = 1;
1218
#endif
1219
return 4;
1220
break;
1221
case GR_NUM_BOARDS:
1222
case GR_NUM_FB:
1223
case GR_REVISION_FB:
1224
case GR_REVISION_TMU:
1225
if (plength < 4 || params == NULL) return 0;
1226
params[0] = 1;
1227
return 4;
1228
break;
1229
case GR_MEMORY_FB:
1230
if (plength < 4 || params == NULL) return 0;
1231
params[0] = 16*1024*1024;
1232
return 4;
1233
break;
1234
case GR_MEMORY_TMU:
1235
if (plength < 4 || params == NULL) return 0;
1236
params[0] = 16*1024*1024;
1237
return 4;
1238
break;
1239
case GR_MEMORY_UMA:
1240
if (plength < 4 || params == NULL) return 0;
1241
params[0] = 16*1024*1024*nbTextureUnits;
1242
return 4;
1243
break;
1244
case GR_BITS_RGBA:
1245
if (plength < 16 || params == NULL) return 0;
1246
params[0] = 8;
1247
params[1] = 8;
1248
params[2] = 8;
1249
params[3] = 8;
1250
return 16;
1251
break;
1252
case GR_BITS_DEPTH:
1253
if (plength < 4 || params == NULL) return 0;
1254
params[0] = 16;
1255
return 4;
1256
break;
1257
case GR_BITS_GAMMA:
1258
if (plength < 4 || params == NULL) return 0;
1259
params[0] = 8;
1260
return 4;
1261
break;
1262
case GR_GAMMA_TABLE_ENTRIES:
1263
if (plength < 4 || params == NULL) return 0;
1264
params[0] = 256;
1265
return 4;
1266
break;
1267
case GR_FOG_TABLE_ENTRIES:
1268
if (plength < 4 || params == NULL) return 0;
1269
params[0] = 64;
1270
return 4;
1271
break;
1272
case GR_WDEPTH_MIN_MAX:
1273
if (plength < 8 || params == NULL) return 0;
1274
params[0] = 0;
1275
params[1] = 65528;
1276
return 8;
1277
break;
1278
case GR_ZDEPTH_MIN_MAX:
1279
if (plength < 8 || params == NULL) return 0;
1280
params[0] = 0;
1281
params[1] = 65535;
1282
return 8;
1283
break;
1284
case GR_LFB_PIXEL_PIPE:
1285
if (plength < 4 || params == NULL) return 0;
1286
params[0] = FXFALSE;
1287
return 4;
1288
break;
1289
case GR_MAX_TEXTURE_ASPECT_RATIO:
1290
if (plength < 4 || params == NULL) return 0;
1291
params[0] = 3;
1292
return 4;
1293
break;
1294
case GR_NON_POWER_OF_TWO_TEXTURES:
1295
if (plength < 4 || params == NULL) return 0;
1296
params[0] = FXFALSE;
1297
return 4;
1298
break;
1299
case GR_TEXTURE_ALIGN:
1300
if (plength < 4 || params == NULL) return 0;
1301
params[0] = 0;
1302
return 4;
1303
break;
1304
default:
1305
display_warning("unknown pname in grGet : %x", pname);
1306
}
1307
return 0;
1308
}
1309
1310
FX_ENTRY const char * FX_CALL
1311
grGetString( FxU32 pname )
1312
{
1313
LOG("grGetString(%d)\r\n", pname);
1314
switch(pname)
1315
{
1316
case GR_EXTENSION:
1317
{
1318
static char extension[] = "CHROMARANGE TEXCHROMA TEXMIRROR PALETTE6666 FOGCOORD EVOODOO TEXTUREBUFFER TEXUMA TEXFMT COMBINE GETGAMMA";
1319
return extension;
1320
}
1321
break;
1322
case GR_HARDWARE:
1323
{
1324
static char hardware[] = "Voodoo5 (tm)";
1325
return hardware;
1326
}
1327
break;
1328
case GR_VENDOR:
1329
{
1330
static char vendor[] = "3Dfx Interactive";
1331
return vendor;
1332
}
1333
break;
1334
case GR_RENDERER:
1335
{
1336
static char renderer[] = "Glide";
1337
return renderer;
1338
}
1339
break;
1340
case GR_VERSION:
1341
{
1342
static char version[] = "3.0";
1343
return version;
1344
}
1345
break;
1346
default:
1347
display_warning("unknown grGetString selector : %x", pname);
1348
}
1349
return NULL;
1350
}
1351
1352
static void render_rectangle(int texture_number,
1353
int dst_x, int dst_y,
1354
int src_width, int src_height,
1355
int tex_width, int tex_height, int invert)
1356
{
1357
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1358
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1359
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1360
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1361
glBegin(GL_QUADS);
1362
glMultiTexCoord2fARB(texture_number, 0.0f, 0.0f);
1363
glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1364
invert*-((int)dst_y - heighto) / (float)(height/2));
1365
glMultiTexCoord2fARB(texture_number, 0.0f, (float)src_height / (float)tex_height);
1366
glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1367
invert*-((int)dst_y + (int)src_height - heighto) / (float)(height/2));
1368
glMultiTexCoord2fARB(texture_number, (float)src_width / (float)tex_width, (float)src_height / (float)tex_height);
1369
glVertex2f(((int)dst_x + (int)src_width - widtho) / (float)(width/2),
1370
invert*-((int)dst_y + (int)src_height - heighto) / (float)(height/2));
1371
glMultiTexCoord2fARB(texture_number, (float)src_width / (float)tex_width, 0.0f);
1372
glVertex2f(((int)dst_x + (int)src_width - widtho) / (float)(width/2),
1373
invert*-((int)dst_y - heighto) / (float)(height/2));
1374
glMultiTexCoord2fARB(texture_number, 0.0f, 0.0f);
1375
glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1376
invert*-((int)dst_y - heighto) / (float)(height/2));
1377
glEnd();
1378
1379
compile_shader();
1380
1381
glEnable(GL_DEPTH_TEST);
1382
glEnable(GL_BLEND);
1383
}
1384
1385
void reloadTexture()
1386
{
1387
if (use_fbo || !render_to_texture || buffer_cleared)
1388
return;
1389
1390
LOG("reload texture %dx%d\n", width, height);
1391
//printf("reload texture %dx%d\n", width, height);
1392
1393
buffer_cleared = 1;
1394
1395
glPushAttrib(GL_ALL_ATTRIB_BITS);
1396
glActiveTextureARB(texture_unit);
1397
glBindTexture(GL_TEXTURE_2D, pBufferAddress);
1398
glDisable(GL_ALPHA_TEST);
1399
glDrawBuffer(current_buffer);
1400
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1401
set_copy_shader();
1402
glDisable(GL_DEPTH_TEST);
1403
glDisable(GL_CULL_FACE);
1404
int w = 0, h = 0;
1405
if (height > screen_height) h = screen_height - height;
1406
render_rectangle(texture_unit,
1407
-w, -h,
1408
width, height,
1409
width, height, -1);
1410
glBindTexture(GL_TEXTURE_2D, default_texture);
1411
glPopAttrib();
1412
}
1413
1414
void updateTexture()
1415
{
1416
if (!use_fbo && render_to_texture == 2) {
1417
LOG("update texture %x\n", pBufferAddress);
1418
//printf("update texture %x\n", pBufferAddress);
1419
1420
// nothing changed, don't update the texture
1421
if (!buffer_cleared) {
1422
LOG("update cancelled\n", pBufferAddress);
1423
return;
1424
}
1425
1426
glPushAttrib(GL_ALL_ATTRIB_BITS);
1427
1428
// save result of render to texture into actual texture
1429
glReadBuffer(current_buffer);
1430
glActiveTextureARB(texture_unit);
1431
// ZIGGY
1432
// deleting the texture before resampling it increases speed on certain old
1433
// nvidia cards (geforce 2 for example), unfortunatly it slows down a lot
1434
// on newer cards.
1435
//glDeleteTextures( 1, &pBufferAddress );
1436
glBindTexture(GL_TEXTURE_2D, pBufferAddress);
1437
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
1438
0, viewport_offset, width, height, 0);
1439
1440
glBindTexture(GL_TEXTURE_2D, default_texture);
1441
glPopAttrib();
1442
}
1443
}
1444
1445
FX_ENTRY void FX_CALL grFramebufferCopyExt(int x, int y, int w, int h,
1446
int from, int to, int mode)
1447
{
1448
if (mode == GR_FBCOPY_MODE_DEPTH) {
1449
1450
int tw = 1, th = 1;
1451
if (npot_support) {
1452
tw = width; th = height;
1453
} else {
1454
while (tw < width) tw <<= 1;
1455
while (th < height) th <<= 1;
1456
}
1457
1458
if (from == GR_FBCOPY_BUFFER_BACK && to == GR_FBCOPY_BUFFER_FRONT) {
1459
//printf("save depth buffer %d\n", render_to_texture);
1460
// save the depth image in a texture
1461
glReadBuffer(current_buffer);
1462
glBindTexture(GL_TEXTURE_2D, depth_texture);
1463
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
1464
0, viewport_offset, tw, th, 0);
1465
glBindTexture(GL_TEXTURE_2D, default_texture);
1466
return;
1467
}
1468
if (from == GR_FBCOPY_BUFFER_FRONT && to == GR_FBCOPY_BUFFER_BACK) {
1469
//printf("writing to depth buffer %d\n", render_to_texture);
1470
glPushAttrib(GL_ALL_ATTRIB_BITS);
1471
glDisable(GL_ALPHA_TEST);
1472
glDrawBuffer(current_buffer);
1473
glActiveTextureARB(texture_unit);
1474
glBindTexture(GL_TEXTURE_2D, depth_texture);
1475
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1476
set_depth_shader();
1477
glEnable(GL_DEPTH_TEST);
1478
glDepthFunc(GL_ALWAYS);
1479
glDisable(GL_CULL_FACE);
1480
render_rectangle(texture_unit,
1481
0, 0,
1482
width, height,
1483
tw, th, -1);
1484
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1485
glBindTexture(GL_TEXTURE_2D, default_texture);
1486
glPopAttrib();
1487
return;
1488
}
1489
1490
}
1491
}
1492
1493
FX_ENTRY void FX_CALL
1494
grRenderBuffer( GrBuffer_t buffer )
1495
{
1496
#ifdef _WIN32
1497
static HANDLE region = NULL;
1498
int realWidth = pBufferWidth, realHeight = pBufferHeight;
1499
#endif // _WIN32
1500
LOG("grRenderBuffer(%d)\r\n", buffer);
1501
//printf("grRenderBuffer(%d)\n", buffer);
1502
1503
switch(buffer)
1504
{
1505
case GR_BUFFER_BACKBUFFER:
1506
if(render_to_texture)
1507
{
1508
updateTexture();
1509
1510
// VP z fix
1511
glMatrixMode(GL_MODELVIEW);
1512
glLoadIdentity();
1513
glTranslatef(0, 0, 1-zscale);
1514
glScalef(1, 1, zscale);
1515
inverted_culling = 0;
1516
grCullMode(culling_mode);
1517
1518
width = savedWidth;
1519
height = savedHeight;
1520
widtho = savedWidtho;
1521
heighto = savedHeighto;
1522
if (use_fbo) {
1523
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1524
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
1525
}
1526
curBufferAddr = 0;
1527
1528
glViewport(0, viewport_offset, width, viewport_height);
1529
glScissor(0, viewport_offset, width, height);
1530
1531
#ifdef SAVE_CBUFFER
1532
if (!use_fbo && render_to_texture == 2) {
1533
// restore color buffer
1534
if (nbAuxBuffers > 0) {
1535
glDrawBuffer(GL_BACK);
1536
current_buffer = GL_BACK;
1537
} else if (save_w) {
1538
int tw = 1, th = 1;
1539
//printf("restore %dx%d\n", save_w, save_h);
1540
if (npot_support) {
1541
tw = screen_width;
1542
th = screen_height;
1543
} else {
1544
while (tw < screen_width) tw <<= 1;
1545
while (th < screen_height) th <<= 1;
1546
}
1547
1548
glPushAttrib(GL_ALL_ATTRIB_BITS);
1549
glDisable(GL_ALPHA_TEST);
1550
glDrawBuffer(GL_BACK);
1551
glActiveTextureARB(texture_unit);
1552
glBindTexture(GL_TEXTURE_2D, color_texture);
1553
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1554
set_copy_shader();
1555
glDisable(GL_DEPTH_TEST);
1556
glDisable(GL_CULL_FACE);
1557
render_rectangle(texture_unit,
1558
0, 0,
1559
save_w, save_h,
1560
tw, th, -1);
1561
glBindTexture(GL_TEXTURE_2D, default_texture);
1562
glPopAttrib();
1563
1564
save_w = save_h = 0;
1565
}
1566
}
1567
#endif
1568
render_to_texture = 0;
1569
}
1570
glDrawBuffer(GL_BACK);
1571
break;
1572
case 6: // RENDER TO TEXTURE
1573
if(!render_to_texture)
1574
{
1575
savedWidth = width;
1576
savedHeight = height;
1577
savedWidtho = widtho;
1578
savedHeighto = heighto;
1579
}
1580
1581
{
1582
if (!use_fbo) {
1583
glMatrixMode(GL_MODELVIEW);
1584
glLoadIdentity();
1585
glTranslatef(0, 0, 1-zscale);
1586
glScalef(1, 1, zscale);
1587
inverted_culling = 0;
1588
} else {
1589
float m[4*4] = {1.0f, 0.0f, 0.0f, 0.0f,
1590
0.0f,-1.0f, 0.0f, 0.0f,
1591
0.0f, 0.0f, 1.0f, 0.0f,
1592
0.0f, 0.0f, 0.0f, 1.0f};
1593
glMatrixMode(GL_MODELVIEW);
1594
glLoadMatrixf(m);
1595
// VP z fix
1596
glTranslatef(0, 0, 1-zscale);
1597
glScalef(1, 1*1, zscale);
1598
inverted_culling = 1;
1599
grCullMode(culling_mode);
1600
}
1601
}
1602
render_to_texture = 1;
1603
break;
1604
default:
1605
display_warning("grRenderBuffer : unknown buffer : %x", buffer);
1606
}
1607
}
1608
1609
FX_ENTRY void FX_CALL
1610
grAuxBufferExt( GrBuffer_t buffer )
1611
{
1612
LOG("grAuxBufferExt(%d)\r\n", buffer);
1613
//display_warning("grAuxBufferExt");
1614
1615
if (buffer == GR_BUFFER_AUXBUFFER) {
1616
invtex[0] = 0;
1617
invtex[1] = 0;
1618
need_to_compile = 0;
1619
set_depth_shader();
1620
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1621
glEnable(GL_DEPTH_TEST);
1622
glDepthFunc(GL_ALWAYS);
1623
glDisable(GL_CULL_FACE);
1624
glDisable(GL_ALPHA_TEST);
1625
glDepthMask(GL_TRUE);
1626
grTexFilterMode(GR_TMU1, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
1627
} else {
1628
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1629
need_to_compile = 1;
1630
}
1631
}
1632
1633
FX_ENTRY void FX_CALL
1634
grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU32 depth )
1635
{
1636
LOG("grBufferClear(%d,%d,%d)\r\n", color, alpha, depth);
1637
switch(lfb_color_fmt)
1638
{
1639
case GR_COLORFORMAT_ARGB:
1640
glClearColor(((color >> 16) & 0xFF) / 255.0f,
1641
((color >> 8) & 0xFF) / 255.0f,
1642
( color & 0xFF) / 255.0f,
1643
alpha / 255.0f);
1644
break;
1645
case GR_COLORFORMAT_RGBA:
1646
glClearColor(((color >> 24) & 0xFF) / 255.0f,
1647
((color >> 16) & 0xFF) / 255.0f,
1648
(color & 0xFF) / 255.0f,
1649
alpha / 255.0f);
1650
break;
1651
default:
1652
display_warning("grBufferClear: unknown color format : %x", lfb_color_fmt);
1653
}
1654
1655
if (w_buffer_mode)
1656
glClearDepth(1.0f - ((1.0f + (depth >> 4) / 4096.0f) * (1 << (depth & 0xF))) / 65528.0);
1657
else
1658
glClearDepth(depth / 65535.0f);
1659
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1660
1661
// ZIGGY TODO check that color mask is on
1662
buffer_cleared = 1;
1663
1664
}
1665
1666
// #include <unistd.h>
1667
FX_ENTRY void FX_CALL
1668
grBufferSwap( FxU32 swap_interval )
1669
{
1670
glFinish();
1671
glUseProgramObjectARB(0);
1672
// printf("rendercallback is %p\n", renderCallback);
1673
if(renderCallback)
1674
(*renderCallback)(1);
1675
int i;
1676
LOG("grBufferSwap(%d)\r\n", swap_interval);
1677
//printf("swap\n");
1678
if (render_to_texture) {
1679
display_warning("swap while render_to_texture\n");
1680
return;
1681
}
1682
1683
CoreVideo_GL_SwapBuffers();
1684
for (i = 0; i < nb_fb; i++)
1685
fbs[i].buff_clear = 1;
1686
1687
// VP debugging
1688
#ifdef VPDEBUG
1689
dump_stop();
1690
SDL_Event event;
1691
while (SDL_PollEvent(&event)) {
1692
switch (event.type) {
1693
case SDL_KEYDOWN:
1694
switch (event.key.keysym.sym) {
1695
case 'd':
1696
printf("Dumping !\n");
1697
dump_start();
1698
break;
1699
case 'w': {
1700
static int wireframe;
1701
wireframe = !wireframe;
1702
glPolygonMode(GL_FRONT_AND_BACK, wireframe? GL_LINE : GL_FILL);
1703
break;
1704
}
1705
}
1706
break;
1707
}
1708
}
1709
#endif
1710
}
1711
1712
// frame buffer
1713
1714
FX_ENTRY FxBool FX_CALL
1715
grLfbLock( GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode,
1716
GrOriginLocation_t origin, FxBool pixelPipeline,
1717
GrLfbInfo_t *info )
1718
{
1719
LOG("grLfbLock(%d,%d,%d,%d,%d)\r\n", type, buffer, writeMode, origin, pixelPipeline);
1720
if (type == GR_LFB_WRITE_ONLY)
1721
{
1722
display_warning("grLfbLock : write only");
1723
}
1724
else
1725
{
1726
unsigned char *buf;
1727
int i,j;
1728
1729
switch(buffer)
1730
{
1731
case GR_BUFFER_FRONTBUFFER:
1732
glReadBuffer(GL_FRONT);
1733
break;
1734
case GR_BUFFER_BACKBUFFER:
1735
glReadBuffer(GL_BACK);
1736
break;
1737
default:
1738
display_warning("grLfbLock : unknown buffer : %x", buffer);
1739
}
1740
1741
if(buffer != GR_BUFFER_AUXBUFFER)
1742
{
1743
if (writeMode == GR_LFBWRITEMODE_888) {
1744
//printf("LfbLock GR_LFBWRITEMODE_888\n");
1745
info->lfbPtr = frameBuffer;
1746
info->strideInBytes = width*4;
1747
info->writeMode = GR_LFBWRITEMODE_888;
1748
info->origin = origin;
1749
glReadPixels(0, viewport_offset, width, height, GL_BGRA, GL_UNSIGNED_BYTE, frameBuffer);
1750
} else {
1751
buf = (unsigned char*)malloc(width*height*4);
1752
1753
info->lfbPtr = frameBuffer;
1754
info->strideInBytes = width*2;
1755
info->writeMode = GR_LFBWRITEMODE_565;
1756
info->origin = origin;
1757
glReadPixels(0, viewport_offset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1758
1759
for (j=0; j<height; j++)
1760
{
1761
for (i=0; i<width; i++)
1762
{
1763
frameBuffer[(height-j-1)*width+i] =
1764
((buf[j*width*4+i*4+0] >> 3) << 11) |
1765
((buf[j*width*4+i*4+1] >> 2) << 5) |
1766
(buf[j*width*4+i*4+2] >> 3);
1767
}
1768
}
1769
free(buf);
1770
}
1771
}
1772
else
1773
{
1774
info->lfbPtr = depthBuffer;
1775
info->strideInBytes = width*2;
1776
info->writeMode = GR_LFBWRITEMODE_ZA16;
1777
info->origin = origin;
1778
glReadPixels(0, viewport_offset, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
1779
}
1780
}
1781
1782
return FXTRUE;
1783
}
1784
1785
FX_ENTRY FxBool FX_CALL
1786
grLfbUnlock( GrLock_t type, GrBuffer_t buffer )
1787
{
1788
LOG("grLfbUnlock(%d,%d)\r\n", type, buffer);
1789
if (type == GR_LFB_WRITE_ONLY)
1790
{
1791
display_warning("grLfbUnlock : write only");
1792
}
1793
return FXTRUE;
1794
}
1795
1796
FX_ENTRY FxBool FX_CALL
1797
grLfbReadRegion( GrBuffer_t src_buffer,
1798
FxU32 src_x, FxU32 src_y,
1799
FxU32 src_width, FxU32 src_height,
1800
FxU32 dst_stride, void *dst_data )
1801
{
1802
unsigned char *buf;
1803
unsigned int i,j;
1804
unsigned short *frameBuffer = (unsigned short*)dst_data;
1805
unsigned short *depthBuffer = (unsigned short*)dst_data;
1806
LOG("grLfbReadRegion(%d,%d,%d,%d,%d,%d)\r\n", src_buffer, src_x, src_y, src_width, src_height, dst_stride);
1807
1808
switch(src_buffer)
1809
{
1810
case GR_BUFFER_FRONTBUFFER:
1811
glReadBuffer(GL_FRONT);
1812
break;
1813
case GR_BUFFER_BACKBUFFER:
1814
glReadBuffer(GL_BACK);
1815
break;
1816
/*case GR_BUFFER_AUXBUFFER:
1817
glReadBuffer(current_buffer);
1818
break;*/
1819
default:
1820
display_warning("grReadRegion : unknown buffer : %x", src_buffer);
1821
}
1822
1823
if(src_buffer != GR_BUFFER_AUXBUFFER)
1824
{
1825
buf = (unsigned char*)malloc(src_width*src_height*4);
1826
1827
glReadPixels(src_x, (viewport_offset)+height-src_y-src_height, src_width, src_height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1828
1829
for (j=0; j<src_height; j++)
1830
{
1831
for (i=0; i<src_width; i++)
1832
{
1833
frameBuffer[j*(dst_stride/2)+i] =
1834
((buf[(src_height-j-1)*src_width*4+i*4+0] >> 3) << 11) |
1835
((buf[(src_height-j-1)*src_width*4+i*4+1] >> 2) << 5) |
1836
(buf[(src_height-j-1)*src_width*4+i*4+2] >> 3);
1837
}
1838
}
1839
free(buf);
1840
}
1841
else
1842
{
1843
buf = (unsigned char*)malloc(src_width*src_height*2);
1844
1845
glReadPixels(src_x, (viewport_offset)+height-src_y-src_height, src_width, src_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
1846
1847
for (j=0;j<src_height; j++)
1848
{
1849
for (i=0; i<src_width; i++)
1850
{
1851
depthBuffer[j*(dst_stride/2)+i] =
1852
((unsigned short*)buf)[(src_height-j-1)*src_width*4+i*4];
1853
}
1854
}
1855
free(buf);
1856
}
1857
1858
return FXTRUE;
1859
}
1860
1861
FX_ENTRY FxBool FX_CALL
1862
grLfbWriteRegion( GrBuffer_t dst_buffer,
1863
FxU32 dst_x, FxU32 dst_y,
1864
GrLfbSrcFmt_t src_format,
1865
FxU32 src_width, FxU32 src_height,
1866
FxBool pixelPipeline,
1867
FxI32 src_stride, void *src_data )
1868
{
1869
unsigned char *buf;
1870
unsigned int i,j;
1871
unsigned short *frameBuffer = (unsigned short*)src_data;
1872
int texture_number;
1873
unsigned int tex_width = 1, tex_height = 1;
1874
LOG("grLfbWriteRegion(%d,%d,%d,%d,%d,%d,%d,%d)\r\n",dst_buffer, dst_x, dst_y, src_format, src_width, src_height, pixelPipeline, src_stride);
1875
1876
glPushAttrib(GL_ALL_ATTRIB_BITS);
1877
1878
while (tex_width < src_width) tex_width <<= 1;
1879
while (tex_height < src_height) tex_height <<= 1;
1880
1881
switch(dst_buffer)
1882
{
1883
case GR_BUFFER_BACKBUFFER:
1884
glDrawBuffer(GL_BACK);
1885
break;
1886
case GR_BUFFER_AUXBUFFER:
1887
glDrawBuffer(current_buffer);
1888
break;
1889
default:
1890
display_warning("grLfbWriteRegion : unknown buffer : %x", dst_buffer);
1891
}
1892
1893
if(dst_buffer != GR_BUFFER_AUXBUFFER)
1894
{
1895
buf = (unsigned char*)malloc(tex_width*tex_height*4);
1896
1897
texture_number = GL_TEXTURE0_ARB;
1898
glActiveTextureARB(texture_number);
1899
1900
const unsigned int half_stride = src_stride / 2;
1901
switch(src_format)
1902
{
1903
case GR_LFB_SRC_FMT_1555:
1904
for (j=0; j<src_height; j++)
1905
{
1906
for (i=0; i<src_width; i++)
1907
{
1908
const unsigned int col = frameBuffer[j*half_stride+i];
1909
buf[j*tex_width*4+i*4+0]=((col>>10)&0x1F)<<3;
1910
buf[j*tex_width*4+i*4+1]=((col>>5)&0x1F)<<3;
1911
buf[j*tex_width*4+i*4+2]=((col>>0)&0x1F)<<3;
1912
buf[j*tex_width*4+i*4+3]= (col>>15) ? 0xFF : 0;
1913
}
1914
}
1915
break;
1916
case GR_LFBWRITEMODE_555:
1917
for (j=0; j<src_height; j++)
1918
{
1919
for (i=0; i<src_width; i++)
1920
{
1921
const unsigned int col = frameBuffer[j*half_stride+i];
1922
buf[j*tex_width*4+i*4+0]=((col>>10)&0x1F)<<3;
1923
buf[j*tex_width*4+i*4+1]=((col>>5)&0x1F)<<3;
1924
buf[j*tex_width*4+i*4+2]=((col>>0)&0x1F)<<3;
1925
buf[j*tex_width*4+i*4+3]=0xFF;
1926
}
1927
}
1928
break;
1929
case GR_LFBWRITEMODE_565:
1930
for (j=0; j<src_height; j++)
1931
{
1932
for (i=0; i<src_width; i++)
1933
{
1934
const unsigned int col = frameBuffer[j*half_stride+i];
1935
buf[j*tex_width*4+i*4+0]=((col>>11)&0x1F)<<3;
1936
buf[j*tex_width*4+i*4+1]=((col>>5)&0x3F)<<2;
1937
buf[j*tex_width*4+i*4+2]=((col>>0)&0x1F)<<3;
1938
buf[j*tex_width*4+i*4+3]=0xFF;
1939
}
1940
}
1941
break;
1942
default:
1943
display_warning("grLfbWriteRegion : unknown format : %d", src_format);
1944
}
1945
1946
#ifdef VPDEBUG
1947
if (dumping) {
1948
ilTexImage(tex_width, tex_height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, buf);
1949
char name[128];
1950
static int id;
1951
sprintf(name, "dump/writecolor%d.png", id++);
1952
ilSaveImage(name);
1953
//printf("dumped gdLfbWriteRegion %s\n", name);
1954
}
1955
#endif
1956
1957
glBindTexture(GL_TEXTURE_2D, default_texture);
1958
glTexImage2D(GL_TEXTURE_2D, 0, 4, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1959
free(buf);
1960
1961
set_copy_shader();
1962
1963
glDisable(GL_DEPTH_TEST);
1964
glDisable(GL_BLEND);
1965
render_rectangle(texture_number,
1966
dst_x, dst_y,
1967
src_width, src_height,
1968
tex_width, tex_height, +1);
1969
1970
}
1971
else
1972
{
1973
float *buf = (float*)malloc(src_width*(src_height+(viewport_offset))*sizeof(float));
1974
1975
if (src_format != GR_LFBWRITEMODE_ZA16)
1976
display_warning("unknown depth buffer write format:%x", src_format);
1977
1978
if(dst_x || dst_y)
1979
display_warning("dst_x:%d, dst_y:%d\n",dst_x, dst_y);
1980
1981
for (j=0; j<src_height; j++)
1982
{
1983
for (i=0; i<src_width; i++)
1984
{
1985
buf[(j+(viewport_offset))*src_width+i] =
1986
(frameBuffer[(src_height-j-1)*(src_stride/2)+i]/(65536.0f*(2.0f/zscale)))+1-zscale/2.0f;
1987
}
1988
}
1989
1990
#ifdef VPDEBUG
1991
if (dumping) {
1992
unsigned char * buf2 = (unsigned char *)malloc(src_width*(src_height+(viewport_offset)));
1993
for (i=0; i<src_width*src_height ; i++)
1994
buf2[i] = buf[i]*255.0f;
1995
ilTexImage(src_width, src_height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, buf2);
1996
char name[128];
1997
static int id;
1998
sprintf(name, "dump/writedepth%d.png", id++);
1999
ilSaveImage(name);
2000
//printf("dumped gdLfbWriteRegion %s\n", name);
2001
free(buf2);
2002
}
2003
#endif
2004
2005
glEnable(GL_DEPTH_TEST);
2006
glDepthFunc(GL_ALWAYS);
2007
2008
glDrawBuffer(GL_BACK);
2009
glClear( GL_DEPTH_BUFFER_BIT );
2010
glDepthMask(1);
2011
glDrawPixels(src_width, src_height+(viewport_offset), GL_DEPTH_COMPONENT, GL_FLOAT, buf);
2012
2013
free(buf);
2014
}
2015
glDrawBuffer(current_buffer);
2016
glPopAttrib();
2017
return FXTRUE;
2018
}
2019
2020
/* wrapper-specific glide extensions */
2021
2022
FX_ENTRY char ** FX_CALL
2023
grQueryResolutionsExt(FxI32 * Size)
2024
{
2025
return 0;
2026
/*
2027
LOG("grQueryResolutionsExt\r\n");
2028
return g_FullScreenResolutions.getResolutionsList(Size);
2029
*/
2030
}
2031
2032
FX_ENTRY GrScreenResolution_t FX_CALL grWrapperFullScreenResolutionExt(FxU32* width, FxU32* height)
2033
{
2034
return 0;
2035
/*
2036
LOG("grWrapperFullScreenResolutionExt\r\n");
2037
g_FullScreenResolutions.getResolution(config.res, width, height);
2038
return config.res;
2039
*/
2040
}
2041
2042
FX_ENTRY FxBool FX_CALL grKeyPressedExt(FxU32 key)
2043
{
2044
return 0;
2045
/*
2046
#ifdef _WIN32
2047
return (GetAsyncKeyState(key) & 0x8000);
2048
#else
2049
if (key == 1) //LBUTTON
2050
{
2051
Uint8 mstate = SDL_GetMouseState(NULL, NULL);
2052
return (mstate & SDL_BUTTON_LMASK);
2053
}
2054
else
2055
{
2056
Uint8 *keystates = SDL_GetKeyState( NULL );
2057
if( keystates[ key ] )
2058
{
2059
return 1;
2060
}
2061
else
2062
{
2063
return 0;
2064
}
2065
}
2066
#endif
2067
*/
2068
}
2069
2070
FX_ENTRY void FX_CALL grConfigWrapperExt(FxI32 resolution, FxI32 vram, FxBool fbo, FxBool aniso)
2071
{
2072
LOG("grConfigWrapperExt\r\n");
2073
config.res = resolution;
2074
config.vram_size = vram;
2075
config.fbo = fbo;
2076
config.anisofilter = aniso;
2077
}
2078
2079
// unused by glide64
2080
2081
FX_ENTRY FxI32 FX_CALL
2082
grQueryResolutions( const GrResolution *resTemplate, GrResolution *output )
2083
{
2084
int res_inf = 0;
2085
int res_sup = 0xf;
2086
int i;
2087
int n=0;
2088
LOG("grQueryResolutions\r\n");
2089
display_warning("grQueryResolutions");
2090
if ((unsigned int)resTemplate->resolution != GR_QUERY_ANY)
2091
{
2092
res_inf = res_sup = resTemplate->resolution;
2093
}
2094
if ((unsigned int)resTemplate->refresh == GR_QUERY_ANY) display_warning("querying any refresh rate");
2095
if ((unsigned int)resTemplate->numAuxBuffers == GR_QUERY_ANY) display_warning("querying any numAuxBuffers");
2096
if ((unsigned int)resTemplate->numColorBuffers == GR_QUERY_ANY) display_warning("querying any numColorBuffers");
2097
2098
if (output == NULL) return res_sup - res_inf + 1;
2099
for (i=res_inf; i<=res_sup; i++)
2100
{
2101
output[n].resolution = i;
2102
output[n].refresh = resTemplate->refresh;
2103
output[n].numAuxBuffers = resTemplate->numAuxBuffers;
2104
output[n].numColorBuffers = resTemplate->numColorBuffers;
2105
n++;
2106
}
2107
return res_sup - res_inf + 1;
2108
}
2109
2110
FX_ENTRY FxBool FX_CALL
2111
grReset( FxU32 what )
2112
{
2113
display_warning("grReset");
2114
return 1;
2115
}
2116
2117
FX_ENTRY void FX_CALL
2118
grEnable( GrEnableMode_t mode )
2119
{
2120
LOG("grEnable(%d)\r\n", mode);
2121
if (mode == GR_TEXTURE_UMA_EXT)
2122
UMAmode = 1;
2123
}
2124
2125
FX_ENTRY void FX_CALL
2126
grDisable( GrEnableMode_t mode )
2127
{
2128
LOG("grDisable(%d)\r\n", mode);
2129
if (mode == GR_TEXTURE_UMA_EXT)
2130
UMAmode = 0;
2131
}
2132
2133
FX_ENTRY void FX_CALL
2134
grDisableAllEffects( void )
2135
{
2136
display_warning("grDisableAllEffects");
2137
}
2138
2139
FX_ENTRY void FX_CALL
2140
grErrorSetCallback( GrErrorCallbackFnc_t fnc )
2141
{
2142
display_warning("grErrorSetCallback");
2143
}
2144
2145
FX_ENTRY void FX_CALL
2146
grFinish(void)
2147
{
2148
display_warning("grFinish");
2149
}
2150
2151
FX_ENTRY void FX_CALL
2152
grFlush(void)
2153
{
2154
display_warning("grFlush");
2155
}
2156
2157
FX_ENTRY void FX_CALL
2158
grTexMultibase( GrChipID_t tmu,
2159
FxBool enable )
2160
{
2161
display_warning("grTexMultibase");
2162
}
2163
2164
FX_ENTRY void FX_CALL
2165
grTexMipMapMode( GrChipID_t tmu,
2166
GrMipMapMode_t mode,
2167
FxBool lodBlend )
2168
{
2169
display_warning("grTexMipMapMode");
2170
}
2171
2172
FX_ENTRY void FX_CALL
2173
grTexDownloadTablePartial( GrTexTable_t type,
2174
void *data,
2175
int start,
2176
int end )
2177
{
2178
display_warning("grTexDownloadTablePartial");
2179
}
2180
2181
FX_ENTRY void FX_CALL
2182
grTexDownloadTable( GrTexTable_t type,
2183
void *data )
2184
{
2185
display_warning("grTexDownloadTable");
2186
}
2187
2188
FX_ENTRY FxBool FX_CALL
2189
grTexDownloadMipMapLevelPartial( GrChipID_t tmu,
2190
FxU32 startAddress,
2191
GrLOD_t thisLod,
2192
GrLOD_t largeLod,
2193
GrAspectRatio_t aspectRatio,
2194
GrTextureFormat_t format,
2195
FxU32 evenOdd,
2196
void *data,
2197
int start,
2198
int end )
2199
{
2200
display_warning("grTexDownloadMipMapLevelPartial");
2201
return 1;
2202
}
2203
2204
FX_ENTRY void FX_CALL
2205
grTexDownloadMipMapLevel( GrChipID_t tmu,
2206
FxU32 startAddress,
2207
GrLOD_t thisLod,
2208
GrLOD_t largeLod,
2209
GrAspectRatio_t aspectRatio,
2210
GrTextureFormat_t format,
2211
FxU32 evenOdd,
2212
void *data )
2213
{
2214
display_warning("grTexDownloadMipMapLevel");
2215
}
2216
2217
FX_ENTRY void FX_CALL
2218
grTexNCCTable( GrNCCTable_t table )
2219
{
2220
display_warning("grTexNCCTable");
2221
}
2222
2223
FX_ENTRY void FX_CALL
2224
grViewport( FxI32 x, FxI32 y, FxI32 width, FxI32 height )
2225
{
2226
display_warning("grViewport");
2227
}
2228
2229
FX_ENTRY void FX_CALL
2230
grDepthRange( FxFloat n, FxFloat f )
2231
{
2232
display_warning("grDepthRange");
2233
}
2234
2235
FX_ENTRY void FX_CALL
2236
grSplash(float x, float y, float width, float height, FxU32 frame)
2237
{
2238
display_warning("grSplash");
2239
}
2240
2241
FX_ENTRY FxBool FX_CALL
2242
grSelectContext( GrContext_t context )
2243
{
2244
display_warning("grSelectContext");
2245
return 1;
2246
}
2247
2248
FX_ENTRY void FX_CALL
2249
grAADrawTriangle(
2250
const void *a, const void *b, const void *c,
2251
FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias
2252
)
2253
{
2254
display_warning("grAADrawTriangle");
2255
}
2256
2257
FX_ENTRY void FX_CALL
2258
grAlphaControlsITRGBLighting( FxBool enable )
2259
{
2260
display_warning("grAlphaControlsITRGBLighting");
2261
}
2262
2263
FX_ENTRY void FX_CALL
2264
grGlideSetVertexLayout( const void *layout )
2265
{
2266
display_warning("grGlideSetVertexLayout");
2267
}
2268
2269
FX_ENTRY void FX_CALL
2270
grGlideGetVertexLayout( void *layout )
2271
{
2272
display_warning("grGlideGetVertexLayout");
2273
}
2274
2275
FX_ENTRY void FX_CALL
2276
grGlideSetState( const void *state )
2277
{
2278
display_warning("grGlideSetState");
2279
}
2280
2281
FX_ENTRY void FX_CALL
2282
grGlideGetState( void *state )
2283
{
2284
display_warning("grGlideGetState");
2285
}
2286
2287
FX_ENTRY void FX_CALL
2288
grLfbWriteColorFormat(GrColorFormat_t colorFormat)
2289
{
2290
display_warning("grLfbWriteColorFormat");
2291
}
2292
2293
FX_ENTRY void FX_CALL
2294
grLfbWriteColorSwizzle(FxBool swizzleBytes, FxBool swapWords)
2295
{
2296
display_warning("grLfbWriteColorSwizzle");
2297
}
2298
2299
FX_ENTRY void FX_CALL
2300
grLfbConstantDepth( FxU32 depth )
2301
{
2302
display_warning("grLfbConstantDepth");
2303
}
2304
2305
FX_ENTRY void FX_CALL
2306
grLfbConstantAlpha( GrAlpha_t alpha )
2307
{
2308
display_warning("grLfbConstantAlpha");
2309
}
2310
2311
FX_ENTRY void FX_CALL
2312
grTexMultibaseAddress( GrChipID_t tmu,
2313
GrTexBaseRange_t range,
2314
FxU32 startAddress,
2315
FxU32 evenOdd,
2316
GrTexInfo *info )
2317
{
2318
display_warning("grTexMultibaseAddress");
2319
}
2320
2321
/*
2322
inline void MySleep(FxU32 ms)
2323
{
2324
#ifdef _WIN32
2325
Sleep(ms);
2326
#else
2327
SDL_Delay(ms);
2328
#endif
2329
}
2330
*/
2331
2332
#ifdef _WIN32
2333
static void CorrectGamma(LPVOID apGammaRamp)
2334
{
2335
HDC hdc = GetDC(NULL);
2336
if (hdc != NULL)
2337
{
2338
SetDeviceGammaRamp(hdc, apGammaRamp);
2339
ReleaseDC(NULL, hdc);
2340
}
2341
}
2342
#else
2343
static void CorrectGamma(const FxU16 aGammaRamp[3][256])
2344
{
2345
//TODO?
2346
//int res = SDL_SetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]);
2347
//LOG("SDL_SetGammaRamp returned %d\r\n", res);
2348
}
2349
#endif
2350
2351
FX_ENTRY void FX_CALL
2352
grLoadGammaTable( FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue)
2353
{
2354
LOG("grLoadGammaTable\r\n");
2355
if (!fullscreen)
2356
return;
2357
FxU16 aGammaRamp[3][256];
2358
for (int i = 0; i < 256; i++)
2359
{
2360
aGammaRamp[0][i] = (FxU16)((red[i] << 8) & 0xFFFF);
2361
aGammaRamp[1][i] = (FxU16)((green[i] << 8) & 0xFFFF);
2362
aGammaRamp[2][i] = (FxU16)((blue[i] << 8) & 0xFFFF);
2363
}
2364
CorrectGamma(aGammaRamp);
2365
//MySleep(1000); //workaround for Mupen64
2366
}
2367
2368
FX_ENTRY void FX_CALL
2369
grGetGammaTableExt(FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue)
2370
{
2371
return;
2372
//TODO?
2373
/*
2374
LOG("grGetGammaTableExt()\r\n");
2375
FxU16 aGammaRamp[3][256];
2376
#ifdef _WIN32
2377
HDC hdc = GetDC(NULL);
2378
if (hdc == NULL)
2379
return;
2380
if (GetDeviceGammaRamp(hdc, aGammaRamp) == TRUE)
2381
{
2382
ReleaseDC(NULL, hdc);
2383
#else
2384
if (SDL_GetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]) != -1)
2385
{
2386
#endif
2387
for (int i = 0; i < 256; i++)
2388
{
2389
red[i] = aGammaRamp[0][i] >> 8;
2390
green[i] = aGammaRamp[1][i] >> 8;
2391
blue[i] = aGammaRamp[2][i] >> 8;
2392
}
2393
}
2394
*/
2395
}
2396
2397
FX_ENTRY void FX_CALL
2398
guGammaCorrectionRGB( FxFloat gammaR, FxFloat gammaG, FxFloat gammaB )
2399
{
2400
LOG("guGammaCorrectionRGB()\r\n");
2401
if (!fullscreen)
2402
return;
2403
FxU16 aGammaRamp[3][256];
2404
for (int i = 0; i < 256; i++)
2405
{
2406
aGammaRamp[0][i] = (((FxU16)((pow(i/255.0F, 1.0F/gammaR)) * 255.0F + 0.5F)) << 8) & 0xFFFF;
2407
aGammaRamp[1][i] = (((FxU16)((pow(i/255.0F, 1.0F/gammaG)) * 255.0F + 0.5F)) << 8) & 0xFFFF;
2408
aGammaRamp[2][i] = (((FxU16)((pow(i/255.0F, 1.0F/gammaB)) * 255.0F + 0.5F)) << 8) & 0xFFFF;
2409
}
2410
CorrectGamma(aGammaRamp);
2411
}
2412
2413
FX_ENTRY void FX_CALL
2414
grDitherMode( GrDitherMode_t mode )
2415
{
2416
display_warning("grDitherMode");
2417
}
2418
2419
void grChromaRangeExt(GrColor_t color0, GrColor_t color1, FxU32 mode)
2420
{
2421
display_warning("grChromaRangeExt");
2422
}
2423
2424
void grChromaRangeModeExt(GrChromakeyMode_t mode)
2425
{
2426
display_warning("grChromaRangeModeExt");
2427
}
2428
2429
void grTexChromaRangeExt(GrChipID_t tmu, GrColor_t color0, GrColor_t color1, GrTexChromakeyMode_t mode)
2430
{
2431
display_warning("grTexChromaRangeExt");
2432
}
2433
2434
void grTexChromaModeExt(GrChipID_t tmu, GrChromakeyMode_t mode)
2435
{
2436
display_warning("grTexChromaRangeModeExt");
2437
}
2438
2439
// VP debug
2440
#ifdef VPDEBUG
2441
int dumping = 0;
2442
static int tl_i;
2443
static int tl[10240];
2444
2445
void dump_start()
2446
{
2447
static int init;
2448
if (!init) {
2449
init = 1;
2450
ilInit();
2451
ilEnable(IL_FILE_OVERWRITE);
2452
}
2453
dumping = 1;
2454
tl_i = 0;
2455
}
2456
2457
void dump_stop()
2458
{
2459
if (!dumping) return;
2460
2461
int i, j;
2462
for (i=0; i<nb_fb; i++) {
2463
dump_tex(fbs[i].texid);
2464
}
2465
dump_tex(default_texture);
2466
dump_tex(depth_texture);
2467
2468
dumping = 0;
2469
2470
glReadBuffer(GL_FRONT);
2471
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer);
2472
ilTexImage(width, height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, frameBuffer);
2473
ilSaveImage("dump/framecolor.png");
2474
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
2475
// FILE * fp = fopen("glide_depth1.bin", "rb");
2476
// fread(depthBuffer, 2, width*height, fp);
2477
// fclose(fp);
2478
for (j=0; j<height; j++) {
2479
for (i=0; i<width; i++) {
2480
//uint16_t d = ( (uint16_t *)depthBuffer )[i+(height-1-j)*width]/2 + 0x8000;
2481
uint16_t d = ( (uint16_t *)depthBuffer )[i+j*width];
2482
uint32_t c = ( (uint32_t *)frameBuffer )[i+j*width];
2483
( (unsigned char *)frameBuffer )[(i+j*width)*3] = d&0xff;
2484
( (unsigned char *)frameBuffer )[(i+j*width)*3+1] = d>>8;
2485
( (unsigned char *)frameBuffer )[(i+j*width)*3+2] = c&0xff;
2486
}
2487
}
2488
ilTexImage(width, height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, frameBuffer);
2489
ilSaveImage("dump/framedepth.png");
2490
2491
for (i=0; i<tl_i; i++) {
2492
glBindTexture(GL_TEXTURE_2D, tl[i]);
2493
GLint w, h, fmt;
2494
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
2495
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
2496
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
2497
fprintf(stderr, "Texture %d %dx%d fmt %x\n", tl[i], (int)w, (int)h, (int) fmt);
2498
2499
uint32_t * pixels = (uint32_t *) malloc(w*h*4);
2500
// 0x1902 is another constant meaning GL_DEPTH_COMPONENT
2501
// (but isn't defined in gl's headers !!)
2502
if (fmt != GL_DEPTH_COMPONENT && fmt != 0x1902) {
2503
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2504
ilTexImage(w, h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pixels);
2505
} else {
2506
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixels);
2507
int i;
2508
for (i=0; i<w*h; i++)
2509
((unsigned char *)frameBuffer)[i] = ((unsigned short *)pixels)[i]/256;
2510
ilTexImage(w, h, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, frameBuffer);
2511
}
2512
char name[128];
2513
// sprintf(name, "mkdir -p dump ; rm -f dump/tex%04d.png", i);
2514
// system(name);
2515
sprintf(name, "dump/tex%04d.png", i);
2516
fprintf(stderr, "Writing '%s'\n", name);
2517
ilSaveImage(name);
2518
2519
// SDL_FreeSurface(surf);
2520
free(pixels);
2521
}
2522
glBindTexture(GL_TEXTURE_2D, default_texture);
2523
}
2524
2525
void dump_tex(int id)
2526
{
2527
if (!dumping) return;
2528
2529
int n;
2530
// yes, it's inefficient
2531
for (n=0; n<tl_i; n++)
2532
if (tl[n] == id)
2533
return;
2534
2535
tl[tl_i++] = id;
2536
2537
int i = tl_i-1;
2538
}
2539
2540
#endif
2541
2542