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