2017-04-26 10:23:36 +00:00
/***************************************************************************
* *
* Project64 - video - A Nintendo 64 gfx plugin . *
* http : //www.pj64-emu.com/ *
* Copyright ( C ) 2017 Project64 . All rights reserved . *
* Copyright ( C ) 2003 - 2009 Sergey ' Gonetz ' Lipski *
* Copyright ( C ) 2002 Dave2001 *
* *
* License : *
* GNU / GPLv2 http : //www.gnu.org/licenses/gpl-2.0.html *
* version 2 of the License , or ( at your option ) any later version . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-04-10 07:08:48 +00:00
# define SAVE_CBUFFER
# ifdef _WIN32
# include <windows.h>
# else
# include <stdint.h>
# include <stdarg.h>
# include <string.h>
# endif // _WIN32
# include <stdlib.h>
# include <stdio.h>
# include <iostream>
# include <fstream>
# include <math.h>
# include "glide.h"
# include "g3ext.h"
2015-10-09 04:53:16 +00:00
# include "glitchmain.h"
2017-04-26 09:05:05 +00:00
# include <Project64-video/trace.h>
2016-03-26 01:26:53 +00:00
# include <Common/Util.h>
2013-04-10 07:08:48 +00:00
# ifdef VPDEBUG
# include <IL/il.h>
# endif
2015-03-05 01:40:31 +00:00
/*
* ` GetSystemSetting ` and ` FindSystemSettingId ` from Project64 debugger
2017-04-18 11:32:43 +00:00
* used only in g_Notify - > DisplayError when OpenGL extension loading fails on WGL
2015-03-05 01:40:31 +00:00
*/
2016-01-20 06:07:06 +00:00
# include <Settings/Settings.h>
2015-03-05 01:40:31 +00:00
2017-01-28 11:29:03 +00:00
wrapper_config config = { 0 , 0 , 0 } ;
2013-04-10 07:08:48 +00:00
int screen_width , screen_height ;
2016-02-03 21:21:30 +00:00
static inline void opt_glCopyTexImage2D ( GLenum target ,
GLint level ,
GLint internalFormat ,
GLint x ,
GLint y ,
GLsizei width ,
GLsizei height ,
GLint border )
{
int w , h , fmt ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_WIDTH , & w ) ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_HEIGHT , & h ) ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_INTERNAL_FORMAT , & fmt ) ;
//printf("copyteximage %dx%d fmt %x oldfmt %x\n", width, height, internalFormat, fmt);
if ( w = = width & & h = = height & & fmt = = internalFormat ) {
if ( x + width > = screen_width ) {
width = screen_width - x ;
//printf("resizing w --> %d\n", width);
}
2017-03-13 09:34:51 +00:00
if ( y + height > = screen_height + g_viewport_offset ) {
height = screen_height + g_viewport_offset - y ;
2016-02-03 21:21:30 +00:00
//printf("resizing h --> %d\n", height);
}
glCopyTexSubImage2D ( target , level , 0 , 0 , x , y , width , height ) ;
}
else {
//printf("copyteximage %dx%d fmt %x old %dx%d oldfmt %x\n", width, height, internalFormat, w, h, fmt);
// glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, internalFormat, GL_UNSIGNED_BYTE, 0);
// glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
// printf("--> %dx%d newfmt %x\n", width, height, fmt);
glCopyTexImage2D ( target , level , internalFormat , x , y , width , height , border ) ;
}
grDisplayGLError ( " opt_glCopyTexImage2D " ) ;
2013-04-10 07:08:48 +00:00
}
# define glCopyTexImage2D opt_glCopyTexImage2D
# ifdef _WIN32
2015-03-04 20:11:35 +00:00
/*
* Some post - 1.1 OpenGL functions can fail to be loaded through GL extensions
* when running primitive OpenGL contexts on Microsoft Windows , specifically .
*
* As of the Project64 Glide64 version , Glitch64 now assigns these GL
* functions to dummy functions to prevent access violations , while also
* displaying error information showing the missing OpenGL support .
*/
2013-04-10 07:08:48 +00:00
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB ;
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT ;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB ;
PFNGLFOGCOORDFPROC glFogCoordfEXT ;
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glActiveTexture ( GLenum /*texture*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 197, req. OpenGL 1.3 (1.2 w/ ARB_multitexture) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glActiveTexture " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glMultiTexCoord2f ( GLenum /*target*/ , GLfloat /*s*/ , GLfloat /*t*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 203, req. OpenGL 1.3 (1.2 w/ ARB_multitexture) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glMultiTexCoord2f " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glFogCoordf ( GLfloat /*coord*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4124, req. OpenGL 1.4 (1.1 w/ EXT_fog_coord) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glFogCoordf " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glBlendFuncSeparate ( GLenum , GLenum , GLenum , GLenum )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4134, req. OpenGL 1.0 w/ EXT_blend_func_separate */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glBlendFuncSeparate " ) ;
2015-03-04 20:11:35 +00:00
}
2013-04-10 07:08:48 +00:00
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB ;
2015-03-05 01:29:59 +00:00
const char * APIENTRY dummy_wglGetExtensionsString ( HDC )
2015-03-04 20:11:35 +00:00
{
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " wglGetExtensionsString " ) ;
2015-03-04 20:11:35 +00:00
return NULL ;
}
2013-04-10 07:08:48 +00:00
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT ;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT ;
PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT ;
PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL ;
PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL ;
PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL ;
PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL ;
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL ;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT ;
PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT ;
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glGenRenderbuffers ( GLsizei /*n*/ , GLuint * /*renderbuffers*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX vendor opcode 1423, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glGenRenderbuffers " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glGenFramebuffers ( GLsizei /*n*/ , GLuint * /*framebuffers*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX vendor opcode 1426, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glGenFramebuffers " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
GLenum APIENTRY dummy_glCheckFramebufferStatus ( GLenum /*target*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX vendor opcode 1427, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glCheckFramebufferStatus " ) ;
2015-03-04 20:11:35 +00:00
return 0x00008CDD ; /* GL_FRAMEBUFFER_UNSUPPORTED */
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glBindRenderbuffer ( GLenum /*target*/ , GLuint /*renderbuffer*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4316, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glBindRenderbuffer " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glDeleteRenderbuffers ( GLsizei /*n*/ , const GLuint * /*renderbuffers*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4317, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glDeleteRenderbuffers " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glRenderbufferStorage ( GLenum , GLenum , GLsizei , GLsizei )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4318, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glRenderbufferStorage " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glBindFramebuffer ( GLenum /*target*/ , GLuint /*framebuffer*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4319, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glBindFramebuffer " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glDeleteFramebuffers ( GLsizei /*n*/ , const GLuint * /*framebuffers*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4320, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glDeleteFramebuffers " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glFramebufferTexture2D ( GLenum , GLenum , GLenum , GLuint , GLint )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4322, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glFramebufferTexture2D " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glFramebufferRenderbuffer ( GLenum , GLenum , GLenum , GLuint )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4324, req. OpenGL 1.2 w/ EXT_framebuffer_object */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glFramebufferRenderbuffer " ) ;
2015-03-04 20:11:35 +00:00
}
2013-04-10 07:08:48 +00:00
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB ;
PFNGLSHADERSOURCEARBPROC glShaderSourceARB ;
PFNGLCOMPILESHADERARBPROC glCompileShaderARB ;
PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB ;
PFNGLATTACHOBJECTARBPROC glAttachObjectARB ;
PFNGLLINKPROGRAMARBPROC glLinkProgramARB ;
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB ;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB ;
PFNGLUNIFORM1IARBPROC glUniform1iARB ;
PFNGLUNIFORM4IARBPROC glUniform4iARB ;
PFNGLUNIFORM4FARBPROC glUniform4fARB ;
PFNGLUNIFORM1FARBPROC glUniform1fARB ;
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB ;
PFNGLGETINFOLOGARBPROC glGetInfoLogARB ;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB ;
PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f ;
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glSecondaryColor3f ( GLfloat /*red*/ , GLfloat /*green*/ , GLfloat /*blue*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 4129, req. OpenGL 1.4 (1.1 w/ EXT_secondary_color) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glSecondaryColor3f " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
GLuint APIENTRY dummy_glCreateShader ( GLenum /*type*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glCreateShader " ) ;
2015-03-04 20:11:35 +00:00
return ( ( GLuint ) ( NULL ) ) ;
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glShaderSource ( GLuint , GLsizei , const GLchar * * , GLint * )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glShaderSource " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glCompileShader ( GLuint /*shader*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glCompileShader " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
GLuint APIENTRY dummy_glCreateProgram ( void )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glCreateProgram " ) ;
2015-03-04 20:11:35 +00:00
return ( ( GLuint ) ( NULL ) ) ;
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glAttachObject ( GLhandleARB , GLhandleARB )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glAttachObject " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glLinkProgram ( GLuint /*program*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glLinkProgram " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glUseProgram ( GLuint /*program*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glUseProgram " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
GLint APIENTRY dummy_glGetUniformLocation ( GLuint /*program*/ , GLchar * /*name*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX single opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glGetUniformLocation " ) ;
2015-03-04 20:11:35 +00:00
return - 1 ;
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glUniform1i ( GLint /*location*/ , GLint /*v0*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glUniform1i " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glUniform4i ( GLint /*location*/ , GLint , GLint , GLint , GLint )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glUniform4i " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glUniform1f ( GLint /*location*/ , GLfloat /*v0*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glUniform1f " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glUniform4f ( GLint /*location*/ , GLfloat , GLfloat , GLfloat , GLfloat )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 2.0 (1.2 w/ ARB_shader_objects) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glUniform4f " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glDeleteObject ( GLhandleARB /*obj*/ )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode ?, req. OpenGL 1.2 w/ ARB_shader_objects */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glDeleteObject " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glGetInfoLog ( GLhandleARB , GLsizei , GLsizei * , GLcharARB * )
2015-03-04 20:12:45 +00:00
{ /* GLX single opcode ?, req. OpenGL 1.2 w/ ARB_shader_objects */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glGetInfoLog " ) ;
2015-03-04 20:11:35 +00:00
}
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glGetObjectParameteriv ( GLhandleARB , GLenum , GLint * )
2015-03-04 20:12:45 +00:00
{ /* GLX single opcode ?, req. OpenGL 1.2 w/ ARB_shader_objects */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glGetObjectParameteriv " ) ;
2015-03-04 20:11:35 +00:00
}
2013-04-10 07:08:48 +00:00
// FXT1,DXT1,DXT5 support - Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
// NOTE: Glide64 + GlideHQ use the following formats
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT
// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
// GL_COMPRESSED_RGB_FXT1_3DFX
// GL_COMPRESSED_RGBA_FXT1_3DFX
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2DARB ;
2015-03-05 01:29:59 +00:00
void APIENTRY dummy_glCompressedTexImage2D ( GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid * )
2015-03-04 20:12:45 +00:00
{ /* GLX render opcode 215, req. OpenGL 1.3 (1.2 w/ ARB_texture_compression) */
2017-04-18 11:32:43 +00:00
g_Notify - > DisplayError ( " glCompressedTexImage2D " ) ;
2015-03-04 20:11:35 +00:00
}
2013-04-10 07:08:48 +00:00
# endif // _WIN32
typedef struct
{
2016-02-03 21:21:30 +00:00
unsigned int address ;
int width ;
int height ;
unsigned int fbid ;
unsigned int zbid ;
unsigned int texid ;
int buff_clear ;
2013-04-10 07:08:48 +00:00
} fb ;
int nbTextureUnits ;
int nbAuxBuffers , current_buffer ;
2017-04-27 09:06:14 +00:00
int g_scr_res_x , g_width , widtho , heighto , g_scr_res_y , g_height ;
int g_res_x , g_res_y ;
2013-04-10 07:08:48 +00:00
int saved_width , saved_height ;
int blend_func_separate_support ;
int npot_support ;
int fog_coord_support ;
int render_to_texture = 0 ;
int texture_unit ;
int use_fbo ;
int buffer_cleared ;
// ZIGGY
// to allocate a new static texture name, take the value (free_texture++)
int free_texture ;
int default_texture ; // the infamous "32*1024*1024" is now configurable
int current_texture ;
int depth_texture , color_texture ;
int glsl_support = 1 ;
2017-03-13 09:34:51 +00:00
int viewport_width , viewport_height , g_viewport_offset = 0 , nvidia_viewport_hack = 0 ;
2013-04-10 07:08:48 +00:00
int save_w , save_h ;
int lfb_color_fmt ;
float invtex [ 2 ] ;
//Gonetz
int UMAmode = 0 ; //support for VSA-100 UMA mode;
# ifdef _WIN32
static HDC hDC = NULL ;
static HGLRC hGLRC = NULL ;
static HWND hToolBar = NULL ;
# endif // _WIN32
static int savedWidtho , savedHeighto ;
static int savedWidth , savedHeight ;
unsigned int pBufferAddress ;
static int pBufferFmt ;
static int pBufferWidth , pBufferHeight ;
static fb fbs [ 100 ] ;
static int nb_fb = 0 ;
static unsigned int curBufferAddr = 0 ;
2015-02-01 17:10:19 +00:00
struct TMU_USAGE { unsigned long min , max ; } tmu_usage [ 2 ] = {
2016-02-03 21:21:30 +00:00
{ 0x0FFFFFFFul , 0x00000000ul } ,
{ 0x0FFFFFFFul , 0x00000000ul } ,
2015-02-01 17:10:19 +00:00
} ;
2013-04-10 07:08:48 +00:00
struct texbuf_t {
2016-02-03 21:21:30 +00:00
FxU32 start , end ;
int fmt ;
2013-04-10 07:08:48 +00:00
} ;
# define NB_TEXBUFS 128 // MUST be a power of two
static texbuf_t texbufs [ NB_TEXBUFS ] ;
static int texbuf_i ;
2016-02-03 21:21:30 +00:00
unsigned short frameBuffer [ 2048 * 2048 ] ;
unsigned short depthBuffer [ 2048 * 2048 ] ;
2013-04-10 07:08:48 +00:00
//#define VOODOO1
FX_ENTRY void FX_CALL
grSstOrigin ( GrOriginLocation_t origin )
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " origin = %d " , origin ) ;
2016-02-03 21:21:30 +00:00
if ( origin ! = GR_ORIGIN_UPPER_LEFT )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grSstOrigin : %x " , origin ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grClipWindow ( FxU32 minx , FxU32 miny , FxU32 maxx , FxU32 maxy )
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " minx = %d, miny: %d maxy: %d " , minx , miny , maxy ) ;
2016-02-03 21:21:30 +00:00
2017-04-27 07:31:49 +00:00
if ( use_fbo & & render_to_texture )
{
2016-02-03 21:21:30 +00:00
if ( int ( minx ) < 0 ) minx = 0 ;
if ( int ( miny ) < 0 ) miny = 0 ;
if ( maxx < minx ) maxx = minx ;
if ( maxy < miny ) maxy = miny ;
glScissor ( minx , miny , maxx - minx , maxy - miny ) ;
glEnable ( GL_SCISSOR_TEST ) ;
grDisplayGLError ( " grClipWindow :: use_fbo " ) ;
return ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( ! use_fbo ) {
2016-03-10 17:21:56 +00:00
int th = g_height ;
2016-02-03 21:21:30 +00:00
if ( th > screen_height )
th = screen_height ;
maxy = th - maxy ;
miny = th - miny ;
FxU32 tmp = maxy ; maxy = miny ; miny = tmp ;
2016-03-10 17:21:56 +00:00
if ( ( FxI32 ) maxx > g_width ) maxx = g_width ;
if ( ( FxI32 ) maxy > g_height ) maxy = g_height ;
2016-02-03 21:21:30 +00:00
if ( int ( minx ) < 0 ) minx = 0 ;
if ( int ( miny ) < 0 ) miny = 0 ;
if ( maxx < minx ) maxx = minx ;
if ( maxy < miny ) maxy = miny ;
2017-03-13 09:34:51 +00:00
glScissor ( minx , miny + g_viewport_offset , maxx - minx , maxy - miny ) ;
2016-02-03 21:21:30 +00:00
//printf("gl scissor %d %d %d %d\n", minx, miny, maxx, maxy);
}
else {
2017-03-13 09:34:51 +00:00
glScissor ( minx , ( g_viewport_offset ) + g_height - maxy , maxx - minx , maxy - miny ) ;
2016-02-03 21:21:30 +00:00
}
2013-04-10 07:08:48 +00:00
glEnable ( GL_SCISSOR_TEST ) ;
2016-02-03 21:21:30 +00:00
grDisplayGLError ( " grClipWindow " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grColorMask ( FxBool rgb , FxBool a )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " rgb = %d, a: %d " , rgb , a ) ;
2016-02-03 21:21:30 +00:00
glColorMask ( ( GLboolean ) rgb , ( GLboolean ) rgb , ( GLboolean ) rgb , ( GLboolean ) a ) ;
grDisplayGLError ( " grColorMask " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grGlideInit ( void )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2013-04-10 07:08:48 +00:00
}
int isExtensionSupported ( const char * extension )
{
2016-02-03 21:21:30 +00:00
const GLubyte * extensions = NULL ;
const GLubyte * start ;
GLubyte * where , * terminator ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
where = ( GLubyte * ) strchr ( extension , ' ' ) ;
if ( where | | * extension = = ' \0 ' )
return 0 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
extensions = glGetString ( GL_EXTENSIONS ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
start = extensions ;
for ( ; ; )
{
where = ( GLubyte * ) strstr ( ( const char * ) start , extension ) ;
if ( ! where )
break ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
terminator = where + strlen ( extension ) ;
if ( where = = start | | * ( where - 1 ) = = ' ' )
if ( * terminator = = ' ' | | * terminator = = ' \0 ' )
return 1 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
start = terminator ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
return 0 ;
2013-04-10 07:08:48 +00:00
}
# ifdef _WIN32
int isWglExtensionSupported ( const char * extension )
{
2016-02-03 21:21:30 +00:00
const GLubyte * extensions = NULL ;
const GLubyte * start ;
GLubyte * where , * terminator ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
where = ( GLubyte * ) strchr ( extension , ' ' ) ;
if ( where | | * extension = = ' \0 ' )
return 0 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
extensions = ( GLubyte * ) wglGetExtensionsStringARB ( wglGetCurrentDC ( ) ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
start = extensions ;
for ( ; ; )
{
where = ( GLubyte * ) strstr ( ( const char * ) start , extension ) ;
if ( ! where )
break ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
terminator = where + strlen ( extension ) ;
if ( where = = start | | * ( where - 1 ) = = ' ' )
if ( * terminator = = ' ' | | * terminator = = ' \0 ' )
return 1 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
start = terminator ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
return 0 ;
2013-04-10 07:08:48 +00:00
}
# endif // _WIN32
# define GrPixelFormat_t int
FX_ENTRY GrContext_t FX_CALL
grSstWinOpenExt (
2017-04-18 11:32:43 +00:00
GrColorFormat_t color_format ,
GrOriginLocation_t origin_location ,
GrPixelFormat_t /*pixelformat*/ ,
int nColBuffers ,
int nAuxBuffers )
2016-02-03 21:21:30 +00:00
{
2017-01-28 19:27:50 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " color_format: %d, origin_location: %d, nColBuffers: %d, nAuxBuffers: %d " , color_format , origin_location , nColBuffers , nAuxBuffers ) ;
return grSstWinOpen ( color_format , origin_location , nColBuffers , nAuxBuffers ) ;
2013-04-10 07:08:48 +00:00
}
2016-03-08 21:55:19 +00:00
# ifdef _WIN32
2013-04-10 07:08:48 +00:00
# include <fcntl.h>
# ifndef ATTACH_PARENT_PROCESS
# define ATTACH_PARENT_PROCESS ((FxU32)-1)
# endif
2017-01-28 11:29:03 +00:00
extern HWND g_hwnd_win ;
2013-04-10 07:08:48 +00:00
# endif
FX_ENTRY GrContext_t FX_CALL
grSstWinOpen (
2017-04-18 11:32:43 +00:00
GrColorFormat_t color_format ,
GrOriginLocation_t origin_location ,
int nColBuffers ,
int nAuxBuffers )
2016-02-03 21:21:30 +00:00
{
static int show_warning = 1 ;
// ZIGGY
// allocate static texture names
// the initial value should be big enough to support the maximal resolution
free_texture = 32 * 2048 * 2048 ;
default_texture = free_texture + + ;
color_texture = free_texture + + ;
depth_texture = free_texture + + ;
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
PIXELFORMATDESCRIPTOR pfd ;
memset ( & pfd , 0 , sizeof ( PIXELFORMATDESCRIPTOR ) ) ;
pfd . nSize = sizeof ( PIXELFORMATDESCRIPTOR ) ;
pfd . nVersion = 1 ;
pfd . dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER ;
pfd . iPixelType = PFD_TYPE_RGBA ;
pfd . iLayerType = PFD_MAIN_PLANE ;
pfd . cColorBits = 32 ;
pfd . cDepthBits = 24 ;
pfd . cAuxBuffers = 1 ;
int pfm ;
2016-03-28 19:57:13 +00:00
# else
fputs ( " ERROR: No GLX yet to start GL on [Free]BSD, Linux etc. \n " , stderr ) ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2017-01-28 19:27:50 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " color_format: %d, origin_location: %d, nColBuffers: %d, nAuxBuffers: %d " , color_format , origin_location , nColBuffers , nAuxBuffers ) ;
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-03-10 17:21:56 +00:00
TMU_SIZE = ( config . vram_size - g_width * g_height * 4 * 3 ) / 2 ;
2016-02-03 21:21:30 +00:00
// save screen resolution for hwfbe, after resolution enumeration
2016-03-10 17:21:56 +00:00
screen_width = g_width ;
screen_height = g_height ;
2016-02-03 21:21:30 +00:00
2017-01-28 11:29:03 +00:00
if ( ( hDC = GetDC ( g_hwnd_win ) ) = = NULL )
2016-02-03 21:21:30 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " GetDC on main window failed " ) ;
2016-02-03 21:21:30 +00:00
return FXFALSE ;
}
if ( ( pfm = ChoosePixelFormat ( hDC , & pfd ) ) = = 0 ) {
//printf("disabling auxiliary buffers\n");
pfd . cAuxBuffers = 0 ;
pfm = ChoosePixelFormat ( hDC , & pfd ) ;
}
if ( pfm = = 0 )
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " ChoosePixelFormat failed " ) ;
2016-02-03 21:21:30 +00:00
return FXFALSE ;
}
if ( SetPixelFormat ( hDC , pfm , & pfd ) = = 0 )
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " SetPixelFormat failed " ) ;
2016-02-03 21:21:30 +00:00
return FXFALSE ;
}
if ( ( hGLRC = wglCreateContext ( hDC ) ) = = 0 )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " wglCreateContext failed! " ) ;
2016-02-03 21:21:30 +00:00
grSstWinClose ( 0 ) ;
return FXFALSE ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
HGLRC CurrenthGLRC = wglGetCurrentContext ( ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( CurrenthGLRC = = NULL | | CurrenthGLRC = = hGLRC )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
if ( ! wglMakeCurrent ( hDC , hGLRC ) )
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " wglMakeCurrent failed! " ) ;
2016-02-03 21:21:30 +00:00
grSstWinClose ( 0 ) ;
return FXFALSE ;
}
}
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2016-02-03 21:21:30 +00:00
lfb_color_fmt = color_format ;
2016-02-14 08:59:33 +00:00
if ( origin_location ! = GR_ORIGIN_UPPER_LEFT ) WriteTrace ( TraceGlitch , TraceWarning , " origin must be in upper left corner " ) ;
if ( nColBuffers ! = 2 ) WriteTrace ( TraceGlitch , TraceWarning , " number of color buffer is not 2 " ) ;
if ( nAuxBuffers ! = 1 ) WriteTrace ( TraceGlitch , TraceWarning , " number of auxiliary buffer is not 1 " ) ;
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_ARB_texture_env_combine " ) = = 0 & &
isExtensionSupported ( " GL_EXT_texture_env_combine " ) = = 0 & &
show_warning )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " Your video card doesn't support GL_ARB_texture_env_combine extension " ) ;
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_ARB_multitexture " ) = = 0 & & show_warning )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " Your video card doesn't support GL_ARB_multitexture extension " ) ;
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_ARB_texture_mirrored_repeat " ) = = 0 & & show_warning )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " Your video card doesn't support GL_ARB_texture_mirrored_repeat extension " ) ;
2016-02-03 21:21:30 +00:00
show_warning = 0 ;
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
glActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) wglGetProcAddress ( " glActiveTextureARB " ) ;
glMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) wglGetProcAddress ( " glMultiTexCoord2fARB " ) ;
2015-03-04 20:11:35 +00:00
2016-02-03 21:21:30 +00:00
if ( glActiveTextureARB = = NULL )
glActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) dummy_glActiveTexture ;
if ( glMultiTexCoord2fARB = = NULL )
glMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) dummy_glMultiTexCoord2f ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2016-02-03 21:21:30 +00:00
nbTextureUnits = 0 ;
glGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & nbTextureUnits ) ;
2016-02-14 08:59:33 +00:00
if ( nbTextureUnits = = 1 ) WriteTrace ( TraceGlitch , TraceWarning , " You need a video card that has at least 2 texture units " ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
nbAuxBuffers = 0 ;
glGetIntegerv ( GL_AUX_BUFFERS , & nbAuxBuffers ) ;
if ( nbAuxBuffers > 0 )
printf ( " Congratulations, you have %d auxilliary buffers, we'll use them wisely ! \n " , nbAuxBuffers ) ;
2013-04-10 07:08:48 +00:00
# ifdef VOODOO1
2016-02-03 21:21:30 +00:00
nbTextureUnits = 2 ;
2013-04-10 07:08:48 +00:00
# endif
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_EXT_blend_func_separate " ) = = 0 )
blend_func_separate_support = 0 ;
else
blend_func_separate_support = 1 ;
if ( isExtensionSupported ( " GL_EXT_packed_pixels " ) = = 0 )
packed_pixels_support = 0 ;
else {
printf ( " packed pixels extension used \n " ) ;
packed_pixels_support = 1 ;
}
if ( isExtensionSupported ( " GL_ARB_texture_non_power_of_two " ) = = 0 )
npot_support = 0 ;
else {
printf ( " NPOT extension used \n " ) ;
npot_support = 1 ;
}
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
glBlendFuncSeparateEXT = ( PFNGLBLENDFUNCSEPARATEEXTPROC ) wglGetProcAddress ( " glBlendFuncSeparateEXT " ) ;
if ( glBlendFuncSeparateEXT = = NULL )
glBlendFuncSeparateEXT = ( PFNGLBLENDFUNCSEPARATEEXTPROC ) dummy_glBlendFuncSeparate ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_EXT_fog_coord " ) = = 0 )
fog_coord_support = 0 ;
else
fog_coord_support = 1 ;
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
glFogCoordfEXT = ( PFNGLFOGCOORDFPROC ) wglGetProcAddress ( " glFogCoordfEXT " ) ;
if ( glFogCoordfEXT = = NULL )
glFogCoordfEXT = ( PFNGLFOGCOORDFPROC ) dummy_glFogCoordf ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
wglGetExtensionsStringARB = ( PFNWGLGETEXTENSIONSSTRINGARBPROC ) wglGetProcAddress ( " wglGetExtensionsStringARB " ) ;
if ( wglGetExtensionsStringARB = = NULL )
wglGetExtensionsStringARB = ( PFNWGLGETEXTENSIONSSTRINGARBPROC ) dummy_wglGetExtensionsString ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
glBindFramebufferEXT = ( PFNGLBINDFRAMEBUFFEREXTPROC ) wglGetProcAddress ( " glBindFramebufferEXT " ) ;
glFramebufferTexture2DEXT = ( PFNGLFRAMEBUFFERTEXTURE2DEXTPROC ) wglGetProcAddress ( " glFramebufferTexture2DEXT " ) ;
glGenFramebuffersEXT = ( PFNGLGENFRAMEBUFFERSEXTPROC ) wglGetProcAddress ( " glGenFramebuffersEXT " ) ;
glCheckFramebufferStatusEXT = ( PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC ) wglGetProcAddress ( " glCheckFramebufferStatusEXT " ) ;
glDeleteFramebuffersEXT = ( PFNGLDELETEFRAMEBUFFERSEXTPROC ) wglGetProcAddress ( " glDeleteFramebuffersEXT " ) ;
if ( glBindFramebufferEXT = = NULL )
glBindFramebufferEXT = ( PFNGLBINDFRAMEBUFFEREXTPROC ) dummy_glBindFramebuffer ;
if ( glFramebufferTexture2DEXT = = NULL )
glFramebufferTexture2DEXT = ( PFNGLFRAMEBUFFERTEXTURE2DEXTPROC ) dummy_glFramebufferTexture2D ;
if ( glGenFramebuffersEXT = = NULL )
glGenFramebuffersEXT = ( PFNGLGENFRAMEBUFFERSEXTPROC ) dummy_glGenFramebuffers ;
if ( glCheckFramebufferStatusEXT = = NULL )
glCheckFramebufferStatusEXT = ( PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC ) dummy_glCheckFramebufferStatus ;
if ( glDeleteFramebuffersEXT = = NULL )
glDeleteFramebuffersEXT = ( PFNGLDELETEFRAMEBUFFERSEXTPROC ) dummy_glDeleteFramebuffers ;
glBindRenderbufferEXT = ( PFNGLBINDRENDERBUFFEREXTPROC ) wglGetProcAddress ( " glBindRenderbufferEXT " ) ;
glDeleteRenderbuffersEXT = ( PFNGLDELETERENDERBUFFERSEXTPROC ) wglGetProcAddress ( " glDeleteRenderbuffersEXT " ) ;
glGenRenderbuffersEXT = ( PFNGLGENRENDERBUFFERSEXTPROC ) wglGetProcAddress ( " glGenRenderbuffersEXT " ) ;
glRenderbufferStorageEXT = ( PFNGLRENDERBUFFERSTORAGEEXTPROC ) wglGetProcAddress ( " glRenderbufferStorageEXT " ) ;
glFramebufferRenderbufferEXT = ( PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC ) wglGetProcAddress ( " glFramebufferRenderbufferEXT " ) ;
if ( glBindRenderbufferEXT = = NULL )
glBindRenderbufferEXT = ( PFNGLBINDRENDERBUFFEREXTPROC ) dummy_glBindRenderbuffer ;
if ( glDeleteRenderbuffersEXT = = NULL )
glDeleteRenderbuffersEXT = ( PFNGLDELETERENDERBUFFERSEXTPROC ) dummy_glDeleteRenderbuffers ;
if ( glGenRenderbuffersEXT = = NULL )
glGenRenderbuffersEXT = ( PFNGLGENRENDERBUFFERSEXTPROC ) dummy_glGenRenderbuffers ;
if ( glRenderbufferStorageEXT = = NULL )
glRenderbufferStorageEXT = ( PFNGLRENDERBUFFERSTORAGEEXTPROC ) dummy_glRenderbufferStorage ;
if ( glFramebufferRenderbufferEXT = = NULL )
glFramebufferRenderbufferEXT = ( PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC ) dummy_glFramebufferRenderbuffer ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2016-02-03 21:21:30 +00:00
use_fbo = config . fbo & & glFramebufferRenderbufferEXT ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
printf ( " use_fbo %d \n " , use_fbo ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_ARB_shading_language_100 " ) & &
isExtensionSupported ( " GL_ARB_shader_objects " ) & &
isExtensionSupported ( " GL_ARB_fragment_shader " ) & &
isExtensionSupported ( " GL_ARB_vertex_shader " ) )
{
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
glCreateShaderObjectARB = ( PFNGLCREATESHADEROBJECTARBPROC ) wglGetProcAddress ( " glCreateShaderObjectARB " ) ;
glShaderSourceARB = ( PFNGLSHADERSOURCEARBPROC ) wglGetProcAddress ( " glShaderSourceARB " ) ;
glCompileShaderARB = ( PFNGLCOMPILESHADERARBPROC ) wglGetProcAddress ( " glCompileShaderARB " ) ;
glCreateProgramObjectARB = ( PFNGLCREATEPROGRAMOBJECTARBPROC ) wglGetProcAddress ( " glCreateProgramObjectARB " ) ;
glAttachObjectARB = ( PFNGLATTACHOBJECTARBPROC ) wglGetProcAddress ( " glAttachObjectARB " ) ;
glLinkProgramARB = ( PFNGLLINKPROGRAMARBPROC ) wglGetProcAddress ( " glLinkProgramARB " ) ;
glUseProgramObjectARB = ( PFNGLUSEPROGRAMOBJECTARBPROC ) wglGetProcAddress ( " glUseProgramObjectARB " ) ;
glGetUniformLocationARB = ( PFNGLGETUNIFORMLOCATIONARBPROC ) wglGetProcAddress ( " glGetUniformLocationARB " ) ;
glUniform1iARB = ( PFNGLUNIFORM1IARBPROC ) wglGetProcAddress ( " glUniform1iARB " ) ;
glUniform4iARB = ( PFNGLUNIFORM4IARBPROC ) wglGetProcAddress ( " glUniform4iARB " ) ;
glUniform4fARB = ( PFNGLUNIFORM4FARBPROC ) wglGetProcAddress ( " glUniform4fARB " ) ;
glUniform1fARB = ( PFNGLUNIFORM1FARBPROC ) wglGetProcAddress ( " glUniform1fARB " ) ;
glDeleteObjectARB = ( PFNGLDELETEOBJECTARBPROC ) wglGetProcAddress ( " glDeleteObjectARB " ) ;
glGetInfoLogARB = ( PFNGLGETINFOLOGARBPROC ) wglGetProcAddress ( " glGetInfoLogARB " ) ;
glGetObjectParameterivARB = ( PFNGLGETOBJECTPARAMETERIVARBPROC ) wglGetProcAddress ( " glGetObjectParameterivARB " ) ;
glSecondaryColor3f = ( PFNGLSECONDARYCOLOR3FPROC ) wglGetProcAddress ( " glSecondaryColor3f " ) ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2016-02-03 21:21:30 +00:00
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_EXT_texture_compression_s3tc " ) = = 0 & & show_warning )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " Your video card doesn't support GL_EXT_texture_compression_s3tc extension " ) ;
2016-02-03 21:21:30 +00:00
if ( isExtensionSupported ( " GL_3DFX_texture_compression_FXT1 " ) = = 0 & & show_warning )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " Your video card doesn't support GL_3DFX_texture_compression_FXT1 extension " ) ;
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
glCompressedTexImage2DARB = ( PFNGLCOMPRESSEDTEXIMAGE2DPROC ) wglGetProcAddress ( " glCompressedTexImage2DARB " ) ;
if ( glCreateShaderObjectARB = = NULL )
glCreateShaderObjectARB = ( PFNGLCREATESHADEROBJECTARBPROC ) dummy_glCreateShader ;
if ( glShaderSourceARB = = NULL )
glShaderSourceARB = ( PFNGLSHADERSOURCEARBPROC ) dummy_glShaderSource ;
if ( glCompileShaderARB = = NULL )
glCompileShaderARB = ( PFNGLCOMPILESHADERARBPROC ) dummy_glCompileShader ;
if ( glCreateProgramObjectARB = = NULL )
glCreateProgramObjectARB = ( PFNGLCREATEPROGRAMOBJECTARBPROC ) dummy_glCreateProgram ;
if ( glAttachObjectARB = = NULL )
glAttachObjectARB = ( PFNGLATTACHOBJECTARBPROC ) dummy_glAttachObject ;
if ( glLinkProgramARB = = NULL )
glLinkProgramARB = ( PFNGLLINKPROGRAMARBPROC ) dummy_glLinkProgram ;
if ( glUseProgramObjectARB = = NULL )
glUseProgramObjectARB = ( PFNGLUSEPROGRAMOBJECTARBPROC ) dummy_glUseProgram ;
if ( glGetUniformLocationARB = = NULL )
glGetUniformLocationARB = ( PFNGLGETUNIFORMLOCATIONARBPROC ) dummy_glGetUniformLocation ;
if ( glUniform1iARB = = NULL )
glUniform1iARB = ( PFNGLUNIFORM1IARBPROC ) dummy_glUniform1i ;
if ( glUniform4iARB = = NULL )
glUniform4iARB = ( PFNGLUNIFORM4IARBPROC ) dummy_glUniform4i ;
if ( glUniform4fARB = = NULL )
glUniform4fARB = ( PFNGLUNIFORM4FARBPROC ) dummy_glUniform4f ;
if ( glUniform1fARB = = NULL )
glUniform1fARB = ( PFNGLUNIFORM1FARBPROC ) dummy_glUniform1f ;
if ( glDeleteObjectARB = = NULL )
glDeleteObjectARB = ( PFNGLDELETEOBJECTARBPROC ) dummy_glDeleteObject ;
if ( glGetInfoLogARB = = NULL )
glGetInfoLogARB = ( PFNGLGETINFOLOGARBPROC ) dummy_glGetInfoLog ;
if ( glGetObjectParameterivARB = = NULL )
glGetObjectParameterivARB = ( PFNGLGETOBJECTPARAMETERIVARBPROC ) dummy_glGetObjectParameteriv ;
if ( glSecondaryColor3f = = NULL )
glSecondaryColor3f = ( PFNGLSECONDARYCOLOR3FPROC ) dummy_glSecondaryColor3f ;
if ( glCompressedTexImage2DARB = = NULL )
glCompressedTexImage2DARB = ( PFNGLCOMPRESSEDTEXIMAGE2DPROC ) dummy_glCompressedTexImage2D ;
2013-04-10 07:08:48 +00:00
# endif
2016-03-27 21:09:52 +00:00
# ifndef ANDROID
2017-03-13 09:34:51 +00:00
glViewport ( 0 , g_viewport_offset , g_width , g_height ) ;
2016-03-10 17:21:56 +00:00
viewport_width = g_width ;
viewport_height = g_height ;
2016-02-03 21:21:30 +00:00
nvidia_viewport_hack = 1 ;
2013-04-10 07:08:48 +00:00
# else
2017-03-13 09:34:51 +00:00
glViewport ( 0 , g_viewport_offset , width , height ) ;
2016-02-03 21:21:30 +00:00
viewport_width = width ;
viewport_height = height ;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2016-02-03 21:21:30 +00:00
// void do_benchmarks();
// do_benchmarks();
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
// VP try to resolve z precision issues
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ;
glTranslatef ( 0 , 0 , 1 - zscale ) ;
glScalef ( 1 , 1 , zscale ) ;
2013-04-10 07:08:48 +00:00
2016-03-10 17:21:56 +00:00
widtho = g_width / 2 ;
heighto = g_height / 2 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
pBufferWidth = pBufferHeight = - 1 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
current_buffer = GL_BACK ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
texture_unit = GL_TEXTURE0_ARB ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
{
int i ;
for ( i = 0 ; i < NB_TEXBUFS ; i + + )
texbufs [ i ] . start = texbufs [ i ] . end = 0xffffffff ;
}
if ( ! use_fbo & & nbAuxBuffers = = 0 ) {
// create the framebuffer saving texture
2016-03-10 17:21:56 +00:00
int w = g_width , h = g_height ;
2016-02-03 21:21:30 +00:00
glBindTexture ( GL_TEXTURE_2D , color_texture ) ;
if ( ! npot_support ) {
w = h = 1 ;
2016-03-10 17:21:56 +00:00
while ( w < g_width ) w * = 2 ;
while ( h < g_height ) h * = 2 ;
2016-02-03 21:21:30 +00:00
}
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGB , w , h , 0 , GL_RGB , GL_UNSIGNED_BYTE , 0 ) ;
glBindTexture ( GL_TEXTURE_2D , 0 ) ;
save_w = save_h = 0 ;
}
void FindBestDepthBias ( ) ;
FindBestDepthBias ( ) ;
init_geometry ( ) ;
init_textures ( ) ;
init_combiner ( ) ;
// Aniso filter check
if ( config . anisofilter > 0 )
glGetFloatv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & largest_supported_anisotropy ) ;
// ATI hack - certain texture formats are slow on ATI?
// Hmm, perhaps the internal format need to be specified explicitly...
{
GLint ifmt ;
glTexImage2D ( GL_PROXY_TEXTURE_2D , 0 , GL_RGBA , 16 , 16 , 0 , GL_BGRA , GL_UNSIGNED_SHORT_1_5_5_5_REV , NULL ) ;
glGetTexLevelParameteriv ( GL_PROXY_TEXTURE_2D , 0 , GL_TEXTURE_INTERNAL_FORMAT , & ifmt ) ;
if ( ifmt ! = GL_RGB5_A1 ) {
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " ATI SUCKS %x \n " , ifmt ) ;
2016-02-03 21:21:30 +00:00
ati_sucks = 1 ;
}
else
ati_sucks = 0 ;
}
grDisplayGLError ( " grSstWinOpen " ) ;
return 1 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grGlideShutdown ( void )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY FxBool FX_CALL
2016-02-03 21:21:30 +00:00
grSstWinClose ( GrContext_t context )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
int i ;
2013-04-15 03:51:39 +00:00
# ifndef WIN32
2016-02-03 21:21:30 +00:00
int clear_texbuff = use_fbo ;
2013-04-15 03:51:39 +00:00
# endif
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " context: %d " , context ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
for ( i = 0 ; i < 2 ; i + + ) {
tmu_usage [ i ] . min = 0x0FFFFFFFul ;
tmu_usage [ i ] . max = 0x00000000ul ;
invtex [ i ] = 0 ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
free_combiners ( ) ;
2013-04-10 07:08:48 +00:00
# ifndef WIN32
2016-02-03 21:21:30 +00:00
try // I don't know why, but opengl can be killed before this function call when emulator is closed (Gonetz).
// 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.
{
if ( use_fbo & & glBindFramebufferEXT )
2016-03-10 17:21:56 +00:00
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , 0 ) ;
2016-02-03 21:21:30 +00:00
}
catch ( . . . )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
clear_texbuff = 0 ;
}
if ( clear_texbuff )
{
2016-02-14 08:59:33 +00:00
for ( i = 0 ; i < nb_fb ; i + + )
2016-02-03 21:21:30 +00:00
{
2016-03-10 17:21:56 +00:00
glDeleteTextures ( 1 , & ( fbs [ i ] . texid ) ) ;
2016-02-04 10:22:19 +00:00
glDeleteFramebuffersEXT ( 1 , & ( fbs [ i ] . fbid ) ) ;
glDeleteRenderbuffersEXT ( 1 , & ( fbs [ i ] . zbid ) ) ;
2016-02-03 21:21:30 +00:00
}
2013-04-10 07:08:48 +00:00
}
# endif
2016-02-03 21:21:30 +00:00
nb_fb = 0 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
free_textures ( ) ;
2013-04-10 07:08:48 +00:00
# ifndef WIN32
2016-02-03 21:21:30 +00:00
// ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
remove_tex ( 0 , 0xfffffff ) ;
2013-04-10 07:08:48 +00:00
# endif
2016-02-03 21:21:30 +00:00
//*/
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
if ( hGLRC )
{
wglMakeCurrent ( hDC , NULL ) ;
wglDeleteContext ( hGLRC ) ;
hGLRC = NULL ;
2016-03-03 10:10:30 +00:00
}
2017-01-28 11:29:03 +00:00
ExitFullScreen ( ) ;
2013-04-10 07:08:48 +00:00
# else
2016-02-03 21:21:30 +00:00
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
//sleep(2);
2016-03-28 19:53:47 +00:00
//m_pScreen = NULL;
2013-04-10 07:08:48 +00:00
# endif
2016-02-03 21:21:30 +00:00
return FXTRUE ;
2016-03-03 10:10:30 +00:00
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
FX_ENTRY void FX_CALL grTextureBufferExt ( GrChipID_t tmu ,
FxU32 startAddress ,
GrLOD_t lodmin ,
GrLOD_t lodmax ,
GrAspectRatio_t aspect ,
GrTextureFormat_t fmt ,
FxU32 evenOdd )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
int i ;
static int fbs_init = 0 ;
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " tmu: %d startAddress: %d lodmin: %d lodmax: %d aspect: %d fmt: %d evenOdd: %d " , tmu , startAddress , lodmin , lodmax , aspect , fmt , evenOdd ) ;
2016-02-14 08:59:33 +00:00
if ( lodmin ! = lodmax ) WriteTrace ( TraceGlitch , TraceWarning , " grTextureBufferExt : loading more than one LOD " ) ;
2016-02-03 21:21:30 +00:00
if ( ! use_fbo ) {
if ( ! render_to_texture ) { //initialization
return ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
render_to_texture = 2 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( aspect < 0 )
{
pBufferHeight = 1 < < lodmin ;
pBufferWidth = pBufferHeight > > - aspect ;
}
else
{
pBufferWidth = 1 < < lodmin ;
pBufferHeight = pBufferWidth > > aspect ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( curBufferAddr & & startAddress + 1 ! = curBufferAddr )
updateTexture ( ) ;
2013-04-10 07:08:48 +00:00
# ifdef SAVE_CBUFFER
2016-02-03 21:21:30 +00:00
//printf("saving %dx%d\n", pBufferWidth, pBufferHeight);
// save color buffer
if ( nbAuxBuffers > 0 ) {
glDrawBuffer ( GL_AUX0 ) ;
current_buffer = GL_AUX0 ;
}
else {
int tw , th ;
if ( pBufferWidth < screen_width )
tw = pBufferWidth ;
else
tw = screen_width ;
if ( pBufferHeight < screen_height )
th = pBufferHeight ;
else
th = screen_height ;
glReadBuffer ( GL_BACK ) ;
glActiveTextureARB ( texture_unit ) ;
glBindTexture ( GL_TEXTURE_2D , color_texture ) ;
// save incrementally the framebuffer
if ( save_w ) {
if ( tw > save_w & & th > save_h ) {
glCopyTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , save_h ,
2017-03-13 09:34:51 +00:00
0 , g_viewport_offset + save_h , tw , th - save_h ) ;
2016-02-03 21:21:30 +00:00
glCopyTexSubImage2D ( GL_TEXTURE_2D , 0 , save_w , 0 ,
2017-03-13 09:34:51 +00:00
save_w , g_viewport_offset , tw - save_w , save_h ) ;
2016-02-03 21:21:30 +00:00
save_w = tw ;
save_h = th ;
}
else if ( tw > save_w ) {
glCopyTexSubImage2D ( GL_TEXTURE_2D , 0 , save_w , 0 ,
2017-03-13 09:34:51 +00:00
save_w , g_viewport_offset , tw - save_w , save_h ) ;
2016-02-03 21:21:30 +00:00
save_w = tw ;
}
else if ( th > save_h ) {
glCopyTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , save_h ,
2017-03-13 09:34:51 +00:00
0 , g_viewport_offset + save_h , save_w , th - save_h ) ;
2016-02-03 21:21:30 +00:00
save_h = th ;
}
}
else {
glCopyTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , 0 ,
2017-03-13 09:34:51 +00:00
0 , g_viewport_offset , tw , th ) ;
2016-02-03 21:21:30 +00:00
save_w = tw ;
save_h = th ;
}
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
2013-04-10 07:08:48 +00:00
}
# endif
2016-02-03 21:21:30 +00:00
if ( startAddress + 1 ! = curBufferAddr | |
( curBufferAddr = = 0L & & nbAuxBuffers = = 0 ) )
buffer_cleared = 0 ;
curBufferAddr = pBufferAddress = startAddress + 1 ;
pBufferFmt = fmt ;
int rtmu = startAddress < grTexMinAddress ( GR_TMU1 ) ? 0 : 1 ;
int size = pBufferWidth * pBufferHeight * 2 ; //grTexFormatSize(fmt);
if ( tmu_usage [ rtmu ] . min > pBufferAddress + 0 )
tmu_usage [ rtmu ] . min = pBufferAddress + 0 ;
if ( tmu_usage [ rtmu ] . max < pBufferAddress + size )
tmu_usage [ rtmu ] . max = pBufferAddress + size ;
// printf("tmu %d usage now %gMb - %gMb\n",
// rtmu, tmu_usage[rtmu].min/1024.0f, tmu_usage[rtmu].max/1024.0f);
2016-03-10 17:21:56 +00:00
g_width = pBufferWidth ;
g_height = pBufferHeight ;
2016-02-03 21:21:30 +00:00
2016-03-10 17:21:56 +00:00
widtho = g_width / 2 ;
heighto = g_height / 2 ;
2016-02-03 21:21:30 +00:00
// this could be improved, but might be enough as long as the set of
// texture buffer addresses stay small
for ( i = ( texbuf_i - 1 ) & ( NB_TEXBUFS - 1 ) ; i ! = texbuf_i ; i = ( i - 1 ) & ( NB_TEXBUFS - 1 ) )
if ( texbufs [ i ] . start = = pBufferAddress )
break ;
texbufs [ i ] . start = pBufferAddress ;
texbufs [ i ] . end = pBufferAddress + size ;
texbufs [ i ] . fmt = fmt ;
if ( i = = texbuf_i )
texbuf_i = ( texbuf_i + 1 ) & ( NB_TEXBUFS - 1 ) ;
//printf("texbuf %x fmt %x\n", pBufferAddress, fmt);
// ZIGGY it speeds things up to not delete the buffers
// a better thing would be to delete them *sometimes*
// remove_tex(pBufferAddress+1, pBufferAddress + size);
add_tex ( pBufferAddress ) ;
//printf("viewport %dx%d\n", width, height);
2016-03-10 17:21:56 +00:00
if ( g_height > screen_height ) {
2017-03-13 09:34:51 +00:00
glViewport ( 0 , g_viewport_offset + screen_height - g_height , g_width , g_height ) ;
2016-02-03 21:21:30 +00:00
}
else
2017-03-13 09:34:51 +00:00
glViewport ( 0 , g_viewport_offset , g_width , g_height ) ;
2016-02-03 21:21:30 +00:00
2017-03-13 09:34:51 +00:00
glScissor ( 0 , g_viewport_offset , g_width , g_height ) ;
2016-02-03 21:21:30 +00:00
grDisplayGLError ( " grTextureBufferExt :: A " ) ;
}
else {
if ( ! render_to_texture ) //initialization
{
if ( ! fbs_init )
{
for ( i = 0 ; i < 100 ; i + + ) fbs [ i ] . address = 0 ;
fbs_init = 1 ;
nb_fb = 0 ;
}
return ; //no need to allocate FBO if render buffer is not texture buffer
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
render_to_texture = 2 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( aspect < 0 )
{
pBufferHeight = 1 < < lodmin ;
pBufferWidth = pBufferHeight > > - aspect ;
}
else
{
pBufferWidth = 1 < < lodmin ;
pBufferHeight = pBufferWidth > > aspect ;
}
pBufferAddress = startAddress + 1 ;
2013-04-10 07:08:48 +00:00
2016-03-10 17:21:56 +00:00
g_width = pBufferWidth ;
g_height = pBufferHeight ;
2013-04-10 07:08:48 +00:00
2016-03-10 17:21:56 +00:00
widtho = g_width / 2 ;
heighto = g_height / 2 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
for ( i = 0 ; i < nb_fb ; i + + )
{
if ( fbs [ i ] . address = = pBufferAddress )
{
2016-03-10 17:21:56 +00:00
if ( fbs [ i ] . width = = g_width & & fbs [ i ] . height = = g_height ) //select already allocated FBO
2016-02-03 21:21:30 +00:00
{
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , 0 ) ;
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , fbs [ i ] . fbid ) ;
glFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D , fbs [ i ] . texid , 0 ) ;
glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , fbs [ i ] . zbid ) ;
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , fbs [ i ] . zbid ) ;
2016-03-10 17:21:56 +00:00
glViewport ( 0 , 0 , g_width , g_height ) ;
glScissor ( 0 , 0 , g_width , g_height ) ;
2016-02-03 21:21:30 +00:00
if ( fbs [ i ] . buff_clear )
{
glDepthMask ( 1 ) ;
glClear ( GL_DEPTH_BUFFER_BIT ) ; //clear z-buffer only. we may need content, stored in the frame buffer
fbs [ i ] . buff_clear = 0 ;
}
CHECK_FRAMEBUFFER_STATUS ( ) ;
curBufferAddr = pBufferAddress ;
grDisplayGLError ( " grTextureBufferExt :: C " ) ;
return ;
}
else //create new FBO at the same address, delete old one
{
glDeleteFramebuffersEXT ( 1 , & ( fbs [ i ] . fbid ) ) ;
glDeleteRenderbuffersEXT ( 1 , & ( fbs [ i ] . zbid ) ) ;
if ( nb_fb > 1 )
memmove ( & ( fbs [ i ] ) , & ( fbs [ i + 1 ] ) , sizeof ( fb ) * ( nb_fb - i ) ) ;
nb_fb - - ;
break ;
}
}
}
2013-04-10 07:08:48 +00:00
2016-03-10 17:21:56 +00:00
remove_tex ( pBufferAddress , pBufferAddress + g_width * g_height * 2 /*grTexFormatSize(fmt)*/ ) ;
2016-02-03 21:21:30 +00:00
//create new FBO
glGenFramebuffersEXT ( 1 , & ( fbs [ nb_fb ] . fbid ) ) ;
glGenRenderbuffersEXT ( 1 , & ( fbs [ nb_fb ] . zbid ) ) ;
glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , fbs [ nb_fb ] . zbid ) ;
2016-03-10 17:21:56 +00:00
glRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT , GL_DEPTH_COMPONENT , g_width , g_height ) ;
2016-02-03 21:21:30 +00:00
fbs [ nb_fb ] . address = pBufferAddress ;
2016-03-10 17:21:56 +00:00
fbs [ nb_fb ] . width = g_width ;
fbs [ nb_fb ] . height = g_height ;
2016-02-03 21:21:30 +00:00
fbs [ nb_fb ] . texid = pBufferAddress ;
fbs [ nb_fb ] . buff_clear = 0 ;
add_tex ( fbs [ nb_fb ] . texid ) ;
glBindTexture ( GL_TEXTURE_2D , fbs [ nb_fb ] . texid ) ;
2016-03-10 17:21:56 +00:00
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGB , g_width , g_height , 0 ,
2016-02-03 21:21:30 +00:00
GL_RGB , GL_UNSIGNED_BYTE , NULL ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , fbs [ nb_fb ] . fbid ) ;
glFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT ,
GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D , fbs [ nb_fb ] . texid , 0 ) ;
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , fbs [ nb_fb ] . zbid ) ;
2016-03-10 17:21:56 +00:00
glViewport ( 0 , 0 , g_width , g_height ) ;
glScissor ( 0 , 0 , g_width , g_height ) ;
2016-02-03 21:21:30 +00:00
glClearColor ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
glDepthMask ( 1 ) ;
glClear ( GL_DEPTH_BUFFER_BIT ) ;
CHECK_FRAMEBUFFER_STATUS ( ) ;
curBufferAddr = pBufferAddress ;
nb_fb + + ;
grDisplayGLError ( " grTextureBufferExt :: B " ) ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
int CheckTextureBufferFormat ( GrChipID_t tmu , FxU32 startAddress , GrTexInfo * info )
{
int found , i ;
if ( ! use_fbo ) {
for ( found = i = 0 ; i < 2 ; i + + )
if ( tmu_usage [ i ] . min < = startAddress & & tmu_usage [ i ] . max > startAddress ) {
//printf("tmu %d == framebuffer %x\n", tmu, startAddress);
found = 1 ;
break ;
}
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
else {
found = i = 0 ;
while ( i < nb_fb )
{
unsigned int end = fbs [ i ] . address + fbs [ i ] . width * fbs [ i ] . height * 2 ;
if ( startAddress > = fbs [ i ] . address & & startAddress < end )
{
found = 1 ;
break ;
}
i + + ;
}
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
if ( ! use_fbo & & found ) {
int tw , th , rh , cw , ch ;
if ( info - > aspectRatioLog2 < 0 )
{
th = 1 < < info - > largeLodLog2 ;
tw = th > > - info - > aspectRatioLog2 ;
}
else
{
tw = 1 < < info - > largeLodLog2 ;
th = tw > > info - > aspectRatioLog2 ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( info - > aspectRatioLog2 < 0 )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
ch = 256 ;
cw = ch > > - info - > aspectRatioLog2 ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
else
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
cw = 256 ;
ch = cw > > info - > aspectRatioLog2 ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
if ( use_fbo | | th < screen_height )
rh = th ;
else
rh = screen_height ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
//printf("th %d rh %d ch %d\n", th, rh, ch);
invtex [ tmu ] = 1.0f - ( th - rh ) / ( float ) th ;
2013-04-10 07:08:48 +00:00
}
else
2016-02-03 21:21:30 +00:00
invtex [ tmu ] = 0 ;
if ( info - > format = = GR_TEXFMT_ALPHA_INTENSITY_88 ) {
if ( ! found ) {
return 0 ;
}
if ( tmu = = 0 )
{
if ( blackandwhite1 ! = found )
{
blackandwhite1 = found ;
need_to_compile = 1 ;
}
}
else
{
if ( blackandwhite0 ! = found )
{
blackandwhite0 = found ;
need_to_compile = 1 ;
}
}
return 1 ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
return 0 ;
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
FX_ENTRY void FX_CALL
grTextureAuxBufferExt ( GrChipID_t tmu ,
2017-04-18 11:32:43 +00:00
FxU32 startAddress ,
GrLOD_t thisLOD ,
GrLOD_t largeLOD ,
GrAspectRatio_t aspectRatio ,
GrTextureFormat_t format ,
FxU32 odd_even_mask )
2016-02-03 21:21:30 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " tmu: %d startAddress: %d thisLOD: %d largeLOD: %d aspectRatio: %d format: %d odd_even_mask: %d " , tmu , startAddress , thisLOD , largeLOD , aspectRatio , format , odd_even_mask ) ;
2016-02-03 21:21:30 +00:00
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
FX_ENTRY void FX_CALL grAuxBufferExt ( GrBuffer_t buffer ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
FX_ENTRY GrProc FX_CALL
grGetProcAddress ( char * procName )
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " procName: %s " , procName ) ;
2016-02-03 21:21:30 +00:00
if ( ! strcmp ( procName , " grSstWinOpenExt " ) )
return ( GrProc ) grSstWinOpenExt ;
if ( ! strcmp ( procName , " grTextureBufferExt " ) )
return ( GrProc ) grTextureBufferExt ;
if ( ! strcmp ( procName , " grChromaRangeExt " ) )
return ( GrProc ) grChromaRangeExt ;
if ( ! strcmp ( procName , " grChromaRangeModeExt " ) )
return ( GrProc ) grChromaRangeModeExt ;
if ( ! strcmp ( procName , " grTexChromaRangeExt " ) )
return ( GrProc ) grTexChromaRangeExt ;
if ( ! strcmp ( procName , " grTexChromaModeExt " ) )
return ( GrProc ) grTexChromaModeExt ;
// ZIGGY framebuffer copy extension
if ( ! strcmp ( procName , " grFramebufferCopyExt " ) )
return ( GrProc ) grFramebufferCopyExt ;
if ( ! strcmp ( procName , " grColorCombineExt " ) )
return ( GrProc ) grColorCombineExt ;
if ( ! strcmp ( procName , " grAlphaCombineExt " ) )
return ( GrProc ) grAlphaCombineExt ;
if ( ! strcmp ( procName , " grTexColorCombineExt " ) )
return ( GrProc ) grTexColorCombineExt ;
if ( ! strcmp ( procName , " grTexAlphaCombineExt " ) )
return ( GrProc ) grTexAlphaCombineExt ;
if ( ! strcmp ( procName , " grConstantColorValueExt " ) )
return ( GrProc ) grConstantColorValueExt ;
if ( ! strcmp ( procName , " grTextureAuxBufferExt " ) )
return ( GrProc ) grTextureAuxBufferExt ;
if ( ! strcmp ( procName , " grAuxBufferExt " ) )
return ( GrProc ) grAuxBufferExt ;
if ( ! strcmp ( procName , " grWrapperFullScreenResolutionExt " ) )
return ( GrProc ) grWrapperFullScreenResolutionExt ;
if ( ! strcmp ( procName , " grConfigWrapperExt " ) )
return ( GrProc ) grConfigWrapperExt ;
if ( ! strcmp ( procName , " grKeyPressedExt " ) )
return ( GrProc ) grKeyPressedExt ;
if ( ! strcmp ( procName , " grQueryResolutionsExt " ) )
return ( GrProc ) grQueryResolutionsExt ;
if ( ! strcmp ( procName , " grGetGammaTableExt " ) )
return ( GrProc ) grGetGammaTableExt ;
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grGetProcAddress : %s " , procName ) ;
2016-02-03 21:21:30 +00:00
return 0 ;
}
2013-04-10 07:08:48 +00:00
FX_ENTRY FxU32 FX_CALL
2016-02-03 21:21:30 +00:00
grGet ( FxU32 pname , FxU32 plength , FxI32 * params )
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " pname: %d plength: %d " , pname , plength ) ;
2016-02-03 21:21:30 +00:00
switch ( pname )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
case GR_MAX_TEXTURE_SIZE :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 2048 ;
return 4 ;
break ;
case GR_NUM_TMU :
if ( plength < 4 | | params = = NULL ) return 0 ;
if ( ! nbTextureUnits )
{
2017-01-28 19:27:50 +00:00
grSstWinOpen ( GR_COLORFORMAT_ARGB , GR_ORIGIN_UPPER_LEFT , 2 , 1 ) ;
2016-02-03 21:21:30 +00:00
grSstWinClose ( 0 ) ;
}
2013-04-10 07:08:48 +00:00
# ifdef VOODOO1
2016-02-03 21:21:30 +00:00
params [ 0 ] = 1 ;
2013-04-10 07:08:48 +00:00
# else
2016-02-03 21:21:30 +00:00
if ( nbTextureUnits > 2 )
params [ 0 ] = 2 ;
else
params [ 0 ] = 1 ;
2013-04-10 07:08:48 +00:00
# endif
2016-02-03 21:21:30 +00:00
return 4 ;
break ;
case GR_NUM_BOARDS :
case GR_NUM_FB :
case GR_REVISION_FB :
case GR_REVISION_TMU :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 1 ;
return 4 ;
break ;
case GR_MEMORY_FB :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 16 * 1024 * 1024 ;
return 4 ;
break ;
case GR_MEMORY_TMU :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 16 * 1024 * 1024 ;
return 4 ;
break ;
case GR_MEMORY_UMA :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 16 * 1024 * 1024 * nbTextureUnits ;
return 4 ;
break ;
case GR_BITS_RGBA :
if ( plength < 16 | | params = = NULL ) return 0 ;
params [ 0 ] = 8 ;
params [ 1 ] = 8 ;
params [ 2 ] = 8 ;
params [ 3 ] = 8 ;
return 16 ;
break ;
case GR_BITS_DEPTH :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 16 ;
return 4 ;
break ;
case GR_BITS_GAMMA :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 8 ;
return 4 ;
break ;
case GR_GAMMA_TABLE_ENTRIES :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 256 ;
return 4 ;
break ;
case GR_FOG_TABLE_ENTRIES :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 64 ;
return 4 ;
break ;
case GR_WDEPTH_MIN_MAX :
if ( plength < 8 | | params = = NULL ) return 0 ;
params [ 0 ] = 0 ;
params [ 1 ] = 65528 ;
return 8 ;
break ;
case GR_ZDEPTH_MIN_MAX :
if ( plength < 8 | | params = = NULL ) return 0 ;
params [ 0 ] = 0 ;
params [ 1 ] = 65535 ;
return 8 ;
break ;
case GR_LFB_PIXEL_PIPE :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = FXFALSE ;
return 4 ;
break ;
case GR_MAX_TEXTURE_ASPECT_RATIO :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 3 ;
return 4 ;
break ;
case GR_NON_POWER_OF_TWO_TEXTURES :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = FXFALSE ;
return 4 ;
break ;
case GR_TEXTURE_ALIGN :
if ( plength < 4 | | params = = NULL ) return 0 ;
params [ 0 ] = 0 ;
return 4 ;
break ;
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " unknown pname in grGet : %x " , pname ) ;
2016-02-03 21:21:30 +00:00
}
return 0 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY const char * FX_CALL
2016-02-03 21:21:30 +00:00
grGetString ( FxU32 pname )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " pname: %d " , pname ) ;
2016-02-03 21:21:30 +00:00
switch ( pname )
{
case GR_EXTENSION :
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
static char extension [ ] = " CHROMARANGE TEXCHROMA TEXMIRROR PALETTE6666 FOGCOORD EVOODOO TEXTUREBUFFER TEXUMA TEXFMT COMBINE GETGAMMA " ;
return extension ;
2013-04-10 07:08:48 +00:00
}
break ;
2016-02-03 21:21:30 +00:00
case GR_HARDWARE :
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
static char hardware [ ] = " Voodoo5 (tm) " ;
return hardware ;
2013-04-10 07:08:48 +00:00
}
break ;
2016-02-03 21:21:30 +00:00
case GR_VENDOR :
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
static char vendor [ ] = " 3Dfx Interactive " ;
return vendor ;
2013-04-10 07:08:48 +00:00
}
break ;
2016-02-03 21:21:30 +00:00
case GR_RENDERER :
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
static char renderer [ ] = " Glide " ;
return renderer ;
2013-04-10 07:08:48 +00:00
}
break ;
2016-02-03 21:21:30 +00:00
case GR_VERSION :
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
static char version [ ] = " 3.0 " ;
return version ;
2013-04-10 07:08:48 +00:00
}
break ;
2016-02-03 21:21:30 +00:00
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " unknown grGetString selector : %x " , pname ) ;
2016-02-03 21:21:30 +00:00
}
return NULL ;
2013-04-10 07:08:48 +00:00
}
static void render_rectangle ( int texture_number ,
2016-02-03 21:21:30 +00:00
int dst_x , int dst_y ,
int src_width , int src_height ,
int tex_width , int tex_height , int invert )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
GLfloat planar_vertices [ 5 ] [ 2 ] ;
2015-03-03 01:46:49 +00:00
2016-02-03 21:21:30 +00:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
2015-03-03 01:46:49 +00:00
2016-03-10 17:21:56 +00:00
planar_vertices [ 0 ] [ 0 ] = ( ( int ) dst_x - widtho ) / ( float ) ( g_width / 2 ) ;
planar_vertices [ 0 ] [ 1 ] = - ( ( int ) dst_y - heighto ) / ( float ) ( g_height / 2 ) * invert ;
planar_vertices [ 1 ] [ 0 ] = ( ( int ) dst_x - widtho ) / ( float ) ( g_width / 2 ) ;
planar_vertices [ 1 ] [ 1 ] = - ( ( int ) dst_y + ( int ) src_height - heighto ) / ( float ) ( g_height / 2 ) * invert ;
planar_vertices [ 2 ] [ 0 ] = ( ( int ) dst_x + ( int ) src_width - widtho ) / ( float ) ( g_width / 2 ) ;
planar_vertices [ 2 ] [ 1 ] = - ( ( int ) dst_y + ( int ) src_height - heighto ) / ( float ) ( g_height / 2 ) * invert ;
planar_vertices [ 3 ] [ 0 ] = ( ( int ) dst_x + ( int ) src_width - widtho ) / ( float ) ( g_width / 2 ) ;
planar_vertices [ 3 ] [ 1 ] = - ( ( int ) dst_y - heighto ) / ( float ) ( g_height / 2 ) * invert ;
planar_vertices [ 4 ] [ 0 ] = ( ( int ) dst_x - widtho ) / ( float ) ( g_width / 2 ) ;
planar_vertices [ 4 ] [ 1 ] = - ( ( int ) dst_y - heighto ) / ( float ) ( g_height / 2 ) * invert ;
2015-03-03 01:51:47 +00:00
2016-02-03 21:21:30 +00:00
glBegin ( GL_QUADS ) ;
2015-03-03 01:46:49 +00:00
2016-02-03 21:21:30 +00:00
glMultiTexCoord2fARB ( texture_number , 0.0f , 0.0f ) ;
glVertex2fv ( planar_vertices [ 0 ] ) ;
2015-03-03 01:46:49 +00:00
2016-02-03 21:21:30 +00:00
glMultiTexCoord2fARB ( texture_number , 0.0f , ( float ) src_height / ( float ) tex_height ) ;
glVertex2fv ( planar_vertices [ 1 ] ) ;
2015-03-03 01:46:49 +00:00
2016-02-03 21:21:30 +00:00
glMultiTexCoord2fARB ( texture_number , ( float ) src_width / ( float ) tex_width , ( float ) src_height / ( float ) tex_height ) ;
glVertex2fv ( planar_vertices [ 2 ] ) ;
2015-03-03 01:46:49 +00:00
2016-02-03 21:21:30 +00:00
glMultiTexCoord2fARB ( texture_number , ( float ) src_width / ( float ) tex_width , 0.0f ) ;
glVertex2fv ( planar_vertices [ 3 ] ) ;
2015-03-03 01:46:49 +00:00
2016-02-03 21:21:30 +00:00
glMultiTexCoord2fARB ( texture_number , 0.0f , 0.0f ) ;
glVertex2fv ( planar_vertices [ 4 ] ) ;
2015-03-03 01:46:49 +00:00
2016-02-03 21:21:30 +00:00
glEnd ( ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
compile_shader ( ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
glEnable ( GL_DEPTH_TEST ) ;
glEnable ( GL_BLEND ) ;
grDisplayGLError ( " render_rectangle " ) ;
2013-04-10 07:08:48 +00:00
}
void reloadTexture ( )
{
2016-02-03 21:21:30 +00:00
if ( use_fbo | | ! render_to_texture | | buffer_cleared )
return ;
2013-04-10 07:08:48 +00:00
2016-03-10 17:21:56 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " width: %d height: %d " , g_width , g_height ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
buffer_cleared = 1 ;
2013-04-10 07:08:48 +00:00
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
glActiveTextureARB ( texture_unit ) ;
glBindTexture ( GL_TEXTURE_2D , pBufferAddress ) ;
2016-02-03 21:21:30 +00:00
glDisable ( GL_ALPHA_TEST ) ;
glDrawBuffer ( current_buffer ) ;
glColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
set_copy_shader ( ) ;
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_CULL_FACE ) ;
int w = 0 , h = 0 ;
2016-03-10 17:21:56 +00:00
if ( g_height > screen_height ) h = screen_height - g_height ;
2016-02-03 21:21:30 +00:00
render_rectangle ( texture_unit ,
- w , - h ,
2016-03-10 17:21:56 +00:00
g_width , g_height ,
g_width , g_height , - 1 ) ;
2013-04-10 07:08:48 +00:00
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
glPopAttrib ( ) ;
2016-02-03 21:21:30 +00:00
grDisplayGLError ( " reloadTexture " ) ;
}
void updateTexture ( )
{
if ( ! use_fbo & & render_to_texture = = 2 ) {
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " pBufferAddress: %x " , pBufferAddress ) ;
2016-02-03 21:21:30 +00:00
//printf("update texture %x\n", pBufferAddress);
// nothing changed, don't update the texture
if ( ! buffer_cleared ) {
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " update cancelled " ) ;
2016-02-03 21:21:30 +00:00
return ;
}
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
// save result of render to texture into actual texture
glReadBuffer ( current_buffer ) ;
glActiveTextureARB ( texture_unit ) ;
// ZIGGY
// deleting the texture before resampling it increases speed on certain old
// nvidia cards (geforce 2 for example), unfortunatly it slows down a lot
// on newer cards.
//glDeleteTextures( 1, &pBufferAddress );
glBindTexture ( GL_TEXTURE_2D , pBufferAddress ) ;
glCopyTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGB ,
2017-03-13 09:34:51 +00:00
0 , g_viewport_offset , g_width , g_height , 0 ) ;
2016-02-03 21:21:30 +00:00
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
glPopAttrib ( ) ;
}
grDisplayGLError ( " updateTexture " ) ;
2013-04-10 07:08:48 +00:00
}
2013-04-21 21:35:30 +00:00
FX_ENTRY void FX_CALL grFramebufferCopyExt ( int /*x*/ , int /*y*/ , int /*w*/ , int /*h*/ ,
2016-02-03 21:21:30 +00:00
int from , int to , int mode )
{
if ( mode = = GR_FBCOPY_MODE_DEPTH ) {
int tw = 1 , th = 1 ;
if ( npot_support ) {
2016-03-10 17:21:56 +00:00
tw = g_width ; th = g_height ;
2016-02-03 21:21:30 +00:00
}
else {
2016-03-10 17:21:56 +00:00
while ( tw < g_width ) tw < < = 1 ;
while ( th < g_height ) th < < = 1 ;
2016-02-03 21:21:30 +00:00
}
if ( from = = GR_FBCOPY_BUFFER_BACK & & to = = GR_FBCOPY_BUFFER_FRONT ) {
//printf("save depth buffer %d\n", render_to_texture);
// save the depth image in a texture
glReadBuffer ( current_buffer ) ;
glBindTexture ( GL_TEXTURE_2D , depth_texture ) ;
glCopyTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT ,
2017-03-13 09:34:51 +00:00
0 , g_viewport_offset , tw , th , 0 ) ;
2016-02-03 21:21:30 +00:00
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
grDisplayGLError ( " grFramebufferCopyExt :: A " ) ;
return ;
}
if ( from = = GR_FBCOPY_BUFFER_FRONT & & to = = GR_FBCOPY_BUFFER_BACK ) {
//printf("writing to depth buffer %d\n", render_to_texture);
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
glDisable ( GL_ALPHA_TEST ) ;
glDrawBuffer ( current_buffer ) ;
glActiveTextureARB ( texture_unit ) ;
glBindTexture ( GL_TEXTURE_2D , depth_texture ) ;
glColorMask ( GL_FALSE , GL_FALSE , GL_FALSE , GL_FALSE ) ;
set_depth_shader ( ) ;
glEnable ( GL_DEPTH_TEST ) ;
glDepthFunc ( GL_ALWAYS ) ;
glDisable ( GL_CULL_FACE ) ;
render_rectangle ( texture_unit ,
0 , 0 ,
2016-03-10 17:21:56 +00:00
g_width , g_height ,
2016-02-03 21:21:30 +00:00
tw , th , - 1 ) ;
glColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
glPopAttrib ( ) ;
grDisplayGLError ( " grFramebufferCopyExt :: B " ) ;
return ;
}
}
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grRenderBuffer ( GrBuffer_t buffer )
2013-04-10 07:08:48 +00:00
{
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
static HANDLE region = NULL ;
//int realWidth = pBufferWidth, realHeight = pBufferHeight;
2013-04-10 07:08:48 +00:00
# endif // _WIN32
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " buffer: %d " , buffer ) ;
2016-02-03 21:21:30 +00:00
//printf("grRenderBuffer(%d)\n", buffer);
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
switch ( buffer )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
case GR_BUFFER_BACKBUFFER :
if ( render_to_texture )
{
updateTexture ( ) ;
// VP z fix
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ;
glTranslatef ( 0 , 0 , 1 - zscale ) ;
glScalef ( 1 , 1 , zscale ) ;
inverted_culling = 0 ;
grCullMode ( culling_mode ) ;
2016-03-10 17:21:56 +00:00
g_width = savedWidth ;
g_height = savedHeight ;
2016-02-03 21:21:30 +00:00
widtho = savedWidtho ;
heighto = savedHeighto ;
2017-04-27 07:31:49 +00:00
if ( use_fbo )
{
2016-02-03 21:21:30 +00:00
glBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , 0 ) ;
glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , 0 ) ;
}
curBufferAddr = 0 ;
2017-03-13 09:34:51 +00:00
glViewport ( 0 , g_viewport_offset , g_width , viewport_height ) ;
glScissor ( 0 , g_viewport_offset , g_width , g_height ) ;
2013-04-10 07:08:48 +00:00
# ifdef SAVE_CBUFFER
2016-02-03 21:21:30 +00:00
if ( ! use_fbo & & render_to_texture = = 2 ) {
// restore color buffer
if ( nbAuxBuffers > 0 ) {
glDrawBuffer ( GL_BACK ) ;
current_buffer = GL_BACK ;
}
else if ( save_w ) {
int tw = 1 , th = 1 ;
//printf("restore %dx%d\n", save_w, save_h);
if ( npot_support ) {
tw = screen_width ;
th = screen_height ;
}
else {
while ( tw < screen_width ) tw < < = 1 ;
while ( th < screen_height ) th < < = 1 ;
}
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
glDisable ( GL_ALPHA_TEST ) ;
glDrawBuffer ( GL_BACK ) ;
glActiveTextureARB ( texture_unit ) ;
glBindTexture ( GL_TEXTURE_2D , color_texture ) ;
glColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
set_copy_shader ( ) ;
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_CULL_FACE ) ;
render_rectangle ( texture_unit ,
0 , 0 ,
save_w , save_h ,
tw , th , - 1 ) ;
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
glPopAttrib ( ) ;
save_w = save_h = 0 ;
}
}
2013-04-10 07:08:48 +00:00
# endif
2016-02-03 21:21:30 +00:00
render_to_texture = 0 ;
}
glDrawBuffer ( GL_BACK ) ;
break ;
case 6 : // RENDER TO TEXTURE
if ( ! render_to_texture )
{
2016-03-10 17:21:56 +00:00
savedWidth = g_width ;
savedHeight = g_height ;
2016-02-03 21:21:30 +00:00
savedWidtho = widtho ;
savedHeighto = heighto ;
}
2013-04-10 07:08:48 +00:00
2017-04-18 11:32:43 +00:00
{
if ( ! use_fbo ) {
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ;
glTranslatef ( 0 , 0 , 1 - zscale ) ;
glScalef ( 1 , 1 , zscale ) ;
inverted_culling = 0 ;
}
else {
float m [ 4 * 4 ] = { 1.0f , 0.0f , 0.0f , 0.0f ,
0.0f , - 1.0f , 0.0f , 0.0f ,
0.0f , 0.0f , 1.0f , 0.0f ,
0.0f , 0.0f , 0.0f , 1.0f } ;
glMatrixMode ( GL_MODELVIEW ) ;
glLoadMatrixf ( m ) ;
// VP z fix
glTranslatef ( 0 , 0 , 1 - zscale ) ;
glScalef ( 1 , 1 * 1 , zscale ) ;
inverted_culling = 1 ;
grCullMode ( culling_mode ) ;
}
2016-02-03 21:21:30 +00:00
}
2017-04-18 11:32:43 +00:00
render_to_texture = 1 ;
break ;
2016-02-03 21:21:30 +00:00
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grRenderBuffer : unknown buffer : %x " , buffer ) ;
2016-02-03 21:21:30 +00:00
}
grDisplayGLError ( " grRenderBuffer " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grAuxBufferExt ( GrBuffer_t buffer )
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " buffer: %d " , buffer ) ;
2016-02-03 21:21:30 +00:00
2017-04-18 11:32:43 +00:00
if ( buffer = = GR_BUFFER_AUXBUFFER )
2016-12-25 22:26:36 +00:00
{
2016-02-03 21:21:30 +00:00
invtex [ 0 ] = 0 ;
invtex [ 1 ] = 0 ;
need_to_compile = 0 ;
set_depth_shader ( ) ;
glColorMask ( GL_FALSE , GL_FALSE , GL_FALSE , GL_FALSE ) ;
glEnable ( GL_DEPTH_TEST ) ;
glDepthFunc ( GL_ALWAYS ) ;
glDisable ( GL_CULL_FACE ) ;
glDisable ( GL_ALPHA_TEST ) ;
glDepthMask ( GL_TRUE ) ;
grTexFilterMode ( GR_TMU1 , GR_TEXTUREFILTER_POINT_SAMPLED , GR_TEXTUREFILTER_POINT_SAMPLED ) ;
}
else {
glColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
need_to_compile = 1 ;
}
grDisplayGLError ( " grAuxBufferExt " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grBufferClear ( GrColor_t color , GrAlpha_t alpha , FxU32 depth )
{
2016-03-10 17:21:56 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " color: %X alpha: %X depth: %X " , color , alpha , depth ) ;
2016-02-03 21:21:30 +00:00
switch ( lfb_color_fmt )
{
case GR_COLORFORMAT_ARGB :
glClearColor ( ( ( color > > 16 ) & 0xFF ) / 255.0f ,
( ( color > > 8 ) & 0xFF ) / 255.0f ,
( color & 0xFF ) / 255.0f ,
alpha / 255.0f ) ;
break ;
case GR_COLORFORMAT_RGBA :
glClearColor ( ( ( color > > 24 ) & 0xFF ) / 255.0f ,
( ( color > > 16 ) & 0xFF ) / 255.0f ,
( color & 0xFF ) / 255.0f ,
alpha / 255.0f ) ;
break ;
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grBufferClear: unknown color format : %x " , lfb_color_fmt ) ;
2016-02-03 21:21:30 +00:00
}
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( w_buffer_mode )
glClearDepth ( 1.0f - ( ( 1.0f + ( depth > > 4 ) / 4096.0f ) * ( 1 < < ( depth & 0xF ) ) ) / 65528.0 ) ;
else
glClearDepth ( depth / 65535.0f ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
// ZIGGY TODO check that color mask is on
buffer_cleared = 1 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
grDisplayGLError ( " grBufferClear " ) ;
2013-04-10 07:08:48 +00:00
}
// #include <unistd.h>
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grBufferSwap ( FxU32 swap_interval )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
int i ;
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " swap_interval: %d " , swap_interval ) ;
2016-02-03 21:21:30 +00:00
//printf("swap\n");
if ( render_to_texture ) {
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " swap while render_to_texture \n " ) ;
2016-02-03 21:21:30 +00:00
return ;
}
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
SwapBuffers ( wglGetCurrentDC ( ) ) ;
2013-04-10 07:08:48 +00:00
# else // _WIN32
# endif // _WIN32
2016-02-03 21:21:30 +00:00
for ( i = 0 ; i < nb_fb ; i + + )
fbs [ i ] . buff_clear = 1 ;
2013-04-10 07:08:48 +00:00
2015-03-02 18:40:34 +00:00
# ifdef _DEBUG
2016-02-03 21:21:30 +00:00
grFinish ( ) ;
2015-03-02 18:40:34 +00:00
# endif
2016-02-03 21:21:30 +00:00
// VP debugging
2013-04-10 07:08:48 +00:00
}
// frame buffer
FX_ENTRY FxBool FX_CALL
2016-02-03 21:21:30 +00:00
grLfbLock ( GrLock_t type , GrBuffer_t buffer , GrLfbWriteMode_t writeMode ,
2017-04-18 11:32:43 +00:00
GrOriginLocation_t origin , FxBool pixelPipeline ,
GrLfbInfo_t * info )
2016-02-03 21:21:30 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " type: %d buffer: %d writeMode: %d origin: %d pixelPipeline: %d " , type , buffer , writeMode , origin , pixelPipeline ) ;
2016-02-03 21:21:30 +00:00
if ( type = = GR_LFB_WRITE_ONLY )
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbLock : write only " ) ;
2016-02-03 21:21:30 +00:00
}
else
{
unsigned char * buf ;
int i , j ;
switch ( buffer )
{
case GR_BUFFER_FRONTBUFFER :
glReadBuffer ( GL_FRONT ) ;
break ;
case GR_BUFFER_BACKBUFFER :
glReadBuffer ( GL_BACK ) ;
break ;
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbLock : unknown buffer : %x " , buffer ) ;
2016-02-03 21:21:30 +00:00
}
if ( buffer ! = GR_BUFFER_AUXBUFFER )
{
if ( writeMode = = GR_LFBWRITEMODE_888 ) {
//printf("LfbLock GR_LFBWRITEMODE_888\n");
info - > lfbPtr = frameBuffer ;
2016-03-10 17:21:56 +00:00
info - > strideInBytes = g_width * 4 ;
2016-02-03 21:21:30 +00:00
info - > writeMode = GR_LFBWRITEMODE_888 ;
info - > origin = origin ;
2017-03-13 09:34:51 +00:00
glReadPixels ( 0 , g_viewport_offset , g_width , g_height , GL_BGRA , GL_UNSIGNED_BYTE , frameBuffer ) ;
2016-02-03 21:21:30 +00:00
}
else {
2016-03-10 17:21:56 +00:00
buf = ( unsigned char * ) malloc ( g_width * g_height * 4 ) ;
2016-02-03 21:21:30 +00:00
info - > lfbPtr = frameBuffer ;
2016-03-10 17:21:56 +00:00
info - > strideInBytes = g_width * 2 ;
2016-02-03 21:21:30 +00:00
info - > writeMode = GR_LFBWRITEMODE_565 ;
info - > origin = origin ;
2017-03-13 09:34:51 +00:00
glReadPixels ( 0 , g_viewport_offset , g_width , g_height , GL_RGBA , GL_UNSIGNED_BYTE , buf ) ;
2016-02-03 21:21:30 +00:00
2016-03-10 17:21:56 +00:00
for ( j = 0 ; j < g_height ; j + + )
2016-02-03 21:21:30 +00:00
{
2016-03-10 17:21:56 +00:00
for ( i = 0 ; i < g_width ; i + + )
2016-02-03 21:21:30 +00:00
{
2016-03-10 17:21:56 +00:00
frameBuffer [ ( g_height - j - 1 ) * g_width + i ] =
( ( buf [ j * g_width * 4 + i * 4 + 0 ] > > 3 ) < < 11 ) |
( ( buf [ j * g_width * 4 + i * 4 + 1 ] > > 2 ) < < 5 ) |
( buf [ j * g_width * 4 + i * 4 + 2 ] > > 3 ) ;
2016-02-03 21:21:30 +00:00
}
}
free ( buf ) ;
}
}
else
{
info - > lfbPtr = depthBuffer ;
2016-03-10 17:21:56 +00:00
info - > strideInBytes = g_width * 2 ;
2016-02-03 21:21:30 +00:00
info - > writeMode = GR_LFBWRITEMODE_ZA16 ;
info - > origin = origin ;
2017-03-13 09:34:51 +00:00
glReadPixels ( 0 , g_viewport_offset , g_width , g_height , GL_DEPTH_COMPONENT , GL_UNSIGNED_SHORT , depthBuffer ) ;
2016-02-03 21:21:30 +00:00
}
}
grDisplayGLError ( " grLfbLock " ) ;
return FXTRUE ;
2016-03-03 10:10:30 +00:00
}
2016-02-03 21:21:30 +00:00
FX_ENTRY FxBool FX_CALL
grLfbUnlock ( GrLock_t type , GrBuffer_t buffer )
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " type: %d, buffer: %d " , type , buffer ) ;
2016-02-03 21:21:30 +00:00
if ( type = = GR_LFB_WRITE_ONLY )
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbUnlock : write only " ) ;
2016-02-03 21:21:30 +00:00
}
return FXTRUE ;
}
FX_ENTRY FxBool FX_CALL
grLfbReadRegion ( GrBuffer_t src_buffer ,
2017-04-18 11:32:43 +00:00
FxU32 src_x , FxU32 src_y ,
FxU32 src_width , FxU32 src_height ,
FxU32 dst_stride , void * dst_data )
2016-02-03 21:21:30 +00:00
{
2013-04-10 07:08:48 +00:00
unsigned char * buf ;
2016-02-03 21:21:30 +00:00
unsigned int i , j ;
unsigned short * frameBuffer = ( unsigned short * ) dst_data ;
unsigned short * depthBuffer = ( unsigned short * ) dst_data ;
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " src_buffer: %d src_x: %d src_y: %d src_width: %d src_height: %d dst_stride: %d " , src_buffer , src_x , src_y , src_width , src_height , dst_stride ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
switch ( src_buffer )
2013-04-10 07:08:48 +00:00
{
case GR_BUFFER_FRONTBUFFER :
2016-02-03 21:21:30 +00:00
glReadBuffer ( GL_FRONT ) ;
break ;
2013-04-10 07:08:48 +00:00
case GR_BUFFER_BACKBUFFER :
2016-02-03 21:21:30 +00:00
glReadBuffer ( GL_BACK ) ;
break ;
/*case GR_BUFFER_AUXBUFFER:
glReadBuffer ( current_buffer ) ;
break ; */
2013-04-10 07:08:48 +00:00
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grReadRegion : unknown buffer : %x " , src_buffer ) ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
if ( src_buffer ! = GR_BUFFER_AUXBUFFER )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
buf = ( unsigned char * ) malloc ( src_width * src_height * 4 ) ;
2017-03-13 09:34:51 +00:00
glReadPixels ( src_x , ( g_viewport_offset ) + g_height - src_y - src_height , src_width , src_height , GL_RGBA , GL_UNSIGNED_BYTE , buf ) ;
2016-02-03 21:21:30 +00:00
for ( j = 0 ; j < src_height ; j + + )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
for ( i = 0 ; i < src_width ; i + + )
{
frameBuffer [ j * ( dst_stride / 2 ) + i ] =
( ( buf [ ( src_height - j - 1 ) * src_width * 4 + i * 4 + 0 ] > > 3 ) < < 11 ) |
( ( buf [ ( src_height - j - 1 ) * src_width * 4 + i * 4 + 1 ] > > 2 ) < < 5 ) |
( buf [ ( src_height - j - 1 ) * src_width * 4 + i * 4 + 2 ] > > 3 ) ;
}
2013-04-10 07:08:48 +00:00
}
free ( buf ) ;
}
else
{
2016-02-03 21:21:30 +00:00
buf = ( unsigned char * ) malloc ( src_width * src_height * 2 ) ;
2017-03-13 09:34:51 +00:00
glReadPixels ( src_x , ( g_viewport_offset ) + g_height - src_y - src_height , src_width , src_height , GL_DEPTH_COMPONENT , GL_UNSIGNED_SHORT , depthBuffer ) ;
2016-02-03 21:21:30 +00:00
for ( j = 0 ; j < src_height ; j + + )
{
for ( i = 0 ; i < src_width ; i + + )
{
depthBuffer [ j * ( dst_stride / 2 ) + i ] =
( ( unsigned short * ) buf ) [ ( src_height - j - 1 ) * src_width * 4 + i * 4 ] ;
}
}
free ( buf ) ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
grDisplayGLError ( " grLfbReadRegion " ) ;
return FXTRUE ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY FxBool FX_CALL
2016-02-03 21:21:30 +00:00
grLfbWriteRegion ( GrBuffer_t dst_buffer ,
2017-04-18 11:32:43 +00:00
FxU32 dst_x , FxU32 dst_y ,
GrLfbSrcFmt_t src_format ,
FxU32 src_width , FxU32 src_height ,
FxBool pixelPipeline ,
FxI32 src_stride , void * src_data )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
unsigned char * buf ;
unsigned int i , j ;
unsigned short * frameBuffer = ( unsigned short * ) src_data ;
int texture_number ;
unsigned int tex_width = 1 , tex_height = 1 ;
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " dst_buffer: %d dst_x: %d dst_y: %d src_format: %d src_width: %d src_height: %d pixelPipeline: %d src_stride: %d " , dst_buffer , dst_x , dst_y , src_format , src_width , src_height , pixelPipeline , src_stride ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
while ( tex_width < src_width ) tex_width < < = 1 ;
while ( tex_height < src_height ) tex_height < < = 1 ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
switch ( dst_buffer )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
case GR_BUFFER_BACKBUFFER :
glDrawBuffer ( GL_BACK ) ;
break ;
case GR_BUFFER_AUXBUFFER :
glDrawBuffer ( current_buffer ) ;
break ;
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbWriteRegion : unknown buffer : %x " , dst_buffer ) ;
2013-04-10 07:08:48 +00:00
}
2016-02-03 21:21:30 +00:00
if ( dst_buffer ! = GR_BUFFER_AUXBUFFER )
{
buf = ( unsigned char * ) malloc ( tex_width * tex_height * 4 ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
texture_number = GL_TEXTURE0_ARB ;
glActiveTextureARB ( texture_number ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
const unsigned int half_stride = src_stride / 2 ;
switch ( src_format )
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
case GR_LFB_SRC_FMT_1555 :
for ( j = 0 ; j < src_height ; j + + )
{
for ( i = 0 ; i < src_width ; i + + )
{
const unsigned int col = frameBuffer [ j * half_stride + i ] ;
buf [ j * tex_width * 4 + i * 4 + 0 ] = ( ( col > > 10 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 1 ] = ( ( col > > 5 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 2 ] = ( ( col > > 0 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 3 ] = ( col > > 15 ) ? 0xFF : 0 ;
}
}
break ;
case GR_LFBWRITEMODE_555 :
for ( j = 0 ; j < src_height ; j + + )
{
for ( i = 0 ; i < src_width ; i + + )
{
const unsigned int col = frameBuffer [ j * half_stride + i ] ;
buf [ j * tex_width * 4 + i * 4 + 0 ] = ( ( col > > 10 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 1 ] = ( ( col > > 5 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 2 ] = ( ( col > > 0 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 3 ] = 0xFF ;
}
}
break ;
case GR_LFBWRITEMODE_565 :
for ( j = 0 ; j < src_height ; j + + )
{
for ( i = 0 ; i < src_width ; i + + )
{
const unsigned int col = frameBuffer [ j * half_stride + i ] ;
buf [ j * tex_width * 4 + i * 4 + 0 ] = ( ( col > > 11 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 1 ] = ( ( col > > 5 ) & 0x3F ) < < 2 ;
buf [ j * tex_width * 4 + i * 4 + 2 ] = ( ( col > > 0 ) & 0x1F ) < < 3 ;
buf [ j * tex_width * 4 + i * 4 + 3 ] = 0xFF ;
}
}
break ;
default :
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbWriteRegion : unknown format : %d " , src_format ) ;
2013-04-10 07:08:48 +00:00
}
# ifdef VPDEBUG
2016-02-03 21:21:30 +00:00
if ( dumping ) {
ilTexImage ( tex_width , tex_height , 1 , 4 , IL_RGBA , IL_UNSIGNED_BYTE , buf ) ;
char name [ 128 ] ;
static int id ;
sprintf ( name , " dump/writecolor%d.png " , id + + ) ;
ilSaveImage ( name ) ;
//printf("dumped gdLfbWriteRegion %s\n", name);
}
2013-04-10 07:08:48 +00:00
# endif
2016-02-03 21:21:30 +00:00
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , 4 , tex_width , tex_height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , buf ) ;
free ( buf ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
set_copy_shader ( ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_BLEND ) ;
render_rectangle ( texture_number ,
dst_x , dst_y ,
src_width , src_height ,
tex_width , tex_height , + 1 ) ;
}
else
{
2017-04-18 11:32:43 +00:00
float * buf = ( float * ) malloc ( src_width * ( src_height + ( g_viewport_offset ) ) * sizeof ( float ) ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( src_format ! = GR_LFBWRITEMODE_ZA16 )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " unknown depth buffer write format:%x " , src_format ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
if ( dst_x | | dst_y )
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " dst_x:%d, dst_y:%d \n " , dst_x , dst_y ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
for ( j = 0 ; j < src_height ; j + + )
{
for ( i = 0 ; i < src_width ; i + + )
{
2017-03-13 09:34:51 +00:00
buf [ ( j + ( g_viewport_offset ) ) * src_width + i ] =
2016-02-03 21:21:30 +00:00
( frameBuffer [ ( src_height - j - 1 ) * ( src_stride / 2 ) + i ] / ( 65536.0f * ( 2.0f / zscale ) ) ) + 1 - zscale / 2.0f ;
}
}
2013-04-10 07:08:48 +00:00
# ifdef VPDEBUG
2016-02-03 21:21:30 +00:00
if ( dumping ) {
2017-03-13 09:34:51 +00:00
unsigned char * buf2 = ( unsigned char * ) malloc ( src_width * ( src_height + ( g_viewport_offset ) ) ) ;
2016-02-04 10:22:19 +00:00
for ( i = 0 ; i < src_width * src_height ; i + + )
2016-02-14 08:59:33 +00:00
buf2 [ i ] = buf [ i ] * 255.0f ;
2016-02-03 21:21:30 +00:00
ilTexImage ( src_width , src_height , 1 , 1 , IL_LUMINANCE , IL_UNSIGNED_BYTE , buf2 ) ;
char name [ 128 ] ;
static int id ;
sprintf ( name , " dump/writedepth%d.png " , id + + ) ;
ilSaveImage ( name ) ;
//printf("dumped gdLfbWriteRegion %s\n", name);
free ( buf2 ) ;
}
2013-04-10 07:08:48 +00:00
# endif
2016-02-03 21:21:30 +00:00
glEnable ( GL_DEPTH_TEST ) ;
glDepthFunc ( GL_ALWAYS ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
glDrawBuffer ( GL_BACK ) ;
glClear ( GL_DEPTH_BUFFER_BIT ) ;
glDepthMask ( 1 ) ;
2017-03-13 09:34:51 +00:00
glDrawPixels ( src_width , src_height + ( g_viewport_offset ) , GL_DEPTH_COMPONENT , GL_FLOAT , buf ) ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
free ( buf ) ;
}
glDrawBuffer ( current_buffer ) ;
glPopAttrib ( ) ;
2015-03-07 22:26:02 +00:00
2016-02-03 21:21:30 +00:00
grDisplayGLError ( " grLfbWriteRegion " ) ;
return FXTRUE ;
2016-03-03 10:10:30 +00:00
}
2013-04-10 07:08:48 +00:00
/* wrapper-specific glide extensions */
FX_ENTRY FxBool FX_CALL grKeyPressedExt ( FxU32 key )
{
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
return ( GetAsyncKeyState ( key ) & 0x8000 ) ;
2013-04-10 07:08:48 +00:00
# else
2016-03-10 18:06:18 +00:00
return 0 ;
2013-04-10 07:08:48 +00:00
# endif
}
2017-01-28 11:29:03 +00:00
void grConfigWrapperExt ( FxI32 vram , FxBool fbo , FxBool aniso )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2016-02-03 21:21:30 +00:00
config . vram_size = vram ;
config . fbo = fbo ;
config . anisofilter = aniso ;
2013-04-10 07:08:48 +00:00
}
// unused by glide64
FX_ENTRY FxI32 FX_CALL
2016-02-03 21:21:30 +00:00
grQueryResolutions ( const GrResolution * resTemplate , GrResolution * output )
{
int res_inf = 0 ;
int res_sup = 0xf ;
int i ;
int n = 0 ;
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grQueryResolutions " ) ;
2016-02-03 21:21:30 +00:00
if ( ( unsigned int ) resTemplate - > resolution ! = GR_QUERY_ANY )
{
res_inf = res_sup = resTemplate - > resolution ;
}
2016-02-14 08:59:33 +00:00
if ( ( unsigned int ) resTemplate - > refresh = = GR_QUERY_ANY ) WriteTrace ( TraceGlitch , TraceWarning , " querying any refresh rate " ) ;
if ( ( unsigned int ) resTemplate - > numAuxBuffers = = GR_QUERY_ANY ) WriteTrace ( TraceGlitch , TraceWarning , " querying any numAuxBuffers " ) ;
if ( ( unsigned int ) resTemplate - > numColorBuffers = = GR_QUERY_ANY ) WriteTrace ( TraceGlitch , TraceWarning , " querying any numColorBuffers " ) ;
2016-02-03 21:21:30 +00:00
if ( output = = NULL ) return res_sup - res_inf + 1 ;
for ( i = res_inf ; i < = res_sup ; i + + )
{
output [ n ] . resolution = i ;
output [ n ] . refresh = resTemplate - > refresh ;
output [ n ] . numAuxBuffers = resTemplate - > numAuxBuffers ;
output [ n ] . numColorBuffers = resTemplate - > numColorBuffers ;
n + + ;
}
return res_sup - res_inf + 1 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY FxBool FX_CALL
2016-02-03 21:21:30 +00:00
grReset ( FxU32 /*what*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grReset " ) ;
2016-02-03 21:21:30 +00:00
return 1 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grEnable ( GrEnableMode_t mode )
2013-04-27 09:17:15 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2016-02-03 21:21:30 +00:00
if ( mode = = GR_TEXTURE_UMA_EXT )
UMAmode = 1 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grDisable ( GrEnableMode_t mode )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2016-02-03 21:21:30 +00:00
if ( mode = = GR_TEXTURE_UMA_EXT )
UMAmode = 0 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grDisableAllEffects ( void )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grDisableAllEffects " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grErrorSetCallback ( GrErrorCallbackFnc_t /*fnc*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grErrorSetCallback " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
grFinish ( void )
{
2016-02-03 21:21:30 +00:00
glFinish ( ) ;
grDisplayGLError ( " grFinish " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
grFlush ( void )
{
2016-02-03 21:21:30 +00:00
glFlush ( ) ;
grDisplayGLError ( " grFlush " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grTexMultibase ( GrChipID_t /*tmu*/ ,
2017-04-18 11:32:43 +00:00
FxBool /*enable*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexMultibase " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grTexMipMapMode ( GrChipID_t /*tmu*/ ,
2017-04-18 11:32:43 +00:00
GrMipMapMode_t /*mode*/ ,
FxBool /*lodBlend*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexMipMapMode " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grTexDownloadTablePartial ( GrTexTable_t /*type*/ ,
2017-04-18 11:32:43 +00:00
void * /*data*/ ,
int /*start*/ ,
int /*end*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexDownloadTablePartial " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grTexDownloadTable ( GrTexTable_t /*type*/ ,
2017-04-18 11:32:43 +00:00
void * /*data*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexDownloadTable " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY FxBool FX_CALL
2016-02-03 21:21:30 +00:00
grTexDownloadMipMapLevelPartial ( GrChipID_t /*tmu*/ ,
2017-04-18 11:32:43 +00:00
FxU32 /*startAddress*/ ,
GrLOD_t /*thisLod*/ ,
GrLOD_t /*largeLod*/ ,
GrAspectRatio_t /*aspectRatio*/ ,
GrTextureFormat_t /*format*/ ,
FxU32 /*evenOdd*/ ,
void * /*data*/ ,
int /*start*/ ,
int /*end*/ )
2016-02-03 21:21:30 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexDownloadMipMapLevelPartial " ) ;
2016-02-03 21:21:30 +00:00
return 1 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grTexDownloadMipMapLevel ( GrChipID_t /*tmu*/ ,
2017-04-18 11:32:43 +00:00
FxU32 /*startAddress*/ ,
GrLOD_t /*thisLod*/ ,
GrLOD_t /*largeLod*/ ,
GrAspectRatio_t /*aspectRatio*/ ,
GrTextureFormat_t /*format*/ ,
FxU32 /*evenOdd*/ ,
void * /*data*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexDownloadMipMapLevel " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grTexNCCTable ( GrNCCTable_t /*table*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexNCCTable " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grViewport ( FxI32 /*x*/ , FxI32 /*y*/ , FxI32 /*width*/ , FxI32 /*height*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grViewport " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grDepthRange ( FxFloat /*n*/ , FxFloat /*f*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grDepthRange " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2013-04-21 21:35:30 +00:00
grSplash ( float /*x*/ , float /*y*/ , float /*width*/ , float /*height*/ , FxU32 /*frame*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grSplash " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY FxBool FX_CALL
2016-02-03 21:21:30 +00:00
grSelectContext ( GrContext_t /*context*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grSelectContext " ) ;
2016-02-03 21:21:30 +00:00
return 1 ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
grAADrawTriangle (
2017-04-18 11:32:43 +00:00
const void * /*a*/ , const void * /*b*/ , const void * /*c*/ ,
FxBool /*ab_antialias*/ , FxBool /*bc_antialias*/ , FxBool /*ca_antialias*/
2016-02-03 21:21:30 +00:00
)
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grAADrawTriangle " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grAlphaControlsITRGBLighting ( FxBool /*enable*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grAlphaControlsITRGBLighting " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grGlideSetVertexLayout ( const void * /*layout*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grGlideSetVertexLayout " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grGlideGetVertexLayout ( void * /*layout*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grGlideGetVertexLayout " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grGlideSetState ( const void * /*state*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grGlideSetState " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grGlideGetState ( void * /*state*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grGlideGetState " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2013-04-15 03:51:39 +00:00
grLfbWriteColorFormat ( GrColorFormat_t /*colorFormat*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbWriteColorFormat " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2013-04-15 03:51:39 +00:00
grLfbWriteColorSwizzle ( FxBool /*swizzleBytes*/ , FxBool /*swapWords*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbWriteColorSwizzle " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grLfbConstantDepth ( FxU32 /*depth*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbConstantDepth " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grLfbConstantAlpha ( GrAlpha_t /*alpha*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grLfbConstantAlpha " ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grTexMultibaseAddress ( GrChipID_t /*tmu*/ ,
2017-04-18 11:32:43 +00:00
GrTexBaseRange_t /*range*/ ,
FxU32 /*startAddress*/ ,
FxU32 /*evenOdd*/ ,
GrTexInfo * /*info*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexMultibaseAddress " ) ;
2013-04-10 07:08:48 +00:00
}
# ifdef _WIN32
static void CorrectGamma ( LPVOID apGammaRamp )
{
2016-02-03 21:21:30 +00:00
HDC hdc = GetDC ( NULL ) ;
if ( hdc ! = NULL )
{
SetDeviceGammaRamp ( hdc , apGammaRamp ) ;
ReleaseDC ( NULL , hdc ) ;
}
2013-04-27 09:17:15 +00:00
}
2013-04-10 07:08:48 +00:00
# else
static void CorrectGamma ( const FxU16 aGammaRamp [ 3 ] [ 256 ] )
2013-04-27 09:17:15 +00:00
{
2016-02-05 07:57:00 +00:00
int res ;
2017-04-18 11:32:43 +00:00
/* res = SDL_SetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]); */
2016-03-28 19:53:47 +00:00
res = - 1 ;
fputs ( " ERROR: Replacement for SDL_SetGammaRamp unimplemented. \n " , stderr ) ;
2016-02-05 07:57:00 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " SDL_SetGammaRamp returned %d \r \n " , res ) ;
2016-03-03 10:10:30 +00:00
}
2013-04-10 07:08:48 +00:00
# endif
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grLoadGammaTable ( FxU32 /*nentries*/ , FxU32 * red , FxU32 * green , FxU32 * blue )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2016-02-03 21:21:30 +00:00
FxU16 aGammaRamp [ 3 ] [ 256 ] ;
for ( int i = 0 ; i < 256 ; i + + )
{
aGammaRamp [ 0 ] [ i ] = ( FxU16 ) ( ( red [ i ] < < 8 ) & 0xFFFF ) ;
aGammaRamp [ 1 ] [ i ] = ( FxU16 ) ( ( green [ i ] < < 8 ) & 0xFFFF ) ;
aGammaRamp [ 2 ] [ i ] = ( FxU16 ) ( ( blue [ i ] < < 8 ) & 0xFFFF ) ;
}
CorrectGamma ( aGammaRamp ) ;
2013-04-10 07:08:48 +00:00
}
FX_ENTRY void FX_CALL
2013-04-15 03:51:39 +00:00
grGetGammaTableExt ( FxU32 /*nentries*/ , FxU32 * red , FxU32 * green , FxU32 * blue )
2013-04-10 07:08:48 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2016-02-03 21:21:30 +00:00
FxU16 aGammaRamp [ 3 ] [ 256 ] ;
2013-04-10 07:08:48 +00:00
# ifdef _WIN32
2016-02-03 21:21:30 +00:00
HDC hdc = GetDC ( NULL ) ;
if ( hdc = = NULL )
return ;
if ( GetDeviceGammaRamp ( hdc , aGammaRamp ) = = TRUE )
{
ReleaseDC ( NULL , hdc ) ;
2013-04-10 07:08:48 +00:00
# else
2016-03-28 19:53:47 +00:00
fputs ( " ERROR: Replacement for SDL_GetGammaRamp unimplemented. \n " , stderr ) ;
2017-04-18 11:32:43 +00:00
/* if (SDL_GetGammaRamp(aGammaRamp[0], aGammaRamp[1], aGammaRamp[2]) != -1) */
2013-04-10 07:08:48 +00:00
{
2016-02-03 21:21:30 +00:00
# endif
for ( int i = 0 ; i < 256 ; i + + )
{
red [ i ] = aGammaRamp [ 0 ] [ i ] > > 8 ;
green [ i ] = aGammaRamp [ 1 ] [ i ] > > 8 ;
blue [ i ] = aGammaRamp [ 2 ] [ i ] > > 8 ;
}
2013-04-10 07:08:48 +00:00
}
2016-03-03 10:10:30 +00:00
}
2013-04-10 07:08:48 +00:00
2013-04-27 09:17:15 +00:00
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
guGammaCorrectionRGB ( FxFloat gammaR , FxFloat gammaG , FxFloat gammaB )
2013-04-27 09:17:15 +00:00
{
2016-02-04 10:22:19 +00:00
WriteTrace ( TraceGlitch , TraceDebug , " - " ) ;
2017-01-28 11:29:03 +00:00
2016-02-03 21:21:30 +00:00
FxU16 aGammaRamp [ 3 ] [ 256 ] ;
for ( int i = 0 ; i < 256 ; i + + )
{
aGammaRamp [ 0 ] [ i ] = ( ( ( FxU16 ) ( ( pow ( i / 255.0F , 1.0F / gammaR ) ) * 255.0F + 0.5F ) ) < < 8 ) & 0xFFFF ;
aGammaRamp [ 1 ] [ i ] = ( ( ( FxU16 ) ( ( pow ( i / 255.0F , 1.0F / gammaG ) ) * 255.0F + 0.5F ) ) < < 8 ) & 0xFFFF ;
aGammaRamp [ 2 ] [ i ] = ( ( ( FxU16 ) ( ( pow ( i / 255.0F , 1.0F / gammaB ) ) * 255.0F + 0.5F ) ) < < 8 ) & 0xFFFF ;
}
CorrectGamma ( aGammaRamp ) ;
2013-04-27 09:17:15 +00:00
}
2013-04-10 07:08:48 +00:00
FX_ENTRY void FX_CALL
2016-02-03 21:21:30 +00:00
grDitherMode ( GrDitherMode_t /*mode*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grDitherMode " ) ;
2013-04-10 07:08:48 +00:00
}
2013-04-15 03:51:39 +00:00
void grChromaRangeExt ( GrColor_t /*color0*/ , GrColor_t /*color1*/ , FxU32 /*mode*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grChromaRangeExt " ) ;
2013-04-10 07:08:48 +00:00
}
2013-04-15 03:51:39 +00:00
void grChromaRangeModeExt ( GrChromakeyMode_t /*mode*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grChromaRangeModeExt " ) ;
2013-04-10 07:08:48 +00:00
}
2013-04-15 03:51:39 +00:00
void grTexChromaRangeExt ( GrChipID_t /*tmu*/ , GrColor_t /*color0*/ , GrColor_t /*color1*/ , GrTexChromakeyMode_t /*mode*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexChromaRangeExt " ) ;
2013-04-10 07:08:48 +00:00
}
2013-04-15 03:51:39 +00:00
void grTexChromaModeExt ( GrChipID_t /*tmu*/ , GrChromakeyMode_t /*mode*/ )
2013-04-10 07:08:48 +00:00
{
2016-02-14 08:59:33 +00:00
WriteTrace ( TraceGlitch , TraceWarning , " grTexChromaRangeModeExt " ) ;
2013-04-10 07:08:48 +00:00
}
2015-03-07 22:26:02 +00:00
static const char * GL_errors [ 7 + 1 ] = {
" GL_NO_ERROR " , /* "There is no current error." */
" GL_INVALID_ENUM " , /* "Invalid parameter." */
" GL_INVALID_VALUE " , /* "Invalid enum parameter value." */
" GL_INVALID_OPERATION " , /* "Illegal call." */
" GL_STACK_OVERFLOW " ,
" GL_STACK_UNDERFLOW " ,
" GL_OUT_OF_MEMORY " , /* "Unable to allocate memory." */
" GL_UNKNOWN_ERROR " /* ??? */
} ;
# ifndef _DEBUG
int grDisplayGLError ( const char * /*unused*/ )
{
return - 1 ;
}
# else
int grDisplayGLError ( const char * message )
{
GLenum status ;
unsigned int error_index ;
int failure ;
status = glGetError ( ) ;
failure = 1 ;
2013-04-10 07:08:48 +00:00
2015-03-07 22:26:02 +00:00
if ( status = = GL_NO_ERROR )
error_index = failure = 0 ;
else
error_index =
2016-02-03 21:21:30 +00:00
( status < GL_INVALID_ENUM ) /* to avoid underflow when subtracting */
? ( 7 ) /* our own, made-up "GL_UNKNOWN_ERROR" error */
: ( status - GL_INVALID_ENUM ) + 1 ;
2015-03-07 22:26:02 +00:00
if ( error_index > 7 )
error_index = 7 ;
# if !0
2016-02-03 21:21:30 +00:00
/*
* In most cases , we don ' t want to spam the screen to repeatedly say that
* there were no OpenGL errors yet , though sometimes one may need verbosity .
*/
2015-03-07 22:26:02 +00:00
if ( failure = = 0 )
return ( failure ) ;
# endif
# ifdef _WIN32
MessageBoxA ( NULL , message , GL_errors [ error_index ] , MB_ICONERROR ) ;
# else
fprintf ( stderr , " %s \n %s \n \n " , GL_errors [ error_index ] , message ) ;
# endif
return ( failure ) ;
}
# endif
2013-04-10 07:08:48 +00:00
// VP debug
# ifdef VPDEBUG
int dumping = 0 ;
static int tl_i ;
static int tl [ 10240 ] ;
void dump_start ( )
{
2016-02-03 21:21:30 +00:00
static int init ;
if ( ! init ) {
init = 1 ;
ilInit ( ) ;
ilEnable ( IL_FILE_OVERWRITE ) ;
2016-03-03 10:10:30 +00:00
}
2016-02-03 21:21:30 +00:00
dumping = 1 ;
tl_i = 0 ;
2013-04-10 07:08:48 +00:00
}
void dump_stop ( )
{
2016-02-03 21:21:30 +00:00
if ( ! dumping ) return ;
int i , j ;
2016-03-10 17:21:56 +00:00
for ( i = 0 ; i < nb_fb ; i + + ) {
2016-02-03 21:21:30 +00:00
dump_tex ( fbs [ i ] . texid ) ;
}
dump_tex ( default_texture ) ;
dump_tex ( depth_texture ) ;
dumping = 0 ;
glReadBuffer ( GL_FRONT ) ;
glReadPixels ( 0 , 0 , width , height , GL_RGBA , GL_UNSIGNED_BYTE , frameBuffer ) ;
ilTexImage ( width , height , 1 , 4 , IL_RGBA , IL_UNSIGNED_BYTE , frameBuffer ) ;
ilSaveImage ( " dump/framecolor.png " ) ;
glReadPixels ( 0 , 0 , width , height , GL_DEPTH_COMPONENT , GL_UNSIGNED_SHORT , depthBuffer ) ;
// FILE * fp = fopen("glide_depth1.bin", "rb");
// fread(depthBuffer, 2, width*height, fp);
// fclose(fp);
2016-03-10 17:21:56 +00:00
for ( j = 0 ; j < height ; j + + ) {
for ( i = 0 ; i < width ; i + + ) {
2016-02-03 21:21:30 +00:00
//uint16_t d = ( (uint16_t *)depthBuffer )[i+(height-1-j)*width]/2 + 0x8000;
2016-03-10 17:21:56 +00:00
uint16_t d = ( ( uint16_t * ) depthBuffer ) [ i + j * width ] ;
uint32_t c = ( ( uint32_t * ) frameBuffer ) [ i + j * width ] ;
( ( unsigned char * ) frameBuffer ) [ ( i + j * width ) * 3 ] = d & 0xff ;
( ( unsigned char * ) frameBuffer ) [ ( i + j * width ) * 3 + 1 ] = d > > 8 ;
( ( unsigned char * ) frameBuffer ) [ ( i + j * width ) * 3 + 2 ] = c & 0xff ;
2016-02-03 21:21:30 +00:00
}
}
ilTexImage ( width , height , 1 , 3 , IL_RGB , IL_UNSIGNED_BYTE , frameBuffer ) ;
ilSaveImage ( " dump/framedepth.png " ) ;
2016-03-10 17:21:56 +00:00
for ( i = 0 ; i < tl_i ; i + + ) {
2016-02-03 21:21:30 +00:00
glBindTexture ( GL_TEXTURE_2D , tl [ i ] ) ;
GLint w , h , fmt ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_WIDTH , & w ) ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_HEIGHT , & h ) ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_INTERNAL_FORMAT , & fmt ) ;
2016-03-10 17:21:56 +00:00
fprintf ( stderr , " Texture %d %dx%d fmt %x \n " , tl [ i ] , ( int ) w , ( int ) h , ( int ) fmt ) ;
2016-02-03 21:21:30 +00:00
2016-03-10 17:21:56 +00:00
uint32_t * pixels = ( uint32_t * ) malloc ( w * h * 4 ) ;
2016-02-03 21:21:30 +00:00
// 0x1902 is another constant meaning GL_DEPTH_COMPONENT
// (but isn't defined in gl's headers !!)
if ( fmt ! = GL_DEPTH_COMPONENT & & fmt ! = 0x1902 ) {
glGetTexImage ( GL_TEXTURE_2D , 0 , GL_RGBA , GL_UNSIGNED_BYTE , pixels ) ;
ilTexImage ( w , h , 1 , 4 , IL_RGBA , IL_UNSIGNED_BYTE , pixels ) ;
2016-03-10 17:21:56 +00:00
}
else {
2016-02-03 21:21:30 +00:00
glGetTexImage ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT , GL_UNSIGNED_SHORT , pixels ) ;
int i ;
2016-03-10 17:21:56 +00:00
for ( i = 0 ; i < w * h ; i + + )
( ( unsigned char * ) frameBuffer ) [ i ] = ( ( unsigned short * ) pixels ) [ i ] / 256 ;
2016-02-03 21:21:30 +00:00
ilTexImage ( w , h , 1 , 1 , IL_LUMINANCE , IL_UNSIGNED_BYTE , frameBuffer ) ;
}
char name [ 128 ] ;
// sprintf(name, "mkdir -p dump ; rm -f dump/tex%04d.png", i);
// system(name);
sprintf ( name , " dump/tex%04d.png " , i ) ;
fprintf ( stderr , " Writing '%s' \n " , name ) ;
ilSaveImage ( name ) ;
// SDL_FreeSurface(surf);
free ( pixels ) ;
}
glBindTexture ( GL_TEXTURE_2D , default_texture ) ;
grDisplayGLError ( " dump_stop " ) ;
2013-04-10 07:08:48 +00:00
}
void dump_tex ( int id )
{
2016-02-03 21:21:30 +00:00
if ( ! dumping ) return ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
int n ;
// yes, it's inefficient
2017-04-18 11:32:43 +00:00
for ( n = 0 ; n < tl_i ; n + + )
2016-02-03 21:21:30 +00:00
if ( tl [ n ] = = id )
return ;
2013-04-10 07:08:48 +00:00
2016-02-03 21:21:30 +00:00
tl [ tl_i + + ] = id ;
2013-04-10 07:08:48 +00:00
2016-02-04 10:22:19 +00:00
int i = tl_i - 1 ;
2013-04-10 07:08:48 +00:00
}
2016-03-10 18:06:18 +00:00
# endif
void CHECK_FRAMEBUFFER_STATUS ( )
{
GLenum status ;
status = glCheckFramebufferStatusEXT ( GL_FRAMEBUFFER_EXT ) ;
WriteTrace ( TraceGlitch , TraceDebug , " status: %X " , status ) ;
switch ( status ) {
case GL_FRAMEBUFFER_COMPLETE_EXT :
/*WriteTrace(TraceGlitch, TraceWarning, "framebuffer complete!\n");*/
break ;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer GL_FRAMEBUFFER_UNSUPPORTED_EXT \n " ) ;
/* you gotta choose different formats */
/*assert(0);*/
break ;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer INCOMPLETE_ATTACHMENT \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer FRAMEBUFFER_MISSING_ATTACHMENT \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer FRAMEBUFFER_DIMENSIONS \n " ) ;
break ;
/*case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer INCOMPLETE_DUPLICATE_ATTACHMENT \n " ) ;
break ; */
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer INCOMPLETE_FORMATS \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer INCOMPLETE_DRAW_BUFFER \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer INCOMPLETE_READ_BUFFER \n " ) ;
break ;
case GL_FRAMEBUFFER_BINDING_EXT :
WriteTrace ( TraceGlitch , TraceWarning , " framebuffer BINDING_EXT \n " ) ;
break ;
default :
break ;
/* programming error; will fail on all hardware */
/*assert(0);*/
}
2017-04-18 11:32:43 +00:00
}