2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002 Dave2001
4 * Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski
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
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.
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
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); }
48 #include "../Glide64/ticks.h" //*SEB*
50 extern void (*renderCallback)(int);
52 wrapper_config config = {0, 0, 0, 0};
53 int screen_width, screen_height;
56 static inline void opt_glCopyTexImage2D( GLenum target,
58 GLenum internalFormat,
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);
76 if (y+height >= screen_height+viewport_offset) {
77 height = screen_height+viewport_offset - y;
78 //printf("resizing h --> %d\n", height);
80 glCopyTexSubImage2D(target, level, 0, 0, x, y, width, height);
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);
89 #define glCopyTexImage2D opt_glCopyTexImage2D
94 PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
95 PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
96 PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
97 PFNGLFOGCOORDFPROC glFogCoordfEXT;
99 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
101 PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
102 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
103 PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
104 PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL;
105 PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL;
106 PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL;
107 PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL;
108 PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
109 PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
110 PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
112 PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
113 PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
114 PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
115 PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
116 PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
117 PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
118 PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
119 PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
120 PFNGLUNIFORM1IARBPROC glUniform1iARB;
121 PFNGLUNIFORM4IARBPROC glUniform4iARB;
122 PFNGLUNIFORM4FARBPROC glUniform4fARB;
123 PFNGLUNIFORM1FARBPROC glUniform1fARB;
124 PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
125 PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
126 PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
127 PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f;
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
135 PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DARB;
142 unsigned int address;
154 int nbAuxBuffers, current_buffer;
155 int width, widtho, heighto, height;
156 int saved_width, saved_height;
157 int blend_func_separate_support;
159 int fog_coord_support;
160 int render_to_texture = 0;
165 // to allocate a new static texture name, take the value (free_texture++)
167 int default_texture; // the infamous "32*1024*1024" is now configurable
169 int depth_texture, color_texture;
170 int glsl_support = 1;
171 int viewport_width, viewport_height, viewport_offset = 0, nvidia_viewport_hack = 0;
176 int UMAmode = 0; //support for VSA-100 UMA mode;
179 static HDC hDC = NULL;
180 static HGLRC hGLRC = NULL;
181 static HWND hToolBar = NULL;
182 static HWND hwnd_win = NULL;
183 static unsigned long windowedExStyle, windowedStyle;
185 static unsigned long fullscreen;
187 static RECT windowedRect;
188 static HMENU windowedMenu;
191 static int savedWidtho, savedHeighto;
192 static int savedWidth, savedHeight;
193 unsigned int pBufferAddress;
194 static int pBufferFmt;
195 static int pBufferWidth, pBufferHeight;
197 static int nb_fb = 0;
198 static unsigned int curBufferAddr = 0;
200 struct TMU_USAGE { int min, max; } tmu_usage[2] = { {0xfffffff, 0}, {0xfffffff, 0} };
206 #define NB_TEXBUFS 128 // MUST be a power of two
207 static texbuf_t texbufs[NB_TEXBUFS];
210 unsigned short frameBuffer[2048*2048];
211 unsigned short depthBuffer[2048*2048];
215 void display_warning(const char *text, ...)
217 static int first_message = 100;
225 vsprintf(buf, text, ap);
237 FORMAT_MESSAGE_ALLOCATE_BUFFER |
238 FORMAT_MESSAGE_FROM_SYSTEM |
239 FORMAT_MESSAGE_IGNORE_INSERTS,
242 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
250 // Process any inserts in lpMsgBuf.
252 // Display the string.
253 MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
256 LocalFree( lpMsgBuf );
262 bool log_open = false;
263 std::ofstream log_file;
269 log_file.open ("wrapper_log.txt", std::ios_base::out|std::ios_base::app);
283 void LOG(const char *text, ...)
286 if (!dumping) return;
292 vsprintf(out_buf, text, ap);
308 LogManager logManager;
316 FX_ENTRY void FX_CALL
317 grSstOrigin(GrOriginLocation_t origin)
319 LOG("grSstOrigin(%d)\r\n", origin);
320 if (origin != GR_ORIGIN_UPPER_LEFT)
321 display_warning("grSstOrigin : %x", origin);
324 FX_ENTRY void FX_CALL
325 grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy )
327 LOG("grClipWindow(%d,%d,%d,%d)\r\n", minx, miny, maxx, maxy);
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);
341 if (th > screen_height)
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);
355 glScissor(minx, (viewport_offset)+height-maxy, maxx - minx, maxy - miny);
357 glEnable(GL_SCISSOR_TEST);
360 FX_ENTRY void FX_CALL
361 grColorMask( FxBool rgb, FxBool a )
363 LOG("grColorMask(%d, %d)\r\n", rgb, a);
364 glColorMask(rgb, rgb, rgb, a);
367 FX_ENTRY void FX_CALL
370 LOG("grGlideInit()\r\n");
373 FX_ENTRY void FX_CALL
374 grSstSelect( int which_sst )
376 LOG("grSstSelect(%d)\r\n", which_sst);
379 int isExtensionSupported(const char *extension)
382 const GLubyte *extensions = NULL;
383 const GLubyte *start;
384 GLubyte *where, *terminator;
386 where = (GLubyte *)strchr(extension, ' ');
387 if (where || *extension == '\0')
390 extensions = glGetString(GL_EXTENSIONS);
395 where = (GLubyte *) strstr((const char *) start, extension);
399 terminator = where + strlen(extension);
400 if (where == start || *(where - 1) == ' ')
401 if (*terminator == ' ' || *terminator == '\0')
411 int isWglExtensionSupported(const char *extension)
413 const GLubyte *extensions = NULL;
414 const GLubyte *start;
415 GLubyte *where, *terminator;
417 where = (GLubyte *)strchr(extension, ' ');
418 if (where || *extension == '\0')
421 extensions = (GLubyte*)wglGetExtensionsStringARB(wglGetCurrentDC());
426 where = (GLubyte *) strstr((const char *) start, extension);
430 terminator = where + strlen(extension);
431 if (where == start || *(where - 1) == ' ')
432 if (*terminator == ' ' || *terminator == '\0')
442 #define GrPixelFormat_t int
444 FX_ENTRY GrContext_t FX_CALL
447 GrScreenResolution_t screen_resolution,
448 GrScreenRefresh_t refresh_rate,
449 GrColorFormat_t color_format,
450 GrOriginLocation_t origin_location,
451 GrPixelFormat_t pixelformat,
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);
462 # ifndef ATTACH_PARENT_PROCESS
463 # define ATTACH_PARENT_PROCESS ((FxU32)-1)
467 FX_ENTRY GrContext_t FX_CALL
470 GrScreenResolution_t screen_resolution,
471 GrScreenRefresh_t refresh_rate,
472 GrColorFormat_t color_format,
473 GrOriginLocation_t origin_location,
477 static int show_warning = 1;
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++;
487 LOG("grSstWinOpen(%08lx, %d, %d, %d, %d, %d %d)\r\n", hWnd, screen_resolution&~0x80000000, refresh_rate, color_format, origin_location, nColBuffers, nAuxBuffers);
490 if ((HWND)hWnd == NULL) hWnd = GetActiveWindow();
491 hwnd_win = (HWND)hWnd;
495 m64p_handle video_general_section;
496 printf("&ConfigOpenSection is %p\n", &ConfigOpenSection);
497 if (ConfigOpenSection("Video-General", &video_general_section) != M64ERR_SUCCESS)
499 printf("Could not open video settings");
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;
510 // ZIGGY not sure, but it might be better to let the system choose
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);
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)
524 printf("(EE) Error setting videomode %dx%d\n", width, height);
530 sprintf(caption, "Glide64mk2 debug");
532 sprintf(caption, "Glide64mk2");
534 CoreVideo_SetCaption(caption);
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");
542 if (isExtensionSupported("GL_ARB_texture_env_combine") == 0 &&
543 isExtensionSupported("GL_EXT_texture_env_combine") == 0 &&
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");
553 glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
554 glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB");
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");
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);
569 blend_func_separate_support = 1;
570 packed_pixels_support = 0;
572 if (isExtensionSupported("GL_EXT_blend_func_separate") == 0)
573 blend_func_separate_support = 0;
575 blend_func_separate_support = 1;
577 if (isExtensionSupported("GL_EXT_packed_pixels") == 0)
578 packed_pixels_support = 0;
580 printf("packed pixels extension used\n");
581 packed_pixels_support = 1;
585 if (isExtensionSupported("GL_ARB_texture_non_power_of_two") == 0)
588 printf("NPOT extension used\n");
593 glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)wglGetProcAddress("glBlendFuncSeparateEXT");
596 if (isExtensionSupported("GL_EXT_fog_coord") == 0)
597 fog_coord_support = 0;
599 fog_coord_support = 1;
602 glFogCoordfEXT = (PFNGLFOGCOORDFPROC)wglGetProcAddress("glFogCoordfEXT");
606 wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
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");
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);
623 use_fbo = config.fbo;
626 LOGINFO("use_fbo %d\n", use_fbo);
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"))
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");
651 glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)wglGetProcAddress("glSecondaryColor3f");
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");
661 glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)wglGetProcAddress("glCompressedTexImage2DARB");
664 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
665 glPixelStorei(GL_PACK_ALIGNMENT, 1);
669 glViewport(0, viewport_offset, width, height);
670 viewport_width = width;
671 viewport_height = height;
672 nvidia_viewport_hack = 1;
674 glViewport(0, viewport_offset, width, height);
675 viewport_width = width;
676 viewport_height = height;
679 // void do_benchmarks();
682 // VP try to resolve z precision issues
683 // glMatrixMode(GL_MODELVIEW);
685 // glTranslatef(0, 0, 1-zscale);
686 // glScalef(1, 1, zscale);
691 pBufferWidth = pBufferHeight = -1;
693 current_buffer = GL_BACK;
695 texture_unit = GL_TEXTURE0;
699 for (i=0; i<NB_TEXBUFS; i++)
700 texbufs[i].start = texbufs[i].end = 0xffffffff;
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);
709 while (w<width) w*=2;
710 while (h<height) h*=2;
712 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
713 glBindTexture(GL_TEXTURE_2D, 0);
717 void FindBestDepthBias();
725 // Aniso filter check
726 if (config.anisofilter > 0 )
727 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
729 // ATI hack - certain texture formats are slow on ATI?
730 // Hmm, perhaps the internal format need to be specified explicitly...
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);
746 FX_ENTRY void FX_CALL
747 grGlideShutdown( void )
749 LOG("grGlideShutdown\r\n");
752 FX_ENTRY FxBool FX_CALL
753 grSstWinClose( GrContext_t context )
755 int i, clear_texbuff = use_fbo;
756 LOG("grSstWinClose(%d)\r\n", context);
758 for (i=0; i<2; i++) {
759 tmu_usage[i].min = 0xfffffff;
760 tmu_usage[i].max = 0;
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.
770 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
779 for (i=0; i<nb_fb; i++)
781 glDeleteTextures( 1, &(fbs[i].texid) );
782 glDeleteFramebuffers( 1, &(fbs[i].fbid) );
783 glDeleteRenderbuffers( 1, &(fbs[i].zbid) );
791 // ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
792 remove_tex(0, 0xfffffff);
799 wglMakeCurrent(hDC,NULL);
800 wglDeleteContext(hGLRC);
805 ChangeDisplaySettings(NULL, 0);
806 SetWindowPos(hwnd_win, NULL,
807 windowedRect.left, windowedRect.top,
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);
817 //SDL_QuitSubSystem(SDL_INIT_VIDEO);
823 FX_ENTRY void FX_CALL grTextureBufferExt( GrChipID_t tmu,
827 GrAspectRatio_t aspect,
828 GrTextureFormat_t fmt,
832 static int fbs_init = 0;
834 LOG("grTextureBufferExt(%d, %d, %d, %d %d, %d, %d)\r\n", tmu, startAddress, lodmin, lodmax, aspect, fmt, evenOdd);
835 if (lodmin != lodmax) display_warning("grTextureBufferExt : loading more than one LOD");
838 if (!render_to_texture) { //initialization
842 render_to_texture = 2;
846 pBufferHeight = 1 << lodmin;
847 pBufferWidth = pBufferHeight >> -aspect;
851 pBufferWidth = 1 << lodmin;
852 pBufferHeight = pBufferWidth >> aspect;
855 if (curBufferAddr && startAddress+1 != curBufferAddr)
858 //printf("saving %dx%d\n", pBufferWidth, pBufferHeight);
860 if (nbAuxBuffers > 0) {
861 //glDrawBuffer(GL_AUX0);
862 //current_buffer = GL_AUX0;
865 if (pBufferWidth < screen_width)
869 if (pBufferHeight < screen_height)
873 //glReadBuffer(GL_BACK);
874 glActiveTexture(texture_unit);
875 glBindTexture(GL_TEXTURE_2D, color_texture);
876 // save incrementally the framebuffer
878 if (tw > save_w && th > save_h) {
879 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, save_h,
880 0, viewport_offset+save_h, tw, th-save_h);
881 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, save_w, 0,
882 save_w, viewport_offset, tw-save_w, save_h);
885 } else if (tw > save_w) {
886 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, save_w, 0,
887 save_w, viewport_offset, tw-save_w, save_h);
889 } else if (th > save_h) {
890 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, save_h,
891 0, viewport_offset+save_h, save_w, th-save_h);
895 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
896 0, viewport_offset, tw, th);
900 glBindTexture(GL_TEXTURE_2D, default_texture);
904 if (startAddress+1 != curBufferAddr ||
905 (curBufferAddr == 0L && nbAuxBuffers == 0))
908 curBufferAddr = pBufferAddress = startAddress+1;
911 int rtmu = startAddress < grTexMinAddress(GR_TMU1)? 0 : 1;
912 int size = pBufferWidth*pBufferHeight*2; //grTexFormatSize(fmt);
913 if ((unsigned int) tmu_usage[rtmu].min > pBufferAddress)
914 tmu_usage[rtmu].min = pBufferAddress;
915 if ((unsigned int) tmu_usage[rtmu].max < pBufferAddress+size)
916 tmu_usage[rtmu].max = pBufferAddress+size;
917 //printf("tmu %d usage now %gMb - %gMb\n",
918 // rtmu, tmu_usage[rtmu].min/1024.0f, tmu_usage[rtmu].max/1024.0f);
921 width = pBufferWidth;
922 height = pBufferHeight;
927 // this could be improved, but might be enough as long as the set of
928 // texture buffer addresses stay small
929 for (i=(texbuf_i-1)&(NB_TEXBUFS-1) ; i!=texbuf_i; i=(i-1)&(NB_TEXBUFS-1))
930 if (texbufs[i].start == pBufferAddress)
932 texbufs[i].start = pBufferAddress;
933 texbufs[i].end = pBufferAddress + size;
934 texbufs[i].fmt = fmt;
936 texbuf_i = (texbuf_i+1)&(NB_TEXBUFS-1);
937 //printf("texbuf %x fmt %x\n", pBufferAddress, fmt);
939 // ZIGGY it speeds things up to not delete the buffers
940 // a better thing would be to delete them *sometimes*
941 // remove_tex(pBufferAddress+1, pBufferAddress + size);
942 add_tex(pBufferAddress);
944 //printf("viewport %dx%d\n", width, height);
945 if (height > screen_height) {
946 glViewport( 0, viewport_offset + screen_height - height, width, height);
948 glViewport( 0, viewport_offset, width, height);
950 glScissor(0, viewport_offset, width, height);
954 if (!render_to_texture) //initialization
958 for(i=0; i<100; i++) fbs[i].address = 0;
962 return; //no need to allocate FBO if render buffer is not texture buffer
965 render_to_texture = 2;
969 pBufferHeight = 1 << lodmin;
970 pBufferWidth = pBufferHeight >> -aspect;
974 pBufferWidth = 1 << lodmin;
975 pBufferHeight = pBufferWidth >> aspect;
977 pBufferAddress = startAddress+1;
979 width = pBufferWidth;
980 height = pBufferHeight;
985 for (i=0; i<nb_fb; i++)
987 if (fbs[i].address == pBufferAddress)
989 // if (fbs[i].width == width && fbs[i].height == height) //select already allocated FBO
990 if (fbs[i].width >= width && fbs[i].height >= height) //select already allocated FBO, or large enough
992 //unsigned int tticks = ticksGetTicks();
993 glBindFramebuffer( GL_FRAMEBUFFER, 0 );
994 glBindFramebuffer( GL_FRAMEBUFFER, fbs[i].fbid );
995 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbs[i].texid, 0 );
996 glBindRenderbuffer( GL_RENDERBUFFER, fbs[i].zbid );
997 glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbs[i].zbid );
998 glViewport( 0, 0, width, height);
999 glScissor( 0, 0, width, height);
1000 fbs[i].fb_width=width;
1001 fbs[i].fb_height=height;
1002 if (fbs[i].buff_clear)
1005 glClear( GL_DEPTH_BUFFER_BIT ); //clear z-buffer only. we may need content, stored in the frame buffer
1006 fbs[i].buff_clear = 0;
1008 CHECK_FRAMEBUFFER_STATUS();
1009 curBufferAddr = pBufferAddress;
1010 //printf("select existing fbo (%u ms)\n", ticksGetTicks()-tticks);
1013 else //create new FBO at the same address, delete old one
1015 //unsigned int tticks = ticksGetTicks();
1016 glDeleteFramebuffers( 1, &(fbs[i].fbid) );
1017 glDeleteRenderbuffers( 1, &(fbs[i].zbid) );
1019 memmove(&(fbs[i]), &(fbs[i+1]), sizeof(fb)*(nb_fb-i));
1021 //printf("delete existing fbo (%u ms)\n", ticksGetTicks()-tticks);
1026 //unsigned int tticks = ticksGetTicks();
1027 remove_tex(pBufferAddress, pBufferAddress + width*height*2/*grTexFormatSize(fmt)*/);
1028 //printf("delete texture (%u ms)\n", ticksGetTicks()-tticks);
1030 glGenFramebuffers( 1, &(fbs[nb_fb].fbid) );
1031 glGenRenderbuffers( 1, &(fbs[nb_fb].zbid) );
1032 glBindRenderbuffer( GL_RENDERBUFFER, fbs[nb_fb].zbid );
1033 glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
1034 fbs[nb_fb].address = pBufferAddress;
1035 fbs[nb_fb].width = width;
1036 fbs[nb_fb].height = height;
1037 fbs[nb_fb].fb_width = width;
1038 fbs[nb_fb].fb_height = height;
1039 fbs[nb_fb].texid = pBufferAddress;
1040 fbs[nb_fb].buff_clear = 0;
1041 add_tex(fbs[nb_fb].texid);
1042 glBindTexture(GL_TEXTURE_2D, fbs[nb_fb].texid);
1043 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
1044 GL_RGB, GL_UNSIGNED_BYTE, NULL);
1045 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1046 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
1048 glBindFramebuffer( GL_FRAMEBUFFER, fbs[nb_fb].fbid);
1049 glFramebufferTexture2D(GL_FRAMEBUFFER,
1050 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbs[nb_fb].texid, 0);
1051 glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbs[nb_fb].zbid );
1052 glViewport(0,0,width,height);
1053 glScissor(0,0,width,height);
1054 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
1056 glClear( GL_DEPTH_BUFFER_BIT );
1057 CHECK_FRAMEBUFFER_STATUS();
1058 curBufferAddr = pBufferAddress;
1060 //printf("create new fbo=fb[%i] (%u ms)\n", nb_fb-1, ticksGetTicks()-tticks);
1064 int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info )
1068 for (found=i=0; i<2; i++)
1069 if ((FxU32) tmu_usage[i].min <= startAddress && (FxU32) tmu_usage[i].max > startAddress) {
1070 //printf("tmu %d == framebuffer %x\n", tmu, startAddress);
1078 unsigned int end = fbs[i].address + fbs[i].fb_width*fbs[i].fb_height*2;
1079 if (startAddress >= fbs[i].address && startAddress < end)
1088 if (!use_fbo && found) {
1089 int tw, th, rh, cw, ch;
1090 if (info->aspectRatioLog2 < 0)
1092 th = 1 << info->largeLodLog2;
1093 tw = th >> -info->aspectRatioLog2;
1097 tw = 1 << info->largeLodLog2;
1098 th = tw >> info->aspectRatioLog2;
1101 if (info->aspectRatioLog2 < 0)
1104 cw = ch >> -info->aspectRatioLog2;
1109 ch = cw >> info->aspectRatioLog2;
1112 if (use_fbo || th < screen_height)
1117 //printf("th %d rh %d ch %d\n", th, rh, ch);
1119 invtex[tmu] = 1.0f - (th - rh) / (float)th;
1123 if (info->format == GR_TEXFMT_ALPHA_INTENSITY_88 ) {
1129 if(blackandwhite1 != found)
1131 blackandwhite1 = found;
1132 need_to_compile = 1;
1137 if(blackandwhite0 != found)
1139 blackandwhite0 = found;
1140 need_to_compile = 1;
1150 FX_ENTRY void FX_CALL
1151 grTextureAuxBufferExt( GrChipID_t tmu,
1155 GrAspectRatio_t aspectRatio,
1156 GrTextureFormat_t format,
1157 FxU32 odd_even_mask )
1159 LOG("grTextureAuxBufferExt(%d, %d, %d, %d %d, %d, %d)\r\n", tmu, startAddress, thisLOD, largeLOD, aspectRatio, format, odd_even_mask);
1160 //display_warning("grTextureAuxBufferExt");
1163 FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );
1165 FX_ENTRY GrProc FX_CALL
1166 grGetProcAddress( char *procName )
1168 LOG("grGetProcAddress(%s)\r\n", procName);
1169 if(!strcmp(procName, "grSstWinOpenExt"))
1170 return (GrProc)grSstWinOpenExt;
1171 if(!strcmp(procName, "grTextureBufferExt"))
1172 return (GrProc)grTextureBufferExt;
1173 if(!strcmp(procName, "grChromaRangeExt"))
1174 return (GrProc)grChromaRangeExt;
1175 if(!strcmp(procName, "grChromaRangeModeExt"))
1176 return (GrProc)grChromaRangeModeExt;
1177 if(!strcmp(procName, "grTexChromaRangeExt"))
1178 return (GrProc)grTexChromaRangeExt;
1179 if(!strcmp(procName, "grTexChromaModeExt"))
1180 return (GrProc)grTexChromaModeExt;
1181 // ZIGGY framebuffer copy extension
1182 if(!strcmp(procName, "grFramebufferCopyExt"))
1183 return (GrProc)grFramebufferCopyExt;
1184 if(!strcmp(procName, "grColorCombineExt"))
1185 return (GrProc)grColorCombineExt;
1186 if(!strcmp(procName, "grAlphaCombineExt"))
1187 return (GrProc)grAlphaCombineExt;
1188 if(!strcmp(procName, "grTexColorCombineExt"))
1189 return (GrProc)grTexColorCombineExt;
1190 if(!strcmp(procName, "grTexAlphaCombineExt"))
1191 return (GrProc)grTexAlphaCombineExt;
1192 if(!strcmp(procName, "grConstantColorValueExt"))
1193 return (GrProc)grConstantColorValueExt;
1194 if(!strcmp(procName, "grTextureAuxBufferExt"))
1195 return (GrProc)grTextureAuxBufferExt;
1196 if(!strcmp(procName, "grAuxBufferExt"))
1197 return (GrProc)grAuxBufferExt;
1198 if(!strcmp(procName, "grWrapperFullScreenResolutionExt"))
1199 return (GrProc)grWrapperFullScreenResolutionExt;
1200 if(!strcmp(procName, "grConfigWrapperExt"))
1201 return (GrProc)grConfigWrapperExt;
1202 if(!strcmp(procName, "grKeyPressedExt"))
1203 return (GrProc)grKeyPressedExt;
1204 if(!strcmp(procName, "grQueryResolutionsExt"))
1205 return (GrProc)grQueryResolutionsExt;
1206 if(!strcmp(procName, "grGetGammaTableExt"))
1207 return (GrProc)grGetGammaTableExt;
1208 display_warning("grGetProcAddress : %s", procName);
1212 FX_ENTRY FxU32 FX_CALL
1213 grGet( FxU32 pname, FxU32 plength, FxI32 *params )
1215 LOG("grGet(%d,%d)\r\n", pname, plength);
1218 case GR_MAX_TEXTURE_SIZE:
1219 if (plength < 4 || params == NULL) return 0;
1224 if (plength < 4 || params == NULL) return 0;
1225 if (!nbTextureUnits)
1227 grSstWinOpen((unsigned long)NULL, GR_RESOLUTION_640x480 | 0x80000000, 0, GR_COLORFORMAT_ARGB,
1228 GR_ORIGIN_UPPER_LEFT, 2, 1);
1234 if (nbTextureUnits > 2)
1243 case GR_REVISION_FB:
1244 case GR_REVISION_TMU:
1245 if (plength < 4 || params == NULL) return 0;
1250 if (plength < 4 || params == NULL) return 0;
1251 params[0] = 16*1024*1024;
1255 if (plength < 4 || params == NULL) return 0;
1256 params[0] = 16*1024*1024;
1260 if (plength < 4 || params == NULL) return 0;
1261 params[0] = 16*1024*1024*nbTextureUnits;
1265 if (plength < 16 || params == NULL) return 0;
1273 if (plength < 4 || params == NULL) return 0;
1278 if (plength < 4 || params == NULL) return 0;
1282 case GR_GAMMA_TABLE_ENTRIES:
1283 if (plength < 4 || params == NULL) return 0;
1287 case GR_FOG_TABLE_ENTRIES:
1288 if (plength < 4 || params == NULL) return 0;
1292 case GR_WDEPTH_MIN_MAX:
1293 if (plength < 8 || params == NULL) return 0;
1298 case GR_ZDEPTH_MIN_MAX:
1299 if (plength < 8 || params == NULL) return 0;
1304 case GR_LFB_PIXEL_PIPE:
1305 if (plength < 4 || params == NULL) return 0;
1306 params[0] = FXFALSE;
1309 case GR_MAX_TEXTURE_ASPECT_RATIO:
1310 if (plength < 4 || params == NULL) return 0;
1314 case GR_NON_POWER_OF_TWO_TEXTURES:
1315 if (plength < 4 || params == NULL) return 0;
1316 params[0] = FXFALSE;
1319 case GR_TEXTURE_ALIGN:
1320 if (plength < 4 || params == NULL) return 0;
1325 display_warning("unknown pname in grGet : %x", pname);
1330 FX_ENTRY const char * FX_CALL
1331 grGetString( FxU32 pname )
1333 LOG("grGetString(%d)\r\n", pname);
1338 static char extension[] = "CHROMARANGE TEXCHROMA TEXMIRROR PALETTE6666 FOGCOORD EVOODOO TEXTUREBUFFER TEXUMA TEXFMT COMBINE GETGAMMA";
1344 static char hardware[] = "Voodoo5 (tm)";
1350 static char vendor[] = "3Dfx Interactive";
1356 static char renderer[] = "Glide";
1362 static char version[] = "3.0";
1367 display_warning("unknown grGetString selector : %x", pname);
1372 static void render_rectangle(int texture_number,
1373 int dst_x, int dst_y,
1374 int src_width, int src_height,
1375 int tex_width, int tex_height, int invert)
1377 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);
1378 int vertexOffset_location;
1379 int textureSizes_location;
1380 static float data[] = {
1382 invert*-((int)dst_y), //Y 0
1387 invert*-((int)dst_y + (int)src_height), //Y 1
1389 (float)src_height / (float)tex_height, //V 1
1391 ((int)dst_x + (int)src_width),
1392 invert*-((int)dst_y + (int)src_height),
1393 (float)src_width / (float)tex_width,
1394 (float)src_height / (float)tex_height,
1397 invert*-((int)dst_y),
1403 glDisableVertexAttribArray(COLOUR_ATTR);
1404 glDisableVertexAttribArray(TEXCOORD_1_ATTR);
1405 glDisableVertexAttribArray(FOG_ATTR);
1407 glVertexAttribPointer(POSITION_ATTR,2,GL_FLOAT,false,2,data); //Position
1408 glVertexAttribPointer(TEXCOORD_0_ATTR,2,GL_FLOAT,false,2,&data[2]); //Tex
1410 glEnableVertexAttribArray(COLOUR_ATTR);
1411 glEnableVertexAttribArray(TEXCOORD_1_ATTR);
1412 glEnableVertexAttribArray(FOG_ATTR);
1415 disable_textureSizes();
1417 glDrawArrays(GL_TRIANGLE_STRIP,0,4);
1422 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1425 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1427 glMultiTexCoord2fARB(texture_number, 0.0f, 0.0f);
1428 glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1429 invert*-((int)dst_y - heighto) / (float)(height/2));
1430 glMultiTexCoord2fARB(texture_number, 0.0f, (float)src_height / (float)tex_height);
1431 glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1432 invert*-((int)dst_y + (int)src_height - heighto) / (float)(height/2));
1433 glMultiTexCoord2fARB(texture_number, (float)src_width / (float)tex_width, (float)src_height / (float)tex_height);
1434 glVertex2f(((int)dst_x + (int)src_width - 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, 0.0f);
1437 glVertex2f(((int)dst_x + (int)src_width - widtho) / (float)(width/2),
1438 invert*-((int)dst_y - heighto) / (float)(height/2));
1439 glMultiTexCoord2fARB(texture_number, 0.0f, 0.0f);
1440 glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1441 invert*-((int)dst_y - heighto) / (float)(height/2));
1447 glEnable(GL_DEPTH_TEST);
1451 void reloadTexture()
1453 if (use_fbo || !render_to_texture || buffer_cleared)
1456 LOG("reload texture %dx%d\n", width, height);
1457 //printf("reload texture %dx%d\n", width, height);
1461 //glPushAttrib(GL_ALL_ATTRIB_BITS);
1462 glActiveTexture(texture_unit);
1463 glBindTexture(GL_TEXTURE_2D, pBufferAddress);
1464 //glDisable(GL_ALPHA_TEST);
1465 //glDrawBuffer(current_buffer);
1466 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1468 glDisable(GL_DEPTH_TEST);
1469 glDisable(GL_CULL_FACE);
1471 if (height > screen_height) h = screen_height - height;
1472 render_rectangle(texture_unit,
1476 glBindTexture(GL_TEXTURE_2D, default_texture);
1480 void updateTexture()
1482 if (!use_fbo && render_to_texture == 2) {
1483 LOG("update texture %x\n", pBufferAddress);
1484 //printf("update texture %x\n", pBufferAddress);
1486 // nothing changed, don't update the texture
1487 if (!buffer_cleared) {
1488 LOG("update cancelled\n", pBufferAddress);
1492 //glPushAttrib(GL_ALL_ATTRIB_BITS);
1494 // save result of render to texture into actual texture
1495 //glReadBuffer(current_buffer);
1496 glActiveTexture(texture_unit);
1498 // deleting the texture before resampling it increases speed on certain old
1499 // nvidia cards (geforce 2 for example), unfortunatly it slows down a lot
1501 //glDeleteTextures( 1, &pBufferAddress );
1502 glBindTexture(GL_TEXTURE_2D, pBufferAddress);
1503 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
1504 0, viewport_offset, width, height, 0);
1506 glBindTexture(GL_TEXTURE_2D, default_texture);
1511 FX_ENTRY void FX_CALL grFramebufferCopyExt(int x, int y, int w, int h,
1512 int from, int to, int mode)
1514 if (mode == GR_FBCOPY_MODE_DEPTH) {
1518 tw = width; th = height;
1520 while (tw < width) tw <<= 1;
1521 while (th < height) th <<= 1;
1524 if (from == GR_FBCOPY_BUFFER_BACK && to == GR_FBCOPY_BUFFER_FRONT) {
1525 //printf("save depth buffer %d\n", render_to_texture);
1526 // save the depth image in a texture
1527 //glReadBuffer(current_buffer);
1528 glBindTexture(GL_TEXTURE_2D, depth_texture);
1529 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
1530 0, viewport_offset, tw, th, 0);
1531 glBindTexture(GL_TEXTURE_2D, default_texture);
1534 if (from == GR_FBCOPY_BUFFER_FRONT && to == GR_FBCOPY_BUFFER_BACK) {
1535 //printf("writing to depth buffer %d\n", render_to_texture);
1536 //glPushAttrib(GL_ALL_ATTRIB_BITS);
1537 //glDisable(GL_ALPHA_TEST);
1538 //glDrawBuffer(current_buffer);
1539 glActiveTexture(texture_unit);
1540 glBindTexture(GL_TEXTURE_2D, depth_texture);
1541 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1543 glEnable(GL_DEPTH_TEST);
1544 glDepthFunc(GL_ALWAYS);
1545 glDisable(GL_CULL_FACE);
1546 render_rectangle(texture_unit,
1550 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1551 glBindTexture(GL_TEXTURE_2D, default_texture);
1559 FX_ENTRY void FX_CALL
1560 grRenderBuffer( GrBuffer_t buffer )
1563 static HANDLE region = NULL;
1564 int realWidth = pBufferWidth, realHeight = pBufferHeight;
1566 LOG("grRenderBuffer(%d)\r\n", buffer);
1567 //printf("grRenderBuffer(%d)\n", buffer);
1571 case GR_BUFFER_BACKBUFFER:
1572 if(render_to_texture)
1577 //glMatrixMode(GL_MODELVIEW);
1579 //glTranslatef(0, 0, 1-zscale);
1580 //glScalef(1, 1, zscale);
1581 inverted_culling = 0;
1582 grCullMode(culling_mode);
1585 height = savedHeight;
1586 widtho = savedWidtho;
1587 heighto = savedHeighto;
1589 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1590 glBindRenderbuffer( GL_RENDERBUFFER, 0 );
1594 glViewport(0, viewport_offset, width, viewport_height);
1595 glScissor(0, viewport_offset, width, height);
1598 if (!use_fbo && render_to_texture == 2) {
1599 // restore color buffer
1600 if (nbAuxBuffers > 0) {
1601 //glDrawBuffer(GL_BACK);
1602 current_buffer = GL_BACK;
1603 } else if (save_w) {
1605 //printf("restore %dx%d\n", save_w, save_h);
1610 while (tw < screen_width) tw <<= 1;
1611 while (th < screen_height) th <<= 1;
1614 //glPushAttrib(GL_ALL_ATTRIB_BITS);
1615 //glDisable(GL_ALPHA_TEST);
1616 //glDrawBuffer(GL_BACK);
1617 glActiveTexture(texture_unit);
1618 glBindTexture(GL_TEXTURE_2D, color_texture);
1619 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1621 glDisable(GL_DEPTH_TEST);
1622 glDisable(GL_CULL_FACE);
1623 render_rectangle(texture_unit,
1627 glBindTexture(GL_TEXTURE_2D, default_texture);
1630 save_w = save_h = 0;
1634 render_to_texture = 0;
1636 //glDrawBuffer(GL_BACK);
1638 case 6: // RENDER TO TEXTURE
1639 if(!render_to_texture)
1642 savedHeight = height;
1643 savedWidtho = widtho;
1644 savedHeighto = heighto;
1649 //glMatrixMode(GL_MODELVIEW);
1651 //glTranslatef(0, 0, 1-zscale);
1652 //glScalef(1, 1, zscale);
1653 inverted_culling = 0;
1656 float m[4*4] = {1.0f, 0.0f, 0.0f, 0.0f,
1657 0.0f,-1.0f, 0.0f, 0.0f,
1658 0.0f, 0.0f, 1.0f, 0.0f,
1659 0.0f, 0.0f, 0.0f, 1.0f};
1660 glMatrixMode(GL_MODELVIEW);
1663 glTranslatef(0, 0, 1-zscale);
1664 glScalef(1, 1*1, zscale);
1666 inverted_culling = 1;
1667 grCullMode(culling_mode);
1670 render_to_texture = 1;
1673 display_warning("grRenderBuffer : unknown buffer : %x", buffer);
1677 FX_ENTRY void FX_CALL
1678 grAuxBufferExt( GrBuffer_t buffer )
1680 LOG("grAuxBufferExt(%d)\r\n", buffer);
1681 //display_warning("grAuxBufferExt");
1683 if (buffer == GR_BUFFER_AUXBUFFER) {
1686 need_to_compile = 0;
1688 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1689 glEnable(GL_DEPTH_TEST);
1690 glDepthFunc(GL_ALWAYS);
1691 glDisable(GL_CULL_FACE);
1692 //glDisable(GL_ALPHA_TEST);
1693 glDepthMask(GL_TRUE);
1694 grTexFilterMode(GR_TMU1, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
1696 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1697 need_to_compile = 1;
1701 FX_ENTRY void FX_CALL
1702 grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU32 depth )
1705 LOG("grBufferClear(%d,%d,%d)\r\n", color, alpha, depth);
1706 switch(lfb_color_fmt)
1708 case GR_COLORFORMAT_ARGB:
1709 glClearColor(((color >> 16) & 0xFF) / 255.0f,
1710 ((color >> 8) & 0xFF) / 255.0f,
1711 ( color & 0xFF) / 255.0f,
1714 case GR_COLORFORMAT_RGBA:
1715 glClearColor(((color >> 24) & 0xFF) / 255.0f,
1716 ((color >> 16) & 0xFF) / 255.0f,
1717 (color & 0xFF) / 255.0f,
1721 display_warning("grBufferClear: unknown color format : %x", lfb_color_fmt);
1725 glClearDepthf(1.0f - ((1.0f + (depth >> 4) / 4096.0f) * (1 << (depth & 0xF))) / 65528.0);
1727 glClearDepthf(depth / 65535.0f);
1728 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1730 // ZIGGY TODO check that color mask is on
1735 // #include <unistd.h>
1736 FX_ENTRY void FX_CALL
1737 grBufferSwap( FxU32 swap_interval )
1741 // printf("rendercallback is %p\n", renderCallback);
1743 (*renderCallback)(1);
1745 LOG("grBufferSwap(%d)\r\n", swap_interval);
1747 if (render_to_texture) {
1748 display_warning("swap while render_to_texture\n");
1752 CoreVideo_GL_SwapBuffers();
1753 for (i = 0; i < nb_fb; i++)
1754 fbs[i].buff_clear = 1;
1760 while (SDL_PollEvent(&event)) {
1761 switch (event.type) {
1763 switch (event.key.keysym.sym) {
1765 printf("Dumping !\n");
1769 static int wireframe;
1770 wireframe = !wireframe;
1771 glPolygonMode(GL_FRONT_AND_BACK, wireframe? GL_LINE : GL_FILL);
1783 FX_ENTRY FxBool FX_CALL
1784 grLfbLock( GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode,
1785 GrOriginLocation_t origin, FxBool pixelPipeline,
1788 LOG("grLfbLock(%d,%d,%d,%d,%d)\r\n", type, buffer, writeMode, origin, pixelPipeline);
1789 printf("grLfbLock(%d,%d,%d,%d,%d)\r\n", type, buffer, writeMode, origin, pixelPipeline);
1790 if (type == GR_LFB_WRITE_ONLY)
1792 display_warning("grLfbLock : write only");
1801 case GR_BUFFER_FRONTBUFFER:
1802 //glReadBuffer(GL_FRONT);
1804 case GR_BUFFER_BACKBUFFER:
1805 //glReadBuffer(GL_BACK);
1808 display_warning("grLfbLock : unknown buffer : %x", buffer);
1811 if(buffer != GR_BUFFER_AUXBUFFER)
1813 if (writeMode == GR_LFBWRITEMODE_888) {
1815 buf = (unsigned char*)malloc(width*height*4);
1816 //printf("LfbLock GR_LFBWRITEMODE_888\n");
1817 info->lfbPtr = frameBuffer;
1818 info->strideInBytes = width*4;
1819 info->writeMode = GR_LFBWRITEMODE_888;
1820 info->origin = origin;
1821 //glReadPixels(0, viewport_offset, width, height, GL_BGRA, GL_UNSIGNED_BYTE, frameBuffer);
1822 glReadPixels(0, viewport_offset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1825 unsigned char *p=buf;
1826 for (j=0; j<height; j++)
1828 short unsigned int *f=frameBuffer+(height-j-1)*width;
1829 for (i=0; i<width; i++)
1841 buf = (unsigned char*)malloc(width*height*4);
1843 info->lfbPtr = frameBuffer;
1844 info->strideInBytes = width*2;
1845 info->writeMode = GR_LFBWRITEMODE_565;
1846 info->origin = origin;
1847 glReadPixels(0, viewport_offset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1850 unsigned char *p=buf;
1851 for (j=0; j<height; j++)
1853 short unsigned int *f=frameBuffer+(height-j-1)*width;
1854 for (i=0; i<width; i++)
1856 /* frameBuffer[(height-j-1)*width+i] =
1857 ((buf[j*width*4+i*4+0] >> 3) << 11) |
1858 ((buf[j*width*4+i*4+1] >> 2) << 5) |
1859 (buf[j*width*4+i*4+2] >> 3);*/
1861 ((*(p) >> 3) << 11) |
1862 ((*(p+1) >> 2) << 5) |
1872 info->lfbPtr = depthBuffer;
1873 info->strideInBytes = width*2;
1874 info->writeMode = GR_LFBWRITEMODE_ZA16;
1875 info->origin = origin;
1876 //*SEB* *TODO* check alignment
1877 glReadPixels(0, viewport_offset, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
1884 FX_ENTRY FxBool FX_CALL
1885 grLfbUnlock( GrLock_t type, GrBuffer_t buffer )
1887 LOG("grLfbUnlock(%d,%d)\r\n", type, buffer);
1888 if (type == GR_LFB_WRITE_ONLY)
1890 display_warning("grLfbUnlock : write only");
1895 FX_ENTRY FxBool FX_CALL
1896 grLfbReadRegion( GrBuffer_t src_buffer,
1897 FxU32 src_x, FxU32 src_y,
1898 FxU32 src_width, FxU32 src_height,
1899 FxU32 dst_stride, void *dst_data )
1903 unsigned short *frameBuffer = (unsigned short*)dst_data;
1904 unsigned short *depthBuffer = (unsigned short*)dst_data;
1905 LOG("grLfbReadRegion(%d,%d,%d,%d,%d,%d)\r\n", src_buffer, src_x, src_y, src_width, src_height, dst_stride);
1906 //printf("grLfbReadRegion(%d,%d,%d,%d,%d,%d)\r\n", src_buffer, src_x, src_y, src_width, src_height, dst_stride);
1910 case GR_BUFFER_FRONTBUFFER:
1911 //glReadBuffer(GL_FRONT);
1913 case GR_BUFFER_BACKBUFFER:
1914 //glReadBuffer(GL_BACK);
1916 /*case GR_BUFFER_AUXBUFFER:
1917 glReadBuffer(current_buffer);
1920 display_warning("grReadRegion : unknown buffer : %x", src_buffer);
1923 if(src_buffer != GR_BUFFER_AUXBUFFER)
1925 buf = (unsigned char*)malloc(src_width*src_height*4);
1927 glReadPixels(src_x, (viewport_offset)+height-src_y-src_height, src_width, src_height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1928 for (j=0; j<src_height; j++)
1931 unsigned char *p=buf+(src_height-j-1)*src_width*4;
1932 unsigned short *f=frameBuffer+(j*dst_stride/2);
1933 for (i=0; i<src_width; i++)
1935 /* frameBuffer[j*(dst_stride/2)+i] =
1936 ((buf[(src_height-j-1)*src_width*4+i*4+0] >> 3) << 11) |
1937 ((buf[(src_height-j-1)*src_width*4+i*4+1] >> 2) << 5) |
1938 (buf[(src_height-j-1)*src_width*4+i*4+2] >> 3);*/
1940 ((*(p) >> 3) << 11) |
1941 ((*(p+1) >> 2) << 5) |
1950 buf = (unsigned char*)malloc(src_width*src_height*2);
1951 //*SEB read in buf, not depthBuffer.
1952 glReadPixels(src_x, (viewport_offset)+height-src_y-src_height, src_width, src_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, buf);
1954 for (j=0;j<src_height; j++)
1957 unsigned short *d=depthBuffer+j*dst_stride/2;
1958 unsigned short *p=(unsigned short*)buf+(src_height-j-1)*src_width; //orignal look fishy. why *4???
1959 for (i=0; i<src_width; i++)
1961 /* depthBuffer[j*(dst_stride/2)+i] =
1962 ((unsigned short*)buf)[(src_height-j-1)*src_width*4+i*4];*/
1963 *(d++) = *(p++); //why *4 (prob. GL_PACK was=4), plus transcoding to short, that make *8 ???
1972 FX_ENTRY FxBool FX_CALL
1973 grLfbWriteRegion( GrBuffer_t dst_buffer,
1974 FxU32 dst_x, FxU32 dst_y,
1975 GrLfbSrcFmt_t src_format,
1976 FxU32 src_width, FxU32 src_height,
1977 FxBool pixelPipeline,
1978 FxI32 src_stride, void *src_data )
1982 unsigned short *frameBuffer = (unsigned short*)src_data;
1984 unsigned int tex_width = 1, tex_height = 1;
1985 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);
1986 //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);
1988 //glPushAttrib(GL_ALL_ATTRIB_BITS);
1990 while (tex_width < src_width) tex_width <<= 1;
1991 while (tex_height < src_height) tex_height <<= 1;
1995 case GR_BUFFER_BACKBUFFER:
1996 //glDrawBuffer(GL_BACK);
1998 case GR_BUFFER_AUXBUFFER:
1999 //glDrawBuffer(current_buffer);
2002 display_warning("grLfbWriteRegion : unknown buffer : %x", dst_buffer);
2005 if(dst_buffer != GR_BUFFER_AUXBUFFER)
2007 buf = (unsigned char*)malloc(tex_width*tex_height*4);
2009 texture_number = GL_TEXTURE0;
2010 glActiveTexture(texture_number);
2012 const unsigned int half_stride = src_stride / 2;
2014 const int comp_stride = half_stride - src_width;
2015 const int comp_tex = (tex_width - src_width)*4;
2016 unsigned short *f=frameBuffer;
2017 unsigned char *p=buf;
2021 case GR_LFB_SRC_FMT_1555:
2022 for (j=0; j<src_height; j++)
2024 for (i=0; i<src_width; i++)
2026 /* const unsigned int col = frameBuffer[j*half_stride+i];
2027 buf[j*tex_width*4+i*4+0]=((col>>10)&0x1F)<<3;
2028 buf[j*tex_width*4+i*4+1]=((col>>5)&0x1F)<<3;
2029 buf[j*tex_width*4+i*4+2]=((col>>0)&0x1F)<<3;
2030 buf[j*tex_width*4+i*4+3]= (col>>15) ? 0xFF : 0;*/
2031 const unsigned int col = *(f++);
2032 *(p)=((col>>10)&0x1F)<<3;
2033 *(p+1)=((col>>5)&0x1F)<<3;
2034 *(p+2)=((col>>0)&0x1F)<<3;
2035 *(p+3)= (col>>15) ? 0xFF : 0;
2042 case GR_LFBWRITEMODE_555:
2043 for (j=0; j<src_height; j++)
2045 for (i=0; i<src_width; i++)
2047 /* const unsigned int col = frameBuffer[j*half_stride+i];
2048 buf[j*tex_width*4+i*4+0]=((col>>10)&0x1F)<<3;
2049 buf[j*tex_width*4+i*4+1]=((col>>5)&0x1F)<<3;
2050 buf[j*tex_width*4+i*4+2]=((col>>0)&0x1F)<<3;
2051 buf[j*tex_width*4+i*4+3]=0xFF;*/
2052 const unsigned int col = *(f++);
2053 *(p)=((col>>10)&0x1F)<<3;
2054 *(p+1)=((col>>5)&0x1F)<<3;
2055 *(p+2)=((col>>0)&0x1F)<<3;
2063 case GR_LFBWRITEMODE_565:
2064 for (j=0; j<src_height; j++)
2066 for (i=0; i<src_width; i++)
2068 /* const unsigned int col = frameBuffer[j*half_stride+i];
2069 buf[j*tex_width*4+i*4+0]=((col>>11)&0x1F)<<3;
2070 buf[j*tex_width*4+i*4+1]=((col>>5)&0x3F)<<2;
2071 buf[j*tex_width*4+i*4+2]=((col>>0)&0x1F)<<3;
2072 buf[j*tex_width*4+i*4+3]=0xFF;*/
2073 const unsigned int col = *(f++);
2074 *(p)=((col>>11)&0x1F)<<3;
2075 *(p+1)=((col>>5)&0x3F)<<2;
2076 *(p+2)=((col>>0)&0x1F)<<3;
2085 display_warning("grLfbWriteRegion : unknown format : %d", src_format);
2090 ilTexImage(tex_width, tex_height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, buf);
2093 sprintf(name, "dump/writecolor%d.png", id++);
2095 //printf("dumped gdLfbWriteRegion %s\n", name);
2099 glBindTexture(GL_TEXTURE_2D, default_texture);
2100 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
2105 glDisable(GL_DEPTH_TEST);
2106 glDisable(GL_BLEND);
2107 render_rectangle(texture_number,
2109 src_width, src_height,
2110 tex_width, tex_height, +1);
2115 float *buf = (float*)malloc(src_width*(src_height+(viewport_offset))*sizeof(float));
2117 if (src_format != GR_LFBWRITEMODE_ZA16)
2118 display_warning("unknown depth buffer write format:%x", src_format);
2121 display_warning("dst_x:%d, dst_y:%d\n",dst_x, dst_y);
2123 for (j=0; j<src_height; j++)
2125 for (i=0; i<src_width; i++)
2127 buf[(j+(viewport_offset))*src_width+i] =
2128 (frameBuffer[(src_height-j-1)*(src_stride/2)+i]/(65536.0f*(2.0f/zscale)))+1-zscale/2.0f;
2134 unsigned char * buf2 = (unsigned char *)malloc(src_width*(src_height+(viewport_offset)));
2135 for (i=0; i<src_width*src_height ; i++)
2136 buf2[i] = buf[i]*255.0f;
2137 ilTexImage(src_width, src_height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, buf2);
2140 sprintf(name, "dump/writedepth%d.png", id++);
2142 //printf("dumped gdLfbWriteRegion %s\n", name);
2147 glEnable(GL_DEPTH_TEST);
2148 glDepthFunc(GL_ALWAYS);
2150 //glDrawBuffer(GL_BACK);
2151 glClear( GL_DEPTH_BUFFER_BIT );
2153 //glDrawPixels(src_width, src_height+(viewport_offset), GL_DEPTH_COMPONENT, GL_FLOAT, buf);
2157 //glDrawBuffer(current_buffer);
2162 /* wrapper-specific glide extensions */
2164 FX_ENTRY char ** FX_CALL
2165 grQueryResolutionsExt(FxI32 * Size)
2169 LOG("grQueryResolutionsExt\r\n");
2170 return g_FullScreenResolutions.getResolutionsList(Size);
2174 FX_ENTRY GrScreenResolution_t FX_CALL grWrapperFullScreenResolutionExt(FxU32* width, FxU32* height)
2178 LOG("grWrapperFullScreenResolutionExt\r\n");
2179 g_FullScreenResolutions.getResolution(config.res, width, height);
2184 FX_ENTRY FxBool FX_CALL grKeyPressedExt(FxU32 key)
2189 return (GetAsyncKeyState(key) & 0x8000);
2191 if (key == 1) //LBUTTON
2193 Uint8 mstate = SDL_GetMouseState(NULL, NULL);
2194 return (mstate & SDL_BUTTON_LMASK);
2198 Uint8 *keystates = SDL_GetKeyState( NULL );
2199 if( keystates[ key ] )
2212 FX_ENTRY void FX_CALL grConfigWrapperExt(FxI32 resolution, FxI32 vram, FxBool fbo, FxBool aniso)
2214 LOG("grConfigWrapperExt\r\n");
2215 config.res = resolution;
2216 config.vram_size = vram;
2218 config.anisofilter = aniso;
2221 // unused by glide64
2223 FX_ENTRY FxI32 FX_CALL
2224 grQueryResolutions( const GrResolution *resTemplate, GrResolution *output )
2230 LOG("grQueryResolutions\r\n");
2231 display_warning("grQueryResolutions");
2232 if ((unsigned int)resTemplate->resolution != GR_QUERY_ANY)
2234 res_inf = res_sup = resTemplate->resolution;
2236 if ((unsigned int)resTemplate->refresh == GR_QUERY_ANY) display_warning("querying any refresh rate");
2237 if ((unsigned int)resTemplate->numAuxBuffers == GR_QUERY_ANY) display_warning("querying any numAuxBuffers");
2238 if ((unsigned int)resTemplate->numColorBuffers == GR_QUERY_ANY) display_warning("querying any numColorBuffers");
2240 if (output == NULL) return res_sup - res_inf + 1;
2241 for (i=res_inf; i<=res_sup; i++)
2243 output[n].resolution = i;
2244 output[n].refresh = resTemplate->refresh;
2245 output[n].numAuxBuffers = resTemplate->numAuxBuffers;
2246 output[n].numColorBuffers = resTemplate->numColorBuffers;
2249 return res_sup - res_inf + 1;
2252 FX_ENTRY FxBool FX_CALL
2253 grReset( FxU32 what )
2255 display_warning("grReset");
2259 FX_ENTRY void FX_CALL
2260 grEnable( GrEnableMode_t mode )
2262 LOG("grEnable(%d)\r\n", mode);
2263 if (mode == GR_TEXTURE_UMA_EXT)
2267 FX_ENTRY void FX_CALL
2268 grDisable( GrEnableMode_t mode )
2270 LOG("grDisable(%d)\r\n", mode);
2271 if (mode == GR_TEXTURE_UMA_EXT)
2275 FX_ENTRY void FX_CALL
2276 grDisableAllEffects( void )
2278 display_warning("grDisableAllEffects");
2281 FX_ENTRY void FX_CALL
2282 grErrorSetCallback( GrErrorCallbackFnc_t fnc )
2284 display_warning("grErrorSetCallback");
2287 FX_ENTRY void FX_CALL
2290 display_warning("grFinish");
2293 FX_ENTRY void FX_CALL
2296 display_warning("grFlush");
2299 FX_ENTRY void FX_CALL
2300 grTexMultibase( GrChipID_t tmu,
2303 display_warning("grTexMultibase");
2306 FX_ENTRY void FX_CALL
2307 grTexMipMapMode( GrChipID_t tmu,
2308 GrMipMapMode_t mode,
2311 display_warning("grTexMipMapMode");
2314 FX_ENTRY void FX_CALL
2315 grTexDownloadTablePartial( GrTexTable_t type,
2320 display_warning("grTexDownloadTablePartial");
2323 FX_ENTRY void FX_CALL
2324 grTexDownloadTable( GrTexTable_t type,
2327 display_warning("grTexDownloadTable");
2330 FX_ENTRY FxBool FX_CALL
2331 grTexDownloadMipMapLevelPartial( GrChipID_t tmu,
2335 GrAspectRatio_t aspectRatio,
2336 GrTextureFormat_t format,
2342 display_warning("grTexDownloadMipMapLevelPartial");
2346 FX_ENTRY void FX_CALL
2347 grTexDownloadMipMapLevel( GrChipID_t tmu,
2351 GrAspectRatio_t aspectRatio,
2352 GrTextureFormat_t format,
2356 display_warning("grTexDownloadMipMapLevel");
2359 FX_ENTRY void FX_CALL
2360 grTexNCCTable( GrNCCTable_t table )
2362 display_warning("grTexNCCTable");
2365 FX_ENTRY void FX_CALL
2366 grViewport( FxI32 x, FxI32 y, FxI32 width, FxI32 height )
2368 display_warning("grViewport");
2371 FX_ENTRY void FX_CALL
2372 grDepthRange( FxFloat n, FxFloat f )
2374 display_warning("grDepthRange");
2377 FX_ENTRY void FX_CALL
2378 grSplash(float x, float y, float width, float height, FxU32 frame)
2380 display_warning("grSplash");
2383 FX_ENTRY FxBool FX_CALL
2384 grSelectContext( GrContext_t context )
2386 display_warning("grSelectContext");
2390 FX_ENTRY void FX_CALL
2392 const void *a, const void *b, const void *c,
2393 FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias
2396 display_warning("grAADrawTriangle");
2399 FX_ENTRY void FX_CALL
2400 grAlphaControlsITRGBLighting( FxBool enable )
2402 display_warning("grAlphaControlsITRGBLighting");
2405 FX_ENTRY void FX_CALL
2406 grGlideSetVertexLayout( const void *layout )
2408 display_warning("grGlideSetVertexLayout");
2411 FX_ENTRY void FX_CALL
2412 grGlideGetVertexLayout( void *layout )
2414 display_warning("grGlideGetVertexLayout");
2417 FX_ENTRY void FX_CALL
2418 grGlideSetState( const void *state )
2420 display_warning("grGlideSetState");
2423 FX_ENTRY void FX_CALL
2424 grGlideGetState( void *state )
2426 display_warning("grGlideGetState");
2429 FX_ENTRY void FX_CALL
2430 grLfbWriteColorFormat(GrColorFormat_t colorFormat)
2432 display_warning("grLfbWriteColorFormat");
2435 FX_ENTRY void FX_CALL
2436 grLfbWriteColorSwizzle(FxBool swizzleBytes, FxBool swapWords)
2438 display_warning("grLfbWriteColorSwizzle");
2441 FX_ENTRY void FX_CALL
2442 grLfbConstantDepth( FxU32 depth )
2444 display_warning("grLfbConstantDepth");
2447 FX_ENTRY void FX_CALL
2448 grLfbConstantAlpha( GrAlpha_t alpha )
2450 display_warning("grLfbConstantAlpha");
2453 FX_ENTRY void FX_CALL
2454 grTexMultibaseAddress( GrChipID_t tmu,
2455 GrTexBaseRange_t range,
2460 display_warning("grTexMultibaseAddress");
2464 inline void MySleep(FxU32 ms)
2475 static void CorrectGamma(LPVOID apGammaRamp)
2477 HDC hdc = GetDC(NULL);
2480 SetDeviceGammaRamp(hdc, apGammaRamp);
2481 ReleaseDC(NULL, hdc);
2485 static void CorrectGamma(const FxU16 aGammaRamp[3][256])
2488 //int res = SDL_SetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]);
2489 //LOG("SDL_SetGammaRamp returned %d\r\n", res);
2493 FX_ENTRY void FX_CALL
2494 grLoadGammaTable( FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue)
2496 LOG("grLoadGammaTable\r\n");
2499 FxU16 aGammaRamp[3][256];
2500 for (int i = 0; i < 256; i++)
2502 aGammaRamp[0][i] = (FxU16)((red[i] << 8) & 0xFFFF);
2503 aGammaRamp[1][i] = (FxU16)((green[i] << 8) & 0xFFFF);
2504 aGammaRamp[2][i] = (FxU16)((blue[i] << 8) & 0xFFFF);
2506 CorrectGamma(aGammaRamp);
2507 //MySleep(1000); //workaround for Mupen64
2510 FX_ENTRY void FX_CALL
2511 grGetGammaTableExt(FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue)
2516 LOG("grGetGammaTableExt()\r\n");
2517 FxU16 aGammaRamp[3][256];
2519 HDC hdc = GetDC(NULL);
2522 if (GetDeviceGammaRamp(hdc, aGammaRamp) == TRUE)
2524 ReleaseDC(NULL, hdc);
2526 if (SDL_GetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]) != -1)
2529 for (int i = 0; i < 256; i++)
2531 red[i] = aGammaRamp[0][i] >> 8;
2532 green[i] = aGammaRamp[1][i] >> 8;
2533 blue[i] = aGammaRamp[2][i] >> 8;
2539 FX_ENTRY void FX_CALL
2540 guGammaCorrectionRGB( FxFloat gammaR, FxFloat gammaG, FxFloat gammaB )
2542 LOG("guGammaCorrectionRGB()\r\n");
2545 FxU16 aGammaRamp[3][256];
2546 for (int i = 0; i < 256; i++)
2548 aGammaRamp[0][i] = (((FxU16)((pow(i/255.0F, 1.0F/gammaR)) * 255.0F + 0.5F)) << 8) & 0xFFFF;
2549 aGammaRamp[1][i] = (((FxU16)((pow(i/255.0F, 1.0F/gammaG)) * 255.0F + 0.5F)) << 8) & 0xFFFF;
2550 aGammaRamp[2][i] = (((FxU16)((pow(i/255.0F, 1.0F/gammaB)) * 255.0F + 0.5F)) << 8) & 0xFFFF;
2552 CorrectGamma(aGammaRamp);
2555 FX_ENTRY void FX_CALL
2556 grDitherMode( GrDitherMode_t mode )
2558 display_warning("grDitherMode");
2561 void grChromaRangeExt(GrColor_t color0, GrColor_t color1, FxU32 mode)
2563 display_warning("grChromaRangeExt");
2566 void grChromaRangeModeExt(GrChromakeyMode_t mode)
2568 display_warning("grChromaRangeModeExt");
2571 void grTexChromaRangeExt(GrChipID_t tmu, GrColor_t color0, GrColor_t color1, GrTexChromakeyMode_t mode)
2573 display_warning("grTexChromaRangeExt");
2576 void grTexChromaModeExt(GrChipID_t tmu, GrChromakeyMode_t mode)
2578 display_warning("grTexChromaRangeModeExt");
2585 static int tl[10240];
2593 ilEnable(IL_FILE_OVERWRITE);
2601 if (!dumping) return;
2604 for (i=0; i<nb_fb; i++) {
2605 dump_tex(fbs[i].texid);
2607 dump_tex(default_texture);
2608 dump_tex(depth_texture);
2612 glReadBuffer(GL_FRONT);
2613 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer);
2614 ilTexImage(width, height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, frameBuffer);
2615 ilSaveImage("dump/framecolor.png");
2616 glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
2617 // FILE * fp = fopen("glide_depth1.bin", "rb");
2618 // fread(depthBuffer, 2, width*height, fp);
2620 for (j=0; j<height; j++) {
2621 for (i=0; i<width; i++) {
2622 //uint16_t d = ( (uint16_t *)depthBuffer )[i+(height-1-j)*width]/2 + 0x8000;
2623 uint16_t d = ( (uint16_t *)depthBuffer )[i+j*width];
2624 uint32_t c = ( (uint32_t *)frameBuffer )[i+j*width];
2625 ( (unsigned char *)frameBuffer )[(i+j*width)*3] = d&0xff;
2626 ( (unsigned char *)frameBuffer )[(i+j*width)*3+1] = d>>8;
2627 ( (unsigned char *)frameBuffer )[(i+j*width)*3+2] = c&0xff;
2630 ilTexImage(width, height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, frameBuffer);
2631 ilSaveImage("dump/framedepth.png");
2633 for (i=0; i<tl_i; i++) {
2634 glBindTexture(GL_TEXTURE_2D, tl[i]);
2636 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
2637 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
2638 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
2639 fprintf(stderr, "Texture %d %dx%d fmt %x\n", tl[i], (int)w, (int)h, (int) fmt);
2641 uint32_t * pixels = (uint32_t *) malloc(w*h*4);
2642 // 0x1902 is another constant meaning GL_DEPTH_COMPONENT
2643 // (but isn't defined in gl's headers !!)
2644 if (fmt != GL_DEPTH_COMPONENT && fmt != 0x1902) {
2645 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2646 ilTexImage(w, h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pixels);
2648 glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixels);
2650 for (i=0; i<w*h; i++)
2651 ((unsigned char *)frameBuffer)[i] = ((unsigned short *)pixels)[i]/256;
2652 ilTexImage(w, h, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, frameBuffer);
2655 // sprintf(name, "mkdir -p dump ; rm -f dump/tex%04d.png", i);
2657 sprintf(name, "dump/tex%04d.png", i);
2658 fprintf(stderr, "Writing '%s'\n", name);
2661 // SDL_FreeSurface(surf);
2664 glBindTexture(GL_TEXTURE_2D, default_texture);
2667 void dump_tex(int id)
2669 if (!dumping) return;
2672 // yes, it's inefficient
2673 for (n=0; n<tl_i; n++)