1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - glide64/wrapper/main.cpp *
3
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4
* Copyright (C) 2005-2006 Hacktarux *
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 2 of the License, or *
9
* (at your option) any later version. *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program; if not, write to the *
18
* Free Software Foundation, Inc., *
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
29
#define GL_GLEXT_PROTOTYPES
30
#include <SDL_opengl.h>
41
int screen_width, screen_height;
43
static inline void opt_glCopyTexImage2D( GLenum target,
45
GLenum internalFormat,
55
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
56
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
57
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *) &fmt);
58
//printf("copyteximage %dx%d fmt %x oldfmt %x\n", width, height, internalFormat, fmt);
59
if (w == width && h == height && fmt == internalFormat) {
60
if (x+width >= screen_width) {
61
width = screen_width - x;
62
//printf("resizing w --> %d\n", width);
64
if (y+height >= screen_height+viewport_offset) {
65
height = screen_height+viewport_offset - y;
66
//printf("resizing h --> %d\n", height);
68
glCopyTexSubImage2D(target, level, 0, 0, x, y, width, height);
70
printf("copyteximage %dx%d fmt %x old %dx%d oldfmt %x\n", width, height, internalFormat, w, h, fmt);
71
// glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, internalFormat, GL_UNSIGNED_BYTE, 0);
72
// glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
73
// printf("--> %dx%d newfmt %x\n", width, height, fmt);
74
glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
77
#define glCopyTexImage2D opt_glCopyTexImage2D
91
GLint nbAuxBuffers, current_buffer;
92
int width, widtho, heighto, height;
93
int saved_width, saved_height;
94
int blend_func_separate_support;
96
int fog_coord_support;
97
int render_to_texture = 0;
102
// to allocate a new static texture name, take the value (free_texture++)
104
int default_texture; // the infamous "32*1024*1024" is now configurable
106
int depth_texture, color_texture;
107
int glsl_support = 0;
108
int viewport_width, viewport_height, viewport_offset = 0;
113
static unsigned long fullscreen;
115
static int savedWidtho, savedHeighto;
116
static int savedWidth, savedHeight;
117
unsigned int pBufferAddress;
118
static int pBufferFmt;
119
static int pBufferWidth, pBufferHeight;
121
static int nb_fb = 0;
122
static unsigned int curBufferAddr = 0;
124
struct s_usage { unsigned int min, max; }; struct s_usage tmu_usage[2] = { {0xfffffff, 0}, {0xfffffff, 0} };
130
#define NB_TEXBUFS 128 // MUST be a power of two
131
static texbuf_t texbufs[NB_TEXBUFS];
134
static SDL_Surface *m_pScreen;
136
// unsigned short * frameBuffer = NULL;
137
// unsigned short * depthBuffer = NULL;
138
unsigned short frameBuffer[2048*2048];
139
unsigned short depthBuffer[2048*2048];
143
void display_warning(const char *text, ...)
145
static int first_message = 100;
148
unsigned char buf[1000];
153
vsprintf((char*)buf, (char*)text, ap);
156
printf("Glide3x warning : %s\n", buf);
162
FILE *log_file = NULL;
166
log_file = fopen("wrapper_log.txt", "wb+");
171
if(log_file == NULL) return;
176
void LOG(char *text, ...)
179
if (!dumping) return;
183
if(log_file == NULL) return;
185
vfprintf(log_file, text, ap);
186
vfprintf(stderr, text, ap);
191
FX_ENTRY void FX_CALL
192
grSstOrigin(GrOriginLocation_t origin)
194
LOG("grSstOrigin(%d)\r\n", origin);
195
if (origin != GR_ORIGIN_UPPER_LEFT)
196
display_warning("grSstOrigin : %x", origin);
199
FX_ENTRY void FX_CALL
200
grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy )
202
LOG("grClipWindow(%d,%d,%d,%d)\r\n", minx, miny, maxx, maxy);
204
if (use_fbo && render_to_texture) {
205
glScissor(minx, miny, maxx - minx, maxy - miny);
206
glEnable(GL_SCISSOR_TEST);
212
if (!use_fbo && th > screen_height) th = screen_height;
215
FxU32 tmp = maxy; maxy = miny; miny = tmp;
216
// if (minx < 0) minx = 0;
217
// if (miny < 0) miny = 0;
218
if (maxx > (unsigned int) width) maxx = width;
219
if (maxy > (unsigned int) height) maxy = height;
220
glScissor(minx, miny+viewport_offset, maxx - minx, maxy - miny);
221
//printf("gl scissor %d %d %d %d\n", minx, miny, maxx, maxy);
222
//glScissor(minx, (viewport_offset)+height-maxy, maxx - minx, maxy - miny);
224
glScissor(minx, (viewport_offset)+height-maxy, maxx - minx, maxy - miny);
226
glEnable(GL_SCISSOR_TEST);
229
FX_ENTRY void FX_CALL
230
grColorMask( FxBool rgb, FxBool a )
232
LOG("grColorMask(%d, %d)\r\n", rgb, a);
233
glColorMask(rgb, rgb, rgb, a);
236
FX_ENTRY void FX_CALL
240
LOG("grGlideInit()\r\n");
243
FX_ENTRY void FX_CALL
244
grSstSelect( int which_sst )
246
LOG("grSstSelect(%d)\r\n", which_sst);
249
BOOL isExtensionSupported(const char *extension)
251
const GLubyte *extensions = NULL;
252
const GLubyte *start;
253
GLubyte *where, *terminator;
255
where = (GLubyte *)strchr(extension, ' ');
256
if (where || *extension == '\0')
259
extensions = glGetString(GL_EXTENSIONS);
264
where = (GLubyte *) strstr((const char *) start, extension);
268
terminator = where + strlen(extension);
269
if (where == start || *(where - 1) == ' ')
270
if (*terminator == ' ' || *terminator == '\0')
279
#define GrPixelFormat_t int
281
FX_ENTRY GrContext_t FX_CALL
284
GrScreenResolution_t screen_resolution,
285
GrScreenRefresh_t refresh_rate,
286
GrColorFormat_t color_format,
287
GrOriginLocation_t origin_location,
288
GrPixelFormat_t pixelformat,
292
LOG("grSstWinOpenExt(%d, %d, %d, %d, %d, %d %d)\r\n", hWnd, screen_resolution, refresh_rate, color_format, origin_location, nColBuffers, nAuxBuffers);
293
return grSstWinOpen(hWnd, screen_resolution, refresh_rate, color_format,
294
origin_location, nColBuffers, nAuxBuffers);
297
FX_ENTRY GrContext_t FX_CALL
300
GrScreenResolution_t screen_resolution,
301
GrScreenRefresh_t refresh_rate,
302
GrColorFormat_t color_format,
303
GrOriginLocation_t origin_location,
307
static int show_warning = 1;
310
// static int inidebug;
313
// FILE * newstdout = freopen("wrapper-debug.txt", "w", stdout);
314
// _dup2(_fileno(stdout), _fileno(stderr));
319
// allocate static texture names
320
// the initial value should be big enough to support the maximal resolution
321
free_texture = 32*2048*2048;
322
default_texture = free_texture++;
323
color_texture = free_texture++;
324
depth_texture = free_texture++;
326
LOG("grSstWinOpen(%d, %d, %d, %d, %d, %d %d)\r\n", hWnd, screen_resolution, refresh_rate, color_format, origin_location, nColBuffers, nAuxBuffers);
328
switch ((screen_resolution & ~0x80)&0xFF)
330
case GR_RESOLUTION_320x200:
334
case GR_RESOLUTION_320x240:
338
case GR_RESOLUTION_400x256:
342
case GR_RESOLUTION_512x384:
346
case GR_RESOLUTION_640x200:
350
case GR_RESOLUTION_640x350:
354
case GR_RESOLUTION_640x400:
358
case GR_RESOLUTION_640x480:
362
case GR_RESOLUTION_800x600:
366
case GR_RESOLUTION_960x720:
370
case GR_RESOLUTION_856x480:
374
case GR_RESOLUTION_512x256:
378
case GR_RESOLUTION_1024x768:
382
case GR_RESOLUTION_1280x1024:
386
case GR_RESOLUTION_1600x1200:
390
case GR_RESOLUTION_400x300:
395
display_warning("unknown SstWinOpen resolution : %x", screen_resolution);
399
const SDL_VideoInfo *videoInfo;
400
Uint32 videoFlags = 0;
404
printf("(II) Initializing SDL video subsystem...\n");
405
if(SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
407
printf("(EE) Error initializing SDL video subsystem: %s\n", SDL_GetError());
412
printf("(II) Getting video info...\n");
413
if(!(videoInfo = SDL_GetVideoInfo()))
415
printf("(EE) Video query failed: %s\n", SDL_GetError());
416
SDL_QuitSubSystem(SDL_INIT_VIDEO);
420
/* Setting the video mode */
421
videoFlags |= SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE;
423
if(videoInfo->hw_available)
424
videoFlags |= SDL_HWSURFACE;
426
videoFlags |= SDL_SWSURFACE;
428
if(videoInfo->blit_hw)
429
videoFlags |= SDL_HWACCEL;
431
if(screen_resolution & 0x80)
436
videoFlags |= SDL_FULLSCREEN;
438
viewport_offset = ((screen_resolution>>2) > 20) ? screen_resolution >> 2 : 20;
440
// ZIGGY viewport_offset is WIN32 specific, with SDL just set it to zero
441
viewport_offset = 0; //-10 //-20;
443
// ZIGGY not sure, but it might be better to let the system choose
444
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
445
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16);
446
// SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
447
// SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
448
// SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
449
// SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
450
// SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
451
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
453
printf("(II) Setting video mode %dx%d...\n", width, height);
454
if(!(m_pScreen = SDL_SetVideoMode(width, height, 0, videoFlags)))
456
printf("(EE) Error setting videomode %dx%d: %s\n", width, height, SDL_GetError());
457
SDL_QuitSubSystem(SDL_INIT_VIDEO);
463
sprintf(caption, "Glide64 Debug");
465
sprintf(caption, "Glide64");
467
SDL_WM_SetCaption(caption, caption);
468
glViewport(0, viewport_offset, width, height);
470
//if (color_format != GR_COLORFORMAT_ARGB) display_warning("color format is not ARGB");
471
lfb_color_fmt = color_format;
472
if (origin_location != GR_ORIGIN_UPPER_LEFT) display_warning("origin must be in upper left corner");
473
if (nColBuffers != 2) display_warning("number of color buffer is not 2");
474
if (nAuxBuffers != 1) display_warning("number of auxiliary buffer is not 1");
476
if (isExtensionSupported("GL_ARB_texture_env_combine") == FALSE &&
477
isExtensionSupported("GL_EXT_texture_env_combine") == FALSE &&
479
display_warning("Your video card doesn't support GL_ARB_texture_env_combine extension");
480
if (isExtensionSupported("GL_ARB_multitexture") == FALSE && show_warning)
481
display_warning("Your video card doesn't support GL_ARB_multitexture extension");
482
if (isExtensionSupported("GL_ARB_texture_mirrored_repeat") == FALSE && show_warning)
483
display_warning("Your video card doesn't support GL_ARB_texture_mirrored_repeat extension");
487
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &nbTextureUnits);
488
if (nbTextureUnits == 1) display_warning("You need a video card that has at least 2 texture units");
491
int getDisableAuxbuf();
492
if (!getDisableAuxbuf())
493
glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &nbAuxBuffers);
494
if (nbAuxBuffers > 0)
495
printf("Congratulations, you have %d auxilliary buffers, we'll use them wisely !\n", nbAuxBuffers);
501
if (isExtensionSupported("GL_EXT_blend_func_separate") == FALSE)
502
blend_func_separate_support = 0;
504
blend_func_separate_support = 1;
506
if (isExtensionSupported("GL_EXT_packed_pixels") == FALSE)
507
packed_pixels_support = 0;
509
printf("packed pixels extension used\n");
510
packed_pixels_support = 1;
513
if (isExtensionSupported("GL_ARB_texture_non_power_of_two") == FALSE)
516
printf("NPOT extension used\n");
520
if (isExtensionSupported("GL_EXT_fog_coord") == FALSE)
521
fog_coord_support = 0;
523
fog_coord_support = 1;
526
use_fbo = getEnableFBO();
528
printf("use_fbo %d\n", use_fbo);
530
if (isExtensionSupported("GL_ARB_shading_language_100") &&
531
isExtensionSupported("GL_ARB_shader_objects") &&
532
isExtensionSupported("GL_ARB_fragment_shader") &&
533
isExtensionSupported("GL_ARB_vertex_shader") && !getDisableGLSL())
540
glViewport(0, viewport_offset, width, height);
541
viewport_width = width;
542
viewport_height = height;
544
// void do_benchmarks();
547
// VP try to resolve z precision issues
548
glMatrixMode(GL_MODELVIEW);
550
glTranslatef(0, 0, 1-zscale);
551
glScalef(1, 1, zscale);
553
// glAlphaFunc(GL_GREATER, 0.5);
554
// glEnable(GL_ALPHA_TEST);
559
pBufferWidth = pBufferHeight = -1;
561
current_buffer = GL_BACK;
565
switch(nbTextureUnits)
568
texture_unit = GL_TEXTURE1_ARB;
571
texture_unit = GL_TEXTURE2_ARB;
574
texture_unit = GL_TEXTURE3_ARB;
577
else texture_unit = GL_TEXTURE0_ARB;
579
// frameBuffer = (unsigned short *) calloc(2048, 2048*sizeof(unsigned short));
580
// depthBuffer = (unsigned short *) calloc(2048, 2048*sizeof(unsigned short));
582
screen_width = width;
583
screen_height = height;
587
for (i=0; i<NB_TEXBUFS; i++)
588
texbufs[i].start = texbufs[i].end = 0xffffffff;
591
if (!use_fbo && nbAuxBuffers == 0) {
592
// create the framebuffer saving texture
593
int w = width, h = height;
594
glBindTexture(GL_TEXTURE_2D, color_texture);
597
while (w<width) w*=2;
598
while (h<height) h*=2;
600
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
601
glBindTexture(GL_TEXTURE_2D, 0);
605
void FindBestDepthBias();
615
FX_ENTRY void FX_CALL
616
grGlideShutdown( void )
618
LOG("grGlideShutdown\r\n");
622
FX_ENTRY FxBool FX_CALL
623
grSstWinClose( GrContext_t context )
625
int i, clear_texbuff = use_fbo;
626
LOG("grSstWinClose(%d)\r\n", context);
628
// void remove_all_tex();
631
for (i=0; i<2; i++) {
632
tmu_usage[i].min = 0xfffffff;
633
tmu_usage[i].max = 0;
638
// free(frameBuffer);
640
// free(depthBuffer);
641
// frameBuffer = depthBuffer = NULL;
645
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
649
for (i=0; i<nb_fb; i++)
651
glDeleteTextures( 1, &(fbs[i].texid) );
652
glDeleteFramebuffersEXT( 1, &(fbs[i].fbid) );
653
glDeleteRenderbuffersEXT( 1, &(fbs[i].zbid) );
658
// ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit
659
remove_tex(0, 0xfffffff);
661
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
667
FX_ENTRY void FX_CALL grTextureBufferExt( GrChipID_t tmu,
671
GrAspectRatio_t aspect,
672
GrTextureFormat_t fmt,
676
static int fbs_init = 0;
678
//printf("grTextureBufferExt(%d, %d, %d, %d, %d, %d, %d)\r\n", tmu, startAddress, lodmin, lodmax, aspect, fmt, evenOdd);
679
LOG("grTextureBufferExt(%d, %d, %d, %d %d, %d, %d)\r\n", tmu, startAddress, lodmin, lodmax, aspect, fmt, evenOdd);
680
if (lodmin != lodmax) display_warning("grTextureBufferExt : loading more than one LOD");
683
if (!render_to_texture) { //initialization
687
render_to_texture = 2;
691
pBufferHeight = 1 << lodmin;
692
pBufferWidth = pBufferHeight >> -aspect;
696
pBufferWidth = 1 << lodmin;
697
pBufferHeight = pBufferWidth >> aspect;
700
if (curBufferAddr && startAddress+1 != curBufferAddr)
703
//printf("saving %dx%d\n", pBufferWidth, pBufferHeight);
705
if (nbAuxBuffers > 0) {
706
glDrawBuffer(GL_AUX0);
707
current_buffer = GL_AUX0;
710
if (pBufferWidth < screen_width)
714
if (pBufferHeight < screen_height)
718
glReadBuffer(GL_BACK);
719
glActiveTextureARB(texture_unit);
720
glBindTexture(GL_TEXTURE_2D, color_texture);
721
// save incrementally the framebuffer
723
if (tw > save_w && th > save_h) {
724
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, save_h,
725
0, viewport_offset+save_h, tw, th-save_h);
726
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, save_w, 0,
727
save_w, viewport_offset, tw-save_w, save_h);
730
} else if (tw > save_w) {
731
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, save_w, 0,
732
save_w, viewport_offset, tw-save_w, save_h);
734
} else if (th > save_h) {
735
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, save_h,
736
0, viewport_offset+save_h, save_w, th-save_h);
740
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
741
0, viewport_offset, tw, th);
745
glBindTexture(GL_TEXTURE_2D, default_texture);
749
if (startAddress+1 != curBufferAddr ||
750
(curBufferAddr == 0L && nbAuxBuffers == 0))
751
buffer_cleared = FALSE;
753
curBufferAddr = pBufferAddress = startAddress+1;
756
int rtmu = startAddress < grTexMinAddress(GR_TMU1)? 0 : 1;
757
int size = pBufferWidth*pBufferHeight*2; //grTexFormatSize(fmt);
758
if (tmu_usage[rtmu].min > pBufferAddress)
759
tmu_usage[rtmu].min = pBufferAddress;
760
if (tmu_usage[rtmu].max < pBufferAddress+size)
761
tmu_usage[rtmu].max = pBufferAddress+size;
762
// printf("tmu %d usage now %gMb - %gMb\n",
763
// rtmu, tmu_usage[rtmu].min/1024.0f, tmu_usage[rtmu].max/1024.0f);
766
width = pBufferWidth;
767
height = pBufferHeight;
772
// this could be improved, but might be enough as long as the set of
773
// texture buffer addresses stay small
774
for (i=(texbuf_i-1)&(NB_TEXBUFS-1) ; i!=texbuf_i; i=(i-1)&(NB_TEXBUFS-1))
775
if (texbufs[i].start == pBufferAddress)
777
texbufs[i].start = pBufferAddress;
778
texbufs[i].end = pBufferAddress + size;
779
texbufs[i].fmt = fmt;
781
texbuf_i = (texbuf_i+1)&(NB_TEXBUFS-1);
782
//printf("texbuf %x fmt %x\n", pBufferAddress, fmt);
784
// ZIGGY it speeds things up to not delete the buffers
785
// a better thing would be to delete them *sometimes*
786
// remove_tex(pBufferAddress+1, pBufferAddress + size);
787
add_tex(pBufferAddress);
789
//printf("viewport %dx%d\n", width, height);
790
if (height > screen_height) {
791
glViewport( 0, viewport_offset + screen_height - height, width, height);
793
glViewport( 0, viewport_offset, width, height);
795
glScissor(0, viewport_offset, width, height);
797
// glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
798
// glClear( GL_COLOR_BUFFER_BIT );
799
// glClear( GL_DEPTH_BUFFER_BIT );
803
if (!render_to_texture) //initialization
807
for(i=0; i<100; i++) fbs[i].address = 0;
811
return; //no need to allocate FBO if render buffer is not texture buffer
814
render_to_texture = 2;
818
pBufferHeight = 1 << lodmin;
819
pBufferWidth = pBufferHeight >> -aspect;
823
pBufferWidth = 1 << lodmin;
824
pBufferHeight = pBufferWidth >> aspect;
826
pBufferAddress = startAddress+1;
828
width = pBufferWidth;
829
height = pBufferHeight;
834
//glScissor(0, 0, width, height);
835
//glEnable(GL_SCISSOR_TEST);
837
for (i=0; i<nb_fb; i++)
839
if (fbs[i].address == pBufferAddress)
841
if (fbs[i].width == width && fbs[i].height == height) //select already allocated FBO
843
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
844
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbs[i].fbid );
845
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbs[i].texid, 0 );
846
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, fbs[i].zbid );
847
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbs[i].zbid );
848
glViewport( 0, 0, width, height);
849
glScissor( 0, 0, width, height);
850
if (fbs[i].buff_clear)
853
glClear( GL_DEPTH_BUFFER_BIT ); //clear z-buffer only. we may need content, stored in the frame buffer
854
fbs[i].buff_clear = 0;
856
CHECK_FRAMEBUFFER_STATUS();
857
curBufferAddr = pBufferAddress;
860
else //create new FBO at the same address, delete old one
862
glDeleteFramebuffersEXT( 1, &(fbs[i].fbid) );
863
glDeleteRenderbuffersEXT( 1, &(fbs[i].zbid) );
865
memmove(&(fbs[i]), &(fbs[i+1]), sizeof(fb)*(nb_fb-i));
872
remove_tex(pBufferAddress, pBufferAddress + width*height*2/*grTexFormatSize(fmt)*/);
874
glGenFramebuffersEXT( 1, &(fbs[nb_fb].fbid) );
875
glGenRenderbuffersEXT( 1, &(fbs[nb_fb].zbid) );
876
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, fbs[nb_fb].zbid );
877
// VP ported from mudlord
878
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
879
//glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
880
fbs[nb_fb].address = pBufferAddress;
881
fbs[nb_fb].width = width;
882
fbs[nb_fb].height = height;
883
fbs[nb_fb].texid = pBufferAddress;
884
fbs[nb_fb].buff_clear = 0;
885
add_tex(fbs[nb_fb].texid);
886
glBindTexture(GL_TEXTURE_2D, fbs[nb_fb].texid);
887
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
888
GL_RGB, GL_UNSIGNED_BYTE, NULL);
889
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
890
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
892
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbs[nb_fb].fbid);
893
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
894
GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbs[nb_fb].texid, 0);
895
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbs[nb_fb].zbid );
896
glViewport(0,0,width,height);
897
glScissor(0,0,width,height);
898
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
900
glClear( GL_DEPTH_BUFFER_BIT );
901
CHECK_FRAMEBUFFER_STATUS();
902
curBufferAddr = pBufferAddress;
907
int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info )
911
for (found=i=0; i<2; i++)
912
if (tmu_usage[i].min <= startAddress && tmu_usage[i].max > startAddress) {
913
//printf("tmu %d == framebuffer %x\n", tmu, startAddress);
918
// if (found && info->format == GR_TEXFMT_ALPHA_INTENSITY_88) {
919
// // now check the original buffer format
920
// // if it was 565, then we are dealing with a b&w conversion hack
921
// // so use special shader for it
922
// for (i=(texbuf_i-1)&(NB_TEXBUFS-1); i!=texbuf_i; i = (i-1)&(NB_TEXBUFS-1))
923
// if (texbufs[i].start == startAddress) {
924
// if (texbufs[i].fmt != GR_TEXFMT_ALPHA_INTENSITY_88)
927
// printf("texbuf %x fmt now %x\n", startAddress, info->format);
930
// if (i == texbuf_i)
931
// display_warning("Couldn't find texbuf %x !\n", startAddress);
937
unsigned int end = fbs[i].address + fbs[i].width*fbs[i].height*2;
938
if (startAddress >= fbs[i].address && startAddress < end)
947
if (!use_fbo && found) {
948
int tw, th, rh, cw, ch;
949
if (info->aspectRatioLog2 < 0)
951
th = 1 << info->largeLodLog2;
952
tw = th >> -info->aspectRatioLog2;
956
tw = 1 << info->largeLodLog2;
957
th = tw >> info->aspectRatioLog2;
960
if (info->aspectRatioLog2 < 0)
963
cw = ch >> -info->aspectRatioLog2;
968
ch = cw >> info->aspectRatioLog2;
971
if (use_fbo || th < screen_height)
976
//printf("th %d rh %d ch %d\n", th, rh, ch);
978
invtex[tmu] = 1.0f - (th - rh) / (float)th;
982
if (info->format == GR_TEXFMT_ALPHA_INTENSITY_88 ) {
986
//glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8_ALPHA8, fbs[i].width, fbs[i].height, 0, GL_LUMINANCE8_ALPHA8, GL_UNSIGNED_BYTE, NULL);
989
if(blackandwhite1 != found)
991
blackandwhite1 = found;
997
if(blackandwhite0 != found)
999
blackandwhite0 = found;
1000
need_to_compile = 1;
1010
FX_ENTRY void FX_CALL
1011
grTextureAuxBufferExt( GrChipID_t tmu,
1015
GrAspectRatio_t aspectRatio,
1016
GrTextureFormat_t format,
1017
FxU32 odd_even_mask )
1019
LOG("grTextureAuxBufferExt(%d, %d, %d, %d %d, %d, %d)\r\n", tmu, startAddress, thisLOD, largeLOD, aspectRatio, format, odd_even_mask);
1020
//display_warning("grTextureAuxBufferExt");
1023
FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );
1025
FX_ENTRY GrProc FX_CALL
1026
grGetProcAddress( const char *procName )
1028
LOG("grGetProcAddress(%s)\r\n", procName);
1029
if(!strcmp(procName, "grSstWinOpenExt"))
1030
return (GrProc)grSstWinOpenExt;
1031
if(!strcmp(procName, "grTextureBufferExt"))
1032
return (GrProc)grTextureBufferExt;
1033
if(!strcmp(procName, "grChromaRangeExt"))
1034
return (GrProc)grChromaRangeExt;
1035
if(!strcmp(procName, "grChromaRangeModeExt"))
1036
return (GrProc)grChromaRangeModeExt;
1037
if(!strcmp(procName, "grTexChromaRangeExt"))
1038
return (GrProc)grTexChromaRangeExt;
1039
if(!strcmp(procName, "grTexChromaModeExt"))
1040
return (GrProc)grTexChromaModeExt;
1041
if(!strcmp(procName, "grConfigWrapperExt"))
1042
return (GrProc)grConfigWrapperExt;
1043
// ZIGGY framebuffer copy extension
1044
if(/*glsl_support && */!strcmp(procName, "grFramebufferCopyExt"))
1045
return (GrProc)grFramebufferCopyExt;
1046
if(!strcmp(procName, "grWrapperFullScreenResolutionExt"))
1047
return (GrProc)grWrapperFullScreenResolutionExt;
1048
if(!strcmp(procName, "grColorCombineExt"))
1049
return (GrProc)grColorCombineExt;
1050
if(!strcmp(procName, "grAlphaCombineExt"))
1051
return (GrProc)grAlphaCombineExt;
1052
if(!strcmp(procName, "grTexColorCombineExt"))
1053
return (GrProc)grTexColorCombineExt;
1054
if(!strcmp(procName, "grTexAlphaCombineExt"))
1055
return (GrProc)grTexAlphaCombineExt;
1056
if(!strcmp(procName, "grConstantColorValueExt"))
1057
return (GrProc)grConstantColorValueExt;
1058
if(!strcmp(procName, "grTextureAuxBufferExt"))
1059
return (GrProc)grTextureAuxBufferExt;
1060
if(!strcmp(procName, "grAuxBufferExt"))
1061
return (GrProc)grAuxBufferExt;
1062
display_warning("grGetProcAddress : %s", procName);
1066
FX_ENTRY FxU32 FX_CALL
1067
grGet( FxU32 pname, FxU32 plength, FxI32 *params )
1069
LOG("grGet(%d,%d)\r\n", pname, plength);
1072
case GR_MAX_TEXTURE_SIZE:
1073
if (plength < 4 || params == NULL) return 0;
1078
if (plength < 4 || params == NULL) return 0;
1079
if (!nbTextureUnits)
1081
grSstWinOpen((unsigned long)NULL, GR_RESOLUTION_640x480 | 0x80, 0, GR_COLORFORMAT_ARGB,
1082
GR_ORIGIN_UPPER_LEFT, 2, 1);
1088
if (nbTextureUnits > 2)
1097
case GR_REVISION_FB:
1098
case GR_REVISION_TMU:
1099
if (plength < 4 || params == NULL) return 0;
1104
if (plength < 4 || params == NULL) return 0;
1105
params[0] = 16*1024*1024;
1109
if (plength < 4 || params == NULL) return 0;
1110
params[0] = 16*1024*1024;
1114
if (plength < 4 || params == NULL) return 0;
1115
params[0] = 16*1024*1024*nbTextureUnits;
1119
if (plength < 16 || params == NULL) return 0;
1127
if (plength < 4 || params == NULL) return 0;
1132
case GR_GAMMA_TABLE_ENTRIES:
1135
case GR_FOG_TABLE_ENTRIES:
1136
if (plength < 4 || params == NULL) return 0;
1140
case GR_WDEPTH_MIN_MAX:
1141
if (plength < 8 || params == NULL) return 0;
1146
case GR_ZDEPTH_MIN_MAX:
1147
if (plength < 8 || params == NULL) return 0;
1152
case GR_LFB_PIXEL_PIPE:
1153
if (plength < 4 || params == NULL) return 0;
1154
params[0] = FXFALSE;
1157
case GR_MAX_TEXTURE_ASPECT_RATIO:
1158
if (plength < 4 || params == NULL) return 0;
1162
case GR_NON_POWER_OF_TWO_TEXTURES:
1163
if (plength < 4 || params == NULL) return 0;
1164
params[0] = FXFALSE;
1167
case GR_TEXTURE_ALIGN:
1168
if (plength < 4 || params == NULL) return 0;
1173
display_warning("unknown pname in grGet : %x", pname);
1178
FX_ENTRY const char * FX_CALL
1179
grGetString( FxU32 pname )
1181
LOG("grGetString(%d)\r\n", pname);
1186
static int glsl_combiner = -1;
1187
static char extension1[] = "CHROMARANGE TEXCHROMA TEXMIRROR PALETTE6666 FOGCOORD EVOODOO TEXTUREBUFFER TEXFMT COMBINE";
1188
static char extension2[] = "CHROMARANGE TEXCHROMA TEXMIRROR PALETTE6666 FOGCOORD EVOODOO TEXTUREBUFFER TEXFMT";
1189
if(glsl_combiner == -1)
1191
/* JOSH FIXME: hack to avoid implementing CreateGLWindow and KillGLWindow
1192
* Rather than calling glGetString to check for the appropriate extensions,
1193
* just let getDisableGLSL() decide. */
1194
glsl_combiner = 1; /* Just use the disable flag */
1196
if(glsl_combiner == 1 && !getDisableGLSL())
1204
static char hardware[] = "Voodoo5 (tm)";
1210
static char vendor[] = "3Dfx Interactive";
1216
static char renderer[] = "Glide";
1222
static char version[] = "3.0";
1227
display_warning("unknown grGetString selector : %x", pname);
1232
static void render_rectangle(int texture_number,
1233
int dst_x, int dst_y,
1234
int src_width, int src_height,
1235
int tex_width, int tex_height, int invert)
1237
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1238
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1239
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1240
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1242
glMultiTexCoord2fARB(texture_number, 0.0f, 0.0f);
1243
glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1244
invert*-((int)dst_y - heighto) / (float)(height/2));
1245
glMultiTexCoord2fARB(texture_number, 0.0f, (float)src_height / (float)tex_height);
1246
glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1247
invert*-((int)dst_y + (int)src_height - heighto) / (float)(height/2));
1248
glMultiTexCoord2fARB(texture_number, (float)src_width / (float)tex_width, (float)src_height / (float)tex_height);
1249
glVertex2f(((int)dst_x + (int)src_width - widtho) / (float)(width/2),
1250
invert*-((int)dst_y + (int)src_height - heighto) / (float)(height/2));
1251
glMultiTexCoord2fARB(texture_number, (float)src_width / (float)tex_width, 0.0f);
1252
glVertex2f(((int)dst_x + (int)src_width - widtho) / (float)(width/2),
1253
invert*-((int)dst_y - heighto) / (float)(height/2));
1254
glMultiTexCoord2fARB(texture_number, 0.0f, 0.0f);
1255
glVertex2f(((int)dst_x - widtho) / (float)(width/2),
1256
invert*-((int)dst_y - heighto) / (float)(height/2));
1261
switch(nbTextureUnits)
1276
else compile_shader();
1278
glEnable(GL_DEPTH_TEST);
1282
void reloadTexture()
1284
if (use_fbo || !render_to_texture || buffer_cleared)
1287
LOG("reload texture %dx%d\n", width, height);
1288
printf("reload texture %dx%d\n", width, height);
1290
buffer_cleared = TRUE;
1292
glPushAttrib(GL_ALL_ATTRIB_BITS);
1293
glActiveTextureARB(texture_unit);
1294
glBindTexture(GL_TEXTURE_2D, pBufferAddress);
1295
glDisable(GL_ALPHA_TEST);
1296
glDrawBuffer(current_buffer);
1297
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1299
glDisable(GL_DEPTH_TEST);
1300
glDisable(GL_CULL_FACE);
1302
//if (width > screen_width) w = screen_width - width;
1303
if (height > screen_height) h = screen_height - height;
1304
render_rectangle(texture_unit,
1308
glBindTexture(GL_TEXTURE_2D, default_texture);
1312
void updateTexture()
1314
if (!use_fbo && render_to_texture == 2) {
1315
LOG("update texture %x\n", pBufferAddress);
1316
//printf("update texture %x\n", pBufferAddress);
1318
// nothing changed, don't update the texture
1319
if (!buffer_cleared) {
1320
LOG("update cancelled\n", pBufferAddress);
1324
glPushAttrib(GL_ALL_ATTRIB_BITS);
1326
// save result of render to texture into actual texture
1327
glReadBuffer(current_buffer);
1328
glActiveTextureARB(texture_unit);
1330
// deleting the texture before resampling it increases speed on certain old
1331
// nvidia cards (geforce 2 for example), unfortunatly it slows down a lot
1333
//glDeleteTextures( 1, &pBufferAddress );
1334
glBindTexture(GL_TEXTURE_2D, pBufferAddress);
1335
glCopyTexImage2D(GL_TEXTURE_2D, 0, (!glsl_support && pBufferFmt == GR_TEXFMT_ALPHA_INTENSITY_88)? GL_INTENSITY : GL_RGB,
1336
0, viewport_offset, width, height, 0);
1338
glBindTexture(GL_TEXTURE_2D, default_texture);
1343
FX_ENTRY void FX_CALL grFramebufferCopyExt(int x, int y, int w, int h,
1344
int from, int to, int mode)
1346
if (mode == GR_FBCOPY_MODE_DEPTH) {
1353
tw = width; th = height;
1355
while (tw < width) tw <<= 1;
1356
while (th < height) th <<= 1;
1359
if (from == GR_FBCOPY_BUFFER_BACK && to == GR_FBCOPY_BUFFER_FRONT) {
1360
printf("save depth buffer %d\n", render_to_texture);
1361
// save the depth image in a texture
1362
//glDisable(GL_ALPHA_TEST);
1363
glReadBuffer(current_buffer);
1364
glBindTexture(GL_TEXTURE_2D, depth_texture);
1365
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
1366
0, viewport_offset, tw, th, 0);
1367
glBindTexture(GL_TEXTURE_2D, default_texture);
1370
if (from == GR_FBCOPY_BUFFER_FRONT && to == GR_FBCOPY_BUFFER_BACK) {
1371
printf("writing to depth buffer %d\n", render_to_texture);
1373
glPushAttrib(GL_ALL_ATTRIB_BITS);
1374
glDisable(GL_ALPHA_TEST);
1375
glDrawBuffer(current_buffer);
1376
glActiveTextureARB(texture_unit);
1377
glBindTexture(GL_TEXTURE_2D, depth_texture);
1378
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1380
glEnable(GL_DEPTH_TEST);
1381
glDepthFunc(GL_ALWAYS);
1382
glDisable(GL_CULL_FACE);
1383
render_rectangle(texture_unit,
1387
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1388
glBindTexture(GL_TEXTURE_2D, default_texture);
1396
FX_ENTRY void FX_CALL
1397
grRenderBuffer( GrBuffer_t buffer )
1399
LOG("grRenderBuffer(%d)\r\n", buffer);
1400
//printf("grRenderBuffer(%d)\n", buffer);
1404
case GR_BUFFER_BACKBUFFER:
1405
if(render_to_texture)
1410
glMatrixMode(GL_MODELVIEW);
1412
glTranslatef(0, 0, 1-zscale);
1413
glScalef(1, 1, zscale);
1414
inverted_culling = 0;
1415
grCullMode(culling_mode);
1418
height = savedHeight;
1419
widtho = savedWidtho;
1420
heighto = savedHeighto;
1422
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1423
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
1427
glViewport(0, viewport_offset, width, viewport_height);
1428
glScissor(0, viewport_offset, width, height);
1431
if (!use_fbo && render_to_texture == 2) {
1432
// restore color buffer
1433
if (nbAuxBuffers > 0) {
1434
glDrawBuffer(GL_BACK);
1435
current_buffer = GL_BACK;
1436
} else if (save_w) {
1438
//printf("restore %dx%d\n", save_w, save_h);
1443
while (tw < screen_width) tw <<= 1;
1444
while (th < screen_height) th <<= 1;
1447
glPushAttrib(GL_ALL_ATTRIB_BITS);
1448
glDisable(GL_ALPHA_TEST);
1449
glDrawBuffer(GL_BACK);
1450
glActiveTextureARB(texture_unit);
1451
glBindTexture(GL_TEXTURE_2D, color_texture);
1452
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1454
glDisable(GL_DEPTH_TEST);
1455
glDisable(GL_CULL_FACE);
1456
render_rectangle(texture_unit,
1460
glBindTexture(GL_TEXTURE_2D, default_texture);
1463
save_w = save_h = 0;
1469
// restore depth buffer
1470
// grFramebufferCopyExt(0, 0, width, height,
1471
// GR_FBCOPY_BUFFER_FRONT, GR_FBCOPY_BUFFER_BACK,
1472
// GR_FBCOPY_MODE_DEPTH);
1474
render_to_texture = 0;
1476
glDrawBuffer(GL_BACK);
1478
case 6: // RENDER TO TEXTURE
1479
if(!render_to_texture)
1484
// save depth buffer
1485
// grFramebufferCopyExt(0, 0, width, height,
1486
// GR_FBCOPY_BUFFER_BACK, GR_FBCOPY_BUFFER_FRONT,
1487
// GR_FBCOPY_MODE_DEPTH);
1489
savedHeight = height;
1490
savedWidtho = widtho;
1491
savedHeighto = heighto;
1496
glMatrixMode(GL_MODELVIEW);
1498
glTranslatef(0, 0, 1-zscale);
1499
glScalef(1, 1, zscale);
1500
inverted_culling = 0;
1502
float m[4*4] = {1.0f, 0.0f, 0.0f, 0.0f,
1503
0.0f,-1.0f, 0.0f, 0.0f,
1504
0.0f, 0.0f, 1.0f, 0.0f,
1505
0.0f, 0.0f, 0.0f, 1.0f};
1506
glMatrixMode(GL_MODELVIEW);
1509
glTranslatef(0, 0, 1-zscale);
1510
glScalef(1, 1*1, zscale);
1511
inverted_culling = 1;
1512
grCullMode(culling_mode);
1515
render_to_texture = 1;
1518
display_warning("grRenderBuffer : unknown buffer : %x", buffer);
1522
FX_ENTRY void FX_CALL
1523
grAuxBufferExt( GrBuffer_t buffer )
1525
LOG("grAuxBufferExt(%d)\r\n", buffer);
1526
//display_warning("grAuxBufferExt");
1528
if (glsl_support && buffer == GR_BUFFER_AUXBUFFER) {
1531
need_to_compile = 0;
1533
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1534
glEnable(GL_DEPTH_TEST);
1535
glDepthFunc(GL_ALWAYS);
1536
glDisable(GL_CULL_FACE);
1537
glDisable(GL_ALPHA_TEST);
1538
glDepthMask(GL_TRUE);
1539
grTexFilterMode(GR_TMU1, GR_TEXTUREFILTER_POINT_SAMPLED, GR_TEXTUREFILTER_POINT_SAMPLED);
1540
// glActiveTextureARB(texture_unit);
1541
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1542
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1544
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1545
need_to_compile = 1;
1549
FX_ENTRY void FX_CALL
1550
grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU32 depth )
1552
LOG("grBufferClear(%d,%d,%d)\r\n", color, alpha, depth);
1553
switch(lfb_color_fmt)
1555
case GR_COLORFORMAT_ARGB:
1556
glClearColor(((color >> 16) & 0xFF) / 255.0f,
1557
((color >> 8) & 0xFF) / 255.0f,
1558
( color & 0xFF) / 255.0f,
1561
case GR_COLORFORMAT_RGBA:
1562
glClearColor(((color >> 24) & 0xFF) / 255.0f,
1563
((color >> 16) & 0xFF) / 255.0f,
1564
(color & 0xFF) / 255.0f,
1568
display_warning("grBufferClear: unknown color format : %x", lfb_color_fmt);
1572
glClearDepth(1.0f - ((1.0f + (depth >> 4) / 4096.0f) * (1 << (depth & 0xF))) / 65528.0);
1574
glClearDepth(depth / 65535.0f);
1575
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1577
// ZIGGY TODO check that color mask is on
1578
buffer_cleared = TRUE;
1583
extern void (*renderCallback)();
1585
// #include <unistd.h>
1586
FX_ENTRY void FX_CALL
1587
grBufferSwap( FxU32 swap_interval )
1590
(*renderCallback)();
1592
LOG("grBufferSwap(%d)\r\n", swap_interval);
1594
if (render_to_texture) {
1595
display_warning("swap while render_to_texture\n");
1599
SDL_GL_SwapBuffers();
1600
for (i = 0; i < nb_fb; i++)
1601
fbs[i].buff_clear = 1;
1607
while (SDL_PollEvent(&event)) {
1608
switch (event.type) {
1610
switch (event.key.keysym.sym) {
1612
printf("Dumping !\n");
1616
static int wireframe;
1617
wireframe = !wireframe;
1618
glPolygonMode(GL_FRONT_AND_BACK, wireframe? GL_LINE : GL_FILL);
1632
FX_ENTRY FxBool FX_CALL
1633
grLfbLock( GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode,
1634
GrOriginLocation_t origin, FxBool pixelPipeline,
1637
LOG("grLfbLock(%d,%d,%d,%d,%d)\r\n", type, buffer, writeMode, origin, pixelPipeline);
1638
if (type == GR_LFB_WRITE_ONLY)
1640
display_warning("grLfbLock : write only");
1649
case GR_BUFFER_FRONTBUFFER:
1650
glReadBuffer(GL_FRONT);
1652
case GR_BUFFER_BACKBUFFER:
1653
glReadBuffer(GL_BACK);
1655
/*case GR_BUFFER_AUXBUFFER:
1656
glReadBuffer(current_buffer);
1659
display_warning("grLfbLock : unknown buffer : %x", buffer);
1662
if(buffer != GR_BUFFER_AUXBUFFER)
1664
if (writeMode == GR_LFBWRITEMODE_888) {
1665
info->lfbPtr = frameBuffer;
1666
info->strideInBytes = width*4;
1667
info->writeMode = GR_LFBWRITEMODE_888;
1668
info->origin = origin;
1669
glReadPixels(0, viewport_offset, width, height, GL_BGRA, GL_UNSIGNED_BYTE, frameBuffer);
1671
buf = (unsigned char*)malloc(width*height*4);
1673
info->lfbPtr = frameBuffer;
1674
info->strideInBytes = width*2;
1675
info->writeMode = GR_LFBWRITEMODE_565;
1676
info->origin = origin;
1677
glReadPixels(0, viewport_offset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1679
for (j=0; j<height; j++)
1681
for (i=0; i<width; i++)
1683
frameBuffer[(height-j-1)*width+i] =
1684
((buf[j*width*4+i*4+0] >> 3) << 11) |
1685
((buf[j*width*4+i*4+1] >> 2) << 5) |
1686
(buf[j*width*4+i*4+2] >> 3);
1689
//adler32b = adler32(0, (const unsigned char*)frameBuffer, width*height*2);
1695
info->lfbPtr = depthBuffer;
1696
info->strideInBytes = width*2;
1697
info->writeMode = GR_LFBWRITEMODE_ZA16;
1698
info->origin = origin;
1699
glReadPixels(0, viewport_offset, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
1706
FX_ENTRY FxBool FX_CALL
1707
grLfbUnlock( GrLock_t type, GrBuffer_t buffer )
1709
LOG("grLfbUnlock(%d,%d)\r\n", type, buffer);
1710
if (type == GR_LFB_WRITE_ONLY)
1712
display_warning("grLfbUnlock : write only");
1717
FX_ENTRY FxBool FX_CALL
1718
grLfbReadRegion( GrBuffer_t src_buffer,
1719
FxU32 src_x, FxU32 src_y,
1720
FxU32 src_width, FxU32 src_height,
1721
FxU32 dst_stride, void *dst_data )
1725
unsigned short *frameBuffer = (unsigned short*)dst_data;
1726
unsigned short *depthBuffer = (unsigned short*)dst_data;
1727
LOG("grLfbReadRegion(%d,%d,%d,%d,%d,%d)\r\n", src_buffer, src_x, src_y, src_width, src_height, dst_stride);
1731
case GR_BUFFER_FRONTBUFFER:
1732
glReadBuffer(GL_FRONT);
1734
case GR_BUFFER_BACKBUFFER:
1735
glReadBuffer(GL_BACK);
1737
/*case GR_BUFFER_AUXBUFFER:
1738
glReadBuffer(current_buffer);
1741
display_warning("grReadRegion : unknown buffer : %x", src_buffer);
1744
if(src_buffer != GR_BUFFER_AUXBUFFER)
1746
buf = (unsigned char*)malloc(src_width*src_height*4);
1748
glReadPixels(src_x, (viewport_offset)+height-src_y-src_height, src_width, src_height, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1750
for (j=0; j<src_height; j++)
1752
for (i=0; i<src_width; i++)
1754
frameBuffer[j*(dst_stride/2)+i] =
1755
((buf[(src_height-j-1)*src_width*4+i*4+0] >> 3) << 11) |
1756
((buf[(src_height-j-1)*src_width*4+i*4+1] >> 2) << 5) |
1757
(buf[(src_height-j-1)*src_width*4+i*4+2] >> 3);
1764
buf = (unsigned char*)malloc(src_width*src_height*2);
1766
glReadPixels(src_x, (viewport_offset)+height-src_y-src_height, src_width, src_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
1768
for (j=0;j<src_height; j++)
1770
for (i=0; i<src_width; i++)
1772
depthBuffer[j*(dst_stride/2)+i] =
1773
((unsigned short*)buf)[(src_height-j-1)*src_width*4+i*4];
1782
FX_ENTRY FxBool FX_CALL
1783
grLfbWriteRegion( GrBuffer_t dst_buffer,
1784
FxU32 dst_x, FxU32 dst_y,
1785
GrLfbSrcFmt_t src_format,
1786
FxU32 src_width, FxU32 src_height,
1787
FxBool pixelPipeline,
1788
FxI32 src_stride, void *src_data )
1792
unsigned short *frameBuffer = (unsigned short*)src_data;
1794
unsigned int tex_width = 1, tex_height = 1;
1795
LOG("grLfbWriteRegion(%d,%d,%d,%d,%d,%d,%d,%d)\r\n",dst_buffer, dst_x, dst_y, src_format, src_width, src_height, pixelPipeline, src_stride);
1797
glPushAttrib(GL_ALL_ATTRIB_BITS);
1799
while (tex_width < src_width) tex_width <<= 1;
1800
while (tex_height < src_height) tex_height <<= 1;
1804
case GR_BUFFER_BACKBUFFER:
1805
glDrawBuffer(GL_BACK);
1807
case GR_BUFFER_AUXBUFFER:
1808
glDrawBuffer(current_buffer);
1811
display_warning("grLfbWriteRegion : unknown buffer : %x", dst_buffer);
1814
if(dst_buffer != GR_BUFFER_AUXBUFFER)
1816
buf = (unsigned char*)malloc(tex_width*tex_height*4);
1820
switch(nbTextureUnits)
1823
texture_number = GL_TEXTURE1_ARB;
1826
texture_number = GL_TEXTURE2_ARB;
1829
texture_number = GL_TEXTURE3_ARB;
1832
else texture_number = GL_TEXTURE0_ARB;
1833
glActiveTextureARB(texture_number);
1837
case GR_LFB_SRC_FMT_1555:
1838
for (j=0; j<src_height; j++)
1840
for (i=0; i<src_width; i++)
1842
buf[j*tex_width*4+i*4+0]=((frameBuffer[j*(src_stride/2)+i]>>10)&0x1F)<<3;
1843
buf[j*tex_width*4+i*4+1]=((frameBuffer[j*(src_stride/2)+i]>> 5)&0x1F)<<3;
1844
buf[j*tex_width*4+i*4+2]=((frameBuffer[j*(src_stride/2)+i]>> 0)&0x1F)<<3;
1845
buf[j*tex_width*4+i*4+3]=(frameBuffer[j*(src_stride/2)+i]>>15)?0xFF:0;
1849
case GR_LFBWRITEMODE_555:
1850
for (j=0; j<src_height; j++)
1852
for (i=0; i<src_width; i++)
1854
buf[j*tex_width*4+i*4+0]=((frameBuffer[j*(src_stride/2)+i]>>10)&0x1F)<<3;
1855
buf[j*tex_width*4+i*4+1]=((frameBuffer[j*(src_stride/2)+i]>> 5)&0x1F)<<3;
1856
buf[j*tex_width*4+i*4+2]=((frameBuffer[j*(src_stride/2)+i]>> 0)&0x1F)<<3;
1857
buf[j*tex_width*4+i*4+3]=0xFF;
1862
display_warning("grLfbWriteRegion : unknown format : %d", src_format);
1867
ilTexImage(tex_width, tex_height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, buf);
1870
sprintf(name, "dump/writecolor%d.png", id++);
1872
printf("dumped gdLfbWriteRegion %s\n", name);
1876
glBindTexture(GL_TEXTURE_2D, default_texture);
1877
glTexImage2D(GL_TEXTURE_2D, 0, 4, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1882
glDisable(GL_DEPTH_TEST);
1883
glDisable(GL_BLEND);
1884
render_rectangle(texture_number,
1886
src_width, src_height,
1887
tex_width, tex_height, +1);
1892
float *buf = (float*)malloc(src_width*(src_height+(viewport_offset))*sizeof(float));
1894
if (src_format != GR_LFBWRITEMODE_ZA16)
1895
display_warning("unknown depth buffer write format:%x", src_format);
1898
display_warning("dst_x:%d, dst_y:%d\n",dst_x, dst_y);
1900
for (j=0; j<src_height; j++)
1902
for (i=0; i<src_width; i++)
1904
buf[(j+(viewport_offset))*src_width+i] =
1905
(frameBuffer[(src_height-j-1)*(src_stride/2)+i]/(65536.0f*(2.0f/zscale)))+1-zscale/2.0f;
1906
//(frameBuffer[(src_height-j-1)*(src_stride/2)+i]/(65536.0f));
1912
unsigned char * buf2 = (unsigned char *)malloc(src_width*(src_height+(viewport_offset)));
1913
for (i=0; i<src_width*src_height ; i++)
1914
buf2[i] = (unsigned char) (buf[i] * 255.0f);
1915
ilTexImage(src_width, src_height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, buf2);
1918
sprintf(name, "dump/writedepth%d.png", id++);
1920
printf("dumped gdLfbWriteRegion %s\n", name);
1926
//printf("zrite %d, back %d\n", num++, dst_buffer == GR_BUFFER_BACKBUFFER);
1927
glEnable(GL_DEPTH_TEST);
1928
glDepthFunc(GL_ALWAYS);
1930
glDrawBuffer(GL_BACK);
1931
glClear( GL_DEPTH_BUFFER_BIT );
1933
//glDisable(GL_DEPTH_TEST);
1935
glDrawPixels(src_width, src_height+(viewport_offset), GL_DEPTH_COMPONENT, GL_FLOAT, buf);
1941
glDrawBuffer(current_buffer);
1946
// unused by glide64
1948
FX_ENTRY FxI32 FX_CALL
1949
grQueryResolutions( const GrResolution *resTemplate, GrResolution *output )
1955
display_warning("grQueryResolutions");
1956
if ((unsigned int)resTemplate->resolution != GR_QUERY_ANY)
1958
res_inf = res_sup = resTemplate->resolution;
1960
if ((unsigned int)resTemplate->refresh == GR_QUERY_ANY) display_warning("querying any refresh rate");
1961
if ((unsigned int)resTemplate->numAuxBuffers == GR_QUERY_ANY) display_warning("querying any numAuxBuffers");
1962
if ((unsigned int)resTemplate->numColorBuffers == GR_QUERY_ANY) display_warning("querying any numColorBuffers");
1964
if (output == NULL) return res_sup - res_inf + 1;
1965
for (i=res_inf; i<=res_sup; i++)
1967
output[n].resolution = i;
1968
output[n].refresh = resTemplate->refresh;
1969
output[n].numAuxBuffers = resTemplate->numAuxBuffers;
1970
output[n].numColorBuffers = resTemplate->numColorBuffers;
1973
return res_sup - res_inf + 1;
1976
FX_ENTRY FxBool FX_CALL
1977
grReset( FxU32 what )
1979
display_warning("grReset");
1983
FX_ENTRY void FX_CALL
1984
grEnable( GrEnableMode_t mode )
1986
display_warning("grEnable");
1989
FX_ENTRY void FX_CALL
1990
grDisable( GrEnableMode_t mode )
1992
display_warning("grDisable");
1995
FX_ENTRY void FX_CALL
1996
grDisableAllEffects( void )
1998
display_warning("grDisableAllEffects");
2001
FX_ENTRY void FX_CALL
2002
grErrorSetCallback( GrErrorCallbackFnc_t fnc )
2004
display_warning("grErrorSetCallback");
2007
FX_ENTRY void FX_CALL
2010
display_warning("grFinish");
2013
FX_ENTRY void FX_CALL
2016
display_warning("grFlush");
2019
FX_ENTRY void FX_CALL
2020
grTexMultibase( GrChipID_t tmu,
2023
display_warning("grTexMultibase");
2026
FX_ENTRY void FX_CALL
2027
grTexMipMapMode( GrChipID_t tmu,
2028
GrMipMapMode_t mode,
2031
display_warning("grTexMipMapMode");
2034
FX_ENTRY void FX_CALL
2035
grTexDownloadTablePartial( GrTexTable_t type,
2040
display_warning("grTexDownloadTablePartial");
2043
FX_ENTRY void FX_CALL
2044
grTexDownloadTable( GrTexTable_t type,
2047
display_warning("grTexDownloadTable");
2050
FX_ENTRY FxBool FX_CALL
2051
grTexDownloadMipMapLevelPartial( GrChipID_t tmu,
2055
GrAspectRatio_t aspectRatio,
2056
GrTextureFormat_t format,
2062
display_warning("grTexDownloadMipMapLevelPartial");
2066
FX_ENTRY void FX_CALL
2067
grTexDownloadMipMapLevel( GrChipID_t tmu,
2071
GrAspectRatio_t aspectRatio,
2072
GrTextureFormat_t format,
2076
display_warning("grTexDownloadMipMapLevel");
2079
FX_ENTRY void FX_CALL
2080
grTexNCCTable( GrNCCTable_t table )
2082
display_warning("grTexNCCTable");
2085
FX_ENTRY void FX_CALL
2086
grViewport( FxI32 x, FxI32 y, FxI32 width, FxI32 height )
2088
display_warning("grViewport");
2091
FX_ENTRY void FX_CALL
2092
grDepthRange( FxFloat n, FxFloat f )
2094
display_warning("grDepthRange");
2097
FX_ENTRY void FX_CALL
2098
grSplash(float x, float y, float width, float height, FxU32 frame)
2100
display_warning("grSplash");
2103
FX_ENTRY FxBool FX_CALL
2104
grSelectContext( GrContext_t context )
2106
display_warning("grSelectContext");
2110
FX_ENTRY void FX_CALL
2112
const void *a, const void *b, const void *c,
2113
FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias
2116
display_warning("grAADrawTriangle");
2119
FX_ENTRY void FX_CALL
2120
grAlphaControlsITRGBLighting( FxBool enable )
2122
display_warning("grAlphaControlsITRGBLighting");
2125
FX_ENTRY void FX_CALL
2126
grGlideSetVertexLayout( const void *layout )
2128
display_warning("grGlideSetVertexLayout");
2131
FX_ENTRY void FX_CALL
2132
grGlideGetVertexLayout( void *layout )
2134
display_warning("grGlideGetVertexLayout");
2137
FX_ENTRY void FX_CALL
2138
grGlideSetState( const void *state )
2140
display_warning("grGlideSetState");
2143
FX_ENTRY void FX_CALL
2144
grGlideGetState( void *state )
2146
display_warning("grGlideGetState");
2149
FX_ENTRY void FX_CALL
2150
grLfbWriteColorFormat(GrColorFormat_t colorFormat)
2152
display_warning("grLfbWriteColorFormat");
2155
FX_ENTRY void FX_CALL
2156
grLfbWriteColorSwizzle(FxBool swizzleBytes, FxBool swapWords)
2158
display_warning("grLfbWriteColorSwizzle");
2161
FX_ENTRY void FX_CALL
2162
grLfbConstantDepth( FxU32 depth )
2164
display_warning("grLfbConstantDepth");
2167
FX_ENTRY void FX_CALL
2168
grLfbConstantAlpha( GrAlpha_t alpha )
2170
display_warning("grLfbConstantAlpha");
2173
FX_ENTRY void FX_CALL
2174
grTexMultibaseAddress( GrChipID_t tmu,
2175
GrTexBaseRange_t range,
2180
display_warning("grTexMultibaseAddress");
2183
FX_ENTRY void FX_CALL
2184
grLoadGammaTable( FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue)
2186
display_warning("grLoadGammaTable");
2189
FX_ENTRY void FX_CALL
2190
grDitherMode( GrDitherMode_t mode )
2192
display_warning("grDitherMode");
2195
void grChromaRangeExt(GrColor_t color0, GrColor_t color1, FxU32 mode)
2197
display_warning("grChromaRangeExt");
2200
void grChromaRangeModeExt(GrChromakeyMode_t mode)
2202
display_warning("grChromaRangeModeExt");
2205
void grTexChromaRangeExt(GrChipID_t tmu, GrColor_t color0, GrColor_t color1, GrTexChromakeyMode_t mode)
2207
display_warning("grTexChromaRangeExt");
2210
void grTexChromaModeExt(GrChipID_t tmu, GrChromakeyMode_t mode)
2212
display_warning("grTexChromaRangeModeExt");
2221
static int tl[10240];
2229
ilEnable(IL_FILE_OVERWRITE);
2237
if (!dumping) return;
2240
for (i=0; i<nb_fb; i++) {
2241
dump_tex(fbs[i].texid);
2243
dump_tex(default_texture);
2244
dump_tex(depth_texture);
2248
glReadBuffer(GL_FRONT);
2249
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer);
2250
ilTexImage(width, height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, frameBuffer);
2251
ilSaveImage("dump/framecolor.png");
2252
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depthBuffer);
2253
// FILE * fp = fopen("glide_depth1.bin", "rb");
2254
// fread(depthBuffer, 2, width*height, fp);
2256
unsigned char *frameByte = (unsigned char *) frameBuffer;
2257
for (j=0; j<height; j++) {
2258
for (i=0; i<width; i++) {
2259
//uint16_t d = ( (uint16_t *)depthBuffer )[i+(height-1-j)*width]/2 + 0x8000;
2260
uint16_t d = ( (uint16_t *)depthBuffer )[i+j*width];
2261
unsigned char c = frameByte[(i+j*width)*4];
2262
frameByte[(i+j*width)*3] = d&0xff;
2263
frameByte[(i+j*width)*3+1] = d>>8;
2264
frameByte[(i+j*width)*3+2] = c&0xff;
2267
ilTexImage(width, height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, frameBuffer);
2268
ilSaveImage("dump/framedepth.png");
2270
for (i=0; i<tl_i; i++) {
2271
glBindTexture(GL_TEXTURE_2D, tl[i]);
2273
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
2274
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
2275
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
2276
fprintf(stderr, "Texture %d %dx%d fmt %x\n", tl[i], (int)w, (int)h, (int) fmt);
2278
uint32_t * pixels = (uint32_t *) malloc(w*h*4);
2279
// 0x1902 is another constant meaning GL_DEPTH_COMPONENT
2280
// (but isn't defined in gl's headers !!)
2281
if (fmt != GL_DEPTH_COMPONENT && fmt != 0x1902) {
2282
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2283
ilTexImage(w, h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pixels);
2285
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixels);
2287
for (i=0; i<w*h; i++)
2288
((unsigned char *)frameBuffer)[i] = ((unsigned short *)pixels)[i]/256;
2289
ilTexImage(w, h, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, frameBuffer);
2292
// sprintf(name, "mkdir -p dump ; rm -f dump/tex%04d.png", i);
2294
sprintf(name, "dump/tex%04d.png", i);
2295
fprintf(stderr, "Writing '%s'\n", name);
2298
// SDL_FreeSurface(surf);
2301
glBindTexture(GL_TEXTURE_2D, default_texture);
2304
void dump_tex(int id)
2306
if (!dumping) return;
2309
// yes, it's inefficient
2310
for (n=0; n<tl_i; n++)