new texture compression infrastructure
[mesa.git] / src / mesa / drivers / windows / wmesaBackup.c
1 /* $Id: wmesaBackup.c,v 1.3 2001/03/03 20:33:29 brianp Exp $ */
2
3 /*
4 * File name : wmesa.c
5 * Version : 2.3
6 *
7 * Display driver for Mesa 2.3 under
8 * Windows95 and WindowsNT
9 *
10 * Copyright (C) 1996- Li Wei
11 * Address : Institute of Artificial Intelligence
12 * : & Robotics
13 * : Xi'an Jiaotong University
14 * Email : liwei@aiar.xjtu.edu.cn
15 * Web page : http://sun.aiar.xjtu.edu.cn
16 *
17 * This file and its associations are partially borrowed from the
18 * Windows NT driver for Mesa 1.8 , written by Mark Leaming
19 * (mark@rsinc.com).
20 */
21
22
23 /*
24 * $Log: wmesaBackup.c,v $
25 * Revision 1.3 2001/03/03 20:33:29 brianp
26 * lots of gl_*() to _mesa_*() namespace clean-up
27 *
28 * Revision 1.2 2000/11/05 18:41:00 keithw
29 * - Changes for new software rasterizer modules
30 * - Remove support for choosing software fallbacks from core code
31 * - Remove partial fallback code from vbrender.c -- drivers are now
32 * expected to be able to find a triangle/quad function for every state,
33 * even if they have to use _swsetup_Triangle or _swsetup_Quad.
34 * - Marked derived variables in the GLcontext struct with a leading
35 * underscore '_'.
36 *
37 * Revision 1.1.1.1 1999/08/19 00:55:42 jtg
38 * Imported sources
39 *
40 * Revision 1.1 1999/01/03 03:08:57 brianp
41 * Initial revision
42 *
43 * Revision 3.1 1998/06/11 01:42:08 brianp
44 * updated for Mesa 3.0 device driver interface (but not tested)
45 *
46 * Revision 3.0 1998/06/11 01:18:25 brianp
47 * initial revision
48 *
49 */
50
51
52 #define WMESA_STEREO_C
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <GL/wmesa.h>
57 #include "mesa_extend.h"
58 #include "colors.h"
59 #include "macros.h"
60 #include "context.h"
61 #include "dd.h"
62 #include "xform.h"
63 #include "vb.h"
64 #include "matrix.h"
65 #include "depth.h"
66 #include "wmesadef.h"
67
68 #pragma warning ( disable : 4133 4761 )
69
70 #ifdef PROFILE
71 // #include "profile.h"
72 #endif
73
74 #ifdef DITHER
75 #include <wing.h>
76 #endif
77
78 #ifdef __CYGWIN32__
79 #include "macros.h"
80 #include <string.h>
81 #define CopyMemory memcpy
82 #endif
83
84 #if !defined(NO_STEREO)
85
86 #include "gl\glu.h"
87 #include "stereo.h"
88
89 #endif
90 #if !defined(NO_PARALLEL)
91 // #include "parallel.h"
92 #endif
93
94 struct DISPLAY_OPTIONS displayOptions;
95
96 GLenum stereoCompile = GL_FALSE ;
97 GLenum stereoShowing = GL_FALSE ;
98 GLenum stereoBuffer = GL_FALSE;
99 #if !defined(NO_STEREO)
100 GLint displayList = MAXIMUM_DISPLAY_LIST ;
101 #endif
102 GLint stereo_flag = 0 ;
103
104 /* end of added code*/
105
106 static PWMC Current = NULL;
107 WMesaContext WC = NULL;
108
109 #ifdef NDEBUG
110 #define assert(ignore) ((void) 0)
111 #else
112 void Mesa_Assert(void *Cond,void *File,unsigned Line)
113 {
114 char Msg[512];
115 sprintf(Msg,"%s %s %d",Cond,File,Line);
116 MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
117 exit(1);
118 }
119 #define assert(e) if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
120 #endif
121
122 //#define DD_GETDC (Current->hDC )
123 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
124 //#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
125 #define DD_RELEASEDC
126
127 //#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);
128 #define BEGINGDICALL
129 //#define ENDGDICALL if(Current->rgb_flag)wmGetBits(Current);
130 #define ENDGDICALL
131
132 //#define FLIP(Y) (Current->dither_flag? Y : Current->height-(Y)-1)
133 //#define FLIP(Y) (Current->height-(Y)-1)
134 //#define FLIP(Y) Y
135 #define FLIP(Y) (Current->db_flag? Y: Current->height-(Y)-1)
136 #define STARTPROFILE
137 #define ENDPROFILE(PARA)
138
139 #define DITHER_RGB_TO_8BIT_SETUP \
140 GLubyte pixelDithered;
141
142 #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \
143 { \
144 char unsigned redtemp, greentemp, bluetemp, paletteindex; \
145 redtemp = aDividedBy51[red] \
146 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 \
147 + scanline%8]); \
148 greentemp = aDividedBy51[(char unsigned)green] \
149 + (aModulo51[green] > aHalftone8x8[ \
150 (pixel%8)*8 + scanline%8]); \
151 bluetemp = aDividedBy51[(char unsigned)blue] \
152 + (aModulo51[blue] > aHalftone8x8[ \
153 (pixel%8)*8 +scanline%8]); \
154 paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; \
155 pixelDithered = aWinGHalftoneTranslation[paletteindex]; \
156 }
157
158
159 #ifdef DDRAW
160 static BOOL DDInit( WMesaContext wc, HWND hwnd);
161 static void DDFree( WMesaContext wc);
162 static HRESULT DDRestoreAll( WMesaContext wc );
163 static void DDDeleteOffScreen(WMesaContext wc);
164 static BOOL DDCreateOffScreen(WMesaContext wc);
165 #endif
166
167 static void FlushToFile(PWMC pwc, PSTR szFile);
168
169 BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
170 BOOL wmDeleteBackingStore(PWMC pwc);
171 void wmCreatePalette( PWMC pwdc );
172 BOOL wmSetDibColors(PWMC pwc);
173 void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
174
175 void wmCreateDIBSection(
176 HDC hDC,
177 PWMC pwc, // handle of device context
178 CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
179 UINT iUsage // color data type indicator: RGB values or palette indices
180 );
181
182
183 void WMesaViewport( GLcontext *ctx,
184 GLint x, GLint y, GLsizei width, GLsizei height );
185
186
187 static triangle_func choose_triangle_function( GLcontext *ctx );
188
189
190 static void wmSetPixelFormat( PWMC wc, HDC hDC)
191 {
192 if(wc->rgb_flag)
193 wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
194 else
195 wc->cColorBits = 8;
196 switch(wc->cColorBits){
197 case 8:
198 if(wc->dither_flag != GL_TRUE)
199 wc->pixelformat = PF_INDEX8;
200 else
201 wc->pixelformat = PF_DITHER8;
202 break;
203 case 16:
204 wc->pixelformat = PF_5R6G5B;
205 break;
206 case 32:
207 wc->pixelformat = PF_8R8G8B;
208 break;
209 default:
210 wc->pixelformat = PF_BADFORMAT;
211 }
212 }
213
214 //
215 // This function sets the color table of a DIB section
216 // to match that of the destination DC
217 //
218 BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
219 {
220 RGBQUAD *pColTab, *pRGB;
221 PALETTEENTRY *pPal, *pPE;
222 int i, nColors;
223 BOOL bRet=TRUE;
224 DWORD dwErr=0;
225
226 /* Build a color table in the DIB that maps to the
227 selected palette in the DC.
228 */
229 nColors = 1 << pwc->cColorBits;
230 pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
231 memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
232 GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
233 pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
234 for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
235 pRGB->rgbRed = pPE->peRed;
236 pRGB->rgbGreen = pPE->peGreen;
237 pRGB->rgbBlue = pPE->peBlue;
238 }
239 if(pwc->db_flag)
240 bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
241
242 if(!bRet)
243 dwErr = GetLastError();
244
245 free( pColTab );
246 free( pPal );
247
248 return(bRet);
249 }
250
251
252 //
253 // Free up the dib section that was created
254 //
255 BOOL wmDeleteBackingStore(PWMC pwc)
256 {
257 SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
258 DeleteDC(pwc->dib.hDC);
259 DeleteObject(pwc->hbmDIB);
260 UnmapViewOfFile(pwc->dib.base);
261 CloseHandle(pwc->dib.hFileMap);
262 return TRUE;
263 }
264
265
266 //
267 // This function creates the DIB section that is used for combined
268 // GL and GDI calls
269 //
270 BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
271 {
272 HDC hdc = pwc->hDC;
273 LPBITMAPINFO pbmi = &(pwc->bmi);
274 int iUsage;
275
276 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
277 pbmi->bmiHeader.biWidth = lxSize;
278 pbmi->bmiHeader.biHeight= -lySize;
279 pbmi->bmiHeader.biPlanes = 1;
280 if(pwc->rgb_flag)
281 pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
282 else
283 pbmi->bmiHeader.biBitCount = 8;
284 pbmi->bmiHeader.biCompression = BI_RGB;
285 pbmi->bmiHeader.biSizeImage = 0;
286 pbmi->bmiHeader.biXPelsPerMeter = 0;
287 pbmi->bmiHeader.biYPelsPerMeter = 0;
288 pbmi->bmiHeader.biClrUsed = 0;
289 pbmi->bmiHeader.biClrImportant = 0;
290
291 iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
292
293 pwc->cColorBits = pbmi->bmiHeader.biBitCount;
294 pwc->ScanWidth = pwc->pitch = lxSize;
295
296 wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
297
298 if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
299 wmCreatePalette( pwc );
300 wmSetDibColors( pwc );
301 }
302 wmSetPixelFormat(pwc, pwc->hDC);
303 return(TRUE);
304
305 }
306
307
308 //
309 // This function copies one scan line in a DIB section to another
310 //
311 BOOL GLWINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
312 {
313 UINT uiScans = 0;
314 LPBYTE pDest = pwc->pbPixels;
315 DWORD dwNextScan = uiScanWidth;
316 DWORD dwNewScan = uiNewWidth;
317 DWORD dwScanWidth = (uiScanWidth * nBypp);
318
319 //
320 // We need to round up to the nearest DWORD
321 // and multiply by the number of bytes per
322 // pixel
323 //
324 dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
325 dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
326
327 for(uiScans = 0; uiScans < uiNumScans; uiScans++){
328 CopyMemory(pDest, pBits, dwScanWidth);
329 pBits += dwNextScan;
330 pDest += dwNewScan;
331 }
332
333 return(TRUE);
334
335 }
336
337
338 BOOL wmFlush(PWMC pwc);
339
340 /*
341 * Useful macros:
342 Modified from file osmesa.c
343 */
344
345
346 #define PIXELADDR(X,Y) ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
347 #define PIXELADDR1( X, Y ) \
348 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
349 #define PIXELADDR2( X, Y ) \
350 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
351 #define PIXELADDR4( X, Y ) \
352 ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
353
354
355 BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
356
357 /* Finish all pending operations and synchronize. */
358 static void finish(GLcontext* ctx)
359 {
360 /* No op */
361 }
362
363
364 //
365 // We cache all gl draw routines until a flush is made
366 //
367 static void flush(GLcontext* ctx)
368 {
369 STARTPROFILE
370 if((Current->rgb_flag /*&& !(Current->dib.fFlushed)*/&&!(Current->db_flag))
371 ||(!Current->rgb_flag))
372 {
373 wmFlush(Current);
374 }
375 ENDPROFILE(flush)
376
377 }
378
379
380
381 /*
382 * Set the color index used to clear the color buffer.
383 */
384 static void clear_index(GLcontext* ctx, GLuint index)
385 {
386 STARTPROFILE
387 Current->clearpixel = index;
388 ENDPROFILE(clear_index)
389 }
390
391
392
393 /*
394 * Set the color used to clear the color buffer.
395 */
396 static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
397 {
398 STARTPROFILE
399 Current->clearpixel=RGB(r, g, b );
400 ENDPROFILE(clear_color)
401 }
402
403
404
405 /*
406 * Clear the specified region of the color buffer using the clear color
407 * or index as specified by one of the two functions above.
408 */
409 //static void clear(GLcontext* ctx,
410 // GLboolean all,GLint x, GLint y, GLint width, GLint height )
411 // TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
412 // dd.h does not explain what the return type is so I could not set this to the proper
413 // value.
414 static GLbitfield clear(GLcontext* ctx, GLbitfield mask,
415 GLboolean all, GLint x, GLint y, GLint width, GLint height)
416 {
417 DWORD dwColor;
418 WORD wColor;
419 BYTE bColor;
420 LPDWORD lpdw = (LPDWORD)Current->pbPixels;
421 LPWORD lpw = (LPWORD)Current->pbPixels;
422 LPBYTE lpb = Current->pbPixels;
423 int lines;
424
425 STARTPROFILE
426
427 if (all){
428 x=y=0;
429 width=Current->width;
430 height=Current->height;
431 }
432 if(Current->db_flag==GL_TRUE){
433 UINT nBypp = Current->cColorBits / 8;
434 int i = 0;
435 int iSize = 0;
436
437 if(nBypp ==1 ){
438 /* Need rectification */
439 iSize = Current->width/4;
440 bColor = BGR8(GetRValue(Current->clearpixel),
441 GetGValue(Current->clearpixel),
442 GetBValue(Current->clearpixel));
443 wColor = MAKEWORD(bColor,bColor);
444 dwColor = MAKELONG(wColor, wColor);
445 }
446 if(nBypp == 2){
447 iSize = Current->width / 2;
448 wColor = BGR16(GetRValue(Current->clearpixel),
449 GetGValue(Current->clearpixel),
450 GetBValue(Current->clearpixel));
451 dwColor = MAKELONG(wColor, wColor);
452 }
453 else if(nBypp == 4){
454 iSize = Current->width;
455 dwColor = BGR32(GetRValue(Current->clearpixel),
456 GetGValue(Current->clearpixel),
457 GetBValue(Current->clearpixel));
458 }
459
460 while(i < iSize){
461 *lpdw = dwColor;
462 lpdw++;
463 i++;
464 }
465
466 //
467 // This is the 24bit case
468 //
469 if (nBypp == 3) {
470 iSize = Current->width *3/4;
471 dwColor = BGR24(GetRValue(Current->clearpixel),
472 GetGValue(Current->clearpixel),
473 GetBValue(Current->clearpixel));
474 while(i < iSize){
475 *lpdw = dwColor;
476 lpb += nBypp;
477 lpdw = (LPDWORD)lpb;
478 i++;
479 }
480 }
481
482 i = 0;
483 if (stereo_flag)
484 lines = height /2;
485 else
486 lines = height;
487 do {
488 memcpy(lpb, Current->pbPixels, iSize*4);
489 lpb += Current->ScanWidth;
490 i++;
491 }
492 while (i<lines-1);
493 }
494 else { // For single buffer
495 HDC DC=DD_GETDC;
496 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
497 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
498 HPEN Old_Pen=SelectObject(DC,Pen);
499 HBRUSH Old_Brush=SelectObject(DC,Brush);
500 Rectangle(DC,x,y,x+width,y+height);
501 SelectObject(DC,Old_Pen);
502 SelectObject(DC,Old_Brush);
503 DeleteObject(Pen);
504 DeleteObject(Brush);
505 DD_RELEASEDC;
506 }
507
508
509
510 ENDPROFILE(clear)
511
512 return mask; // TODO: I doubt this is correct. dd.h doesn't explain what this should
513 // be...
514 }
515
516
517
518 /* Set the current color index. */
519 static void set_index(GLcontext* ctx, GLuint index)
520 {
521 STARTPROFILE
522 Current->pixel=index;
523 ENDPROFILE(set_index)
524 }
525
526
527
528 /* Set the current RGBA color. */
529 static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
530 {
531 STARTPROFILE
532 Current->pixel = RGB( r, g, b );
533 ENDPROFILE(set_color)
534 }
535
536
537
538 /* Set the index mode bitplane mask. */
539 static GLboolean index_mask(GLcontext* ctx, GLuint mask)
540 {
541 /* can't implement */
542 return GL_FALSE;
543 }
544
545
546
547 /* Set the RGBA drawing mask. */
548 static GLboolean color_mask( GLcontext* ctx,
549 GLboolean rmask, GLboolean gmask,
550 GLboolean bmask, GLboolean amask)
551 {
552 /* can't implement */
553 return GL_FALSE;
554 }
555
556
557
558 /*
559 * Set the pixel logic operation. Return GL_TRUE if the device driver
560 * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
561 * is returned, the logic op will be done in software by Mesa.
562 */
563 GLboolean logicop( GLcontext* ctx, GLenum op )
564 {
565 /* can't implement */
566 return GL_FALSE;
567 }
568
569
570 static void dither( GLcontext* ctx, GLboolean enable )
571 {
572 if(enable == GL_FALSE){
573 Current->dither_flag = GL_FALSE;
574 if(Current->cColorBits == 8)
575 Current->pixelformat = PF_INDEX8;
576 }
577 else{
578 if (Current->rgb_flag && Current->cColorBits == 8){
579 Current->pixelformat = PF_DITHER8;
580 Current->dither_flag = GL_TRUE;
581 }
582 else
583 Current->dither_flag = GL_FALSE;
584 }
585 }
586
587
588
589 static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
590 {
591 STARTPROFILE
592 /* TODO: this could be better */
593 if (mode==GL_FRONT || mode==GL_BACK) {
594 return GL_TRUE;
595 }
596 else {
597 return GL_FALSE;
598 }
599 ENDPROFILE(set_buffer)
600 }
601
602
603
604 /* Return characteristics of the output buffer. */
605 static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height )
606 {
607 int New_Size;
608 RECT CR;
609
610 STARTPROFILE
611 GetClientRect(Current->Window,&CR);
612
613 *width=CR.right;
614 *height=CR.bottom;
615
616 New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
617
618 if (New_Size){
619 Current->width=*width;
620 Current->height=*height;
621 Current->ScanWidth=Current->width;
622 if ((Current->ScanWidth%sizeof(long))!=0)
623 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
624
625 if (Current->db_flag){
626 #ifdef DDRAW
627 DDDeleteOffScreen(Current);
628 DDCreateOffScreen(Current);
629 #else
630 if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
631 wmDeleteBackingStore(Current);
632 wmCreateBackingStore(Current, Current->width, Current->height);
633 }
634 #endif
635 }
636
637 // Resize OsmesaBuffer if in Parallel mode
638 #if !defined(NO_PARALLEL)
639 if(parallelFlag)
640 PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
641 Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
642 #endif
643 }
644 ENDPROFILE(buffer_size)
645 }
646
647
648
649 /**********************************************************************/
650 /***** Accelerated point, line, polygon rendering *****/
651 /**********************************************************************/
652
653
654 static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
655 {
656 GLuint i;
657 // HDC DC=DD_GETDC;
658 PWMC pwc = Current;
659
660 STARTPROFILE
661
662 if (Current->gl_ctx->VB->MonoColor) {
663 /* all drawn with current color */
664 for (i=first;i<=last;i++) {
665 if (!Current->gl_ctx->VB->ClipMask[i]) {
666 int x, y;
667 x = (GLint) Current->gl_ctx->VB->Win[i][0];
668 y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
669 wmSetPixel(pwc, y,x,GetRValue(Current->pixel),
670 GetGValue(Current->pixel), GetBValue(Current->pixel));
671 }
672 }
673 }
674 else {
675 /* draw points of different colors */
676 for (i=first;i<=last;i++) {
677 if (!Current->gl_ctx->VB->ClipMask[i]) {
678 int x, y;
679 unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
680 Current->gl_ctx->VB->Color[i][1]*255.0,
681 Current->gl_ctx->VB->Color[i][2]*255.0);
682 x = (GLint) Current->gl_ctx->VB->Win[i][0];
683 y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
684 wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,
685 Current->gl_ctx->VB->Color[i][1]*255.0,
686 Current->gl_ctx->VB->Color[i][2]*255.0);
687 }
688 }
689 }
690 // DD_RELEASEDC;
691 ENDPROFILE(fast_rgb_points)
692 }
693
694
695
696 /* Return pointer to accerated points function */
697 extern points_func choose_points_function( GLcontext* ctx )
698 {
699 STARTPROFILE
700 if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->_RasterMask==0
701 && !ctx->Texture.Enabled && ctx->Visual->RGBAflag) {
702 ENDPROFILE(choose_points_function)
703 return fast_rgb_points;
704 }
705 else {
706 ENDPROFILE(choose_points_function)
707 return NULL;
708 }
709 }
710
711
712
713 /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
714 static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
715 {
716 STARTPROFILE
717 int x0, y0, x1, y1;
718 unsigned long pixel;
719 HDC DC=DD_GETDC;
720 HPEN Pen;
721 HPEN Old_Pen;
722
723 if (Current->gl_ctx->VB->MonoColor) {
724 pixel = Current->pixel; /* use current color */
725 }
726 else {
727 pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
728 }
729
730 x0 = (int) Current->gl_ctx->VB->Win[v0][0];
731 y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
732 x1 = (int) Current->gl_ctx->VB->Win[v1][0];
733 y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
734
735
736 BEGINGDICALL
737
738 Pen=CreatePen(PS_SOLID,1,pixel);
739 Old_Pen=SelectObject(DC,Pen);
740 MoveToEx(DC,x0,y0,NULL);
741 LineTo(DC,x1,y1);
742 SelectObject(DC,Old_Pen);
743 DeleteObject(Pen);
744 DD_RELEASEDC;
745
746 ENDGDICALL
747
748 ENDPROFILE(fast_flat_rgb_line)
749 }
750
751
752
753 /* Return pointer to accerated line function */
754 static line_func choose_line_function( GLcontext* ctx )
755 {
756 STARTPROFILE
757 if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
758 && ctx->Light.ShadeModel==GL_FLAT && ctx->_RasterMask==0
759 && !ctx->Texture.Enabled && Current->rgb_flag) {
760 ENDPROFILE(choose_line_function)
761 return fast_flat_rgb_line;
762 }
763 else {
764 ENDPROFILE(choose_line_function)
765 return NULL;
766 }
767 }
768
769
770 /**********************************************************************/
771 /***** Span-based pixel drawing *****/
772 /**********************************************************************/
773
774
775 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
776 static void write_ci32_span( const GLcontext* ctx,
777 GLuint n, GLint x, GLint y,
778 const GLuint index[],
779 const GLubyte mask[] )
780 {
781 STARTPROFILE
782 GLuint i;
783 PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
784 assert(Current->rgb_flag==GL_FALSE);
785 for (i=0; i<n; i++)
786 if (mask[i])
787 Mem[i]=index[i];
788 ENDPROFILE(write_ci32_span)
789 }
790
791
792 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
793 static void write_ci8_span( const GLcontext* ctx,
794 GLuint n, GLint x, GLint y,
795 const GLubyte index[],
796 const GLubyte mask[] )
797 {
798 STARTPROFILE
799 GLuint i;
800 PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
801 assert(Current->rgb_flag==GL_FALSE);
802 for (i=0; i<n; i++)
803 if (mask[i])
804 Mem[i]=index[i];
805 ENDPROFILE(write_ci8_span)
806 }
807
808
809
810 /*
811 * Write a horizontal span of pixels with a boolean mask. The current
812 * color index is used for all pixels.
813 */
814 static void write_mono_ci_span(const GLcontext* ctx,
815 GLuint n,GLint x,GLint y,
816 const GLubyte mask[])
817 {
818 STARTPROFILE
819 GLuint i;
820 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
821 assert(Current->rgb_flag==GL_FALSE);
822 for (i=0; i<n; i++)
823 if (mask[i])
824 Mem[i]=Current->pixel;
825 ENDPROFILE(write_mono_ci_span)
826 }
827
828 /*
829 * To improve the performance of this routine, frob the data into an actual
830 * scanline and call bitblt on the complete scan line instead of SetPixel.
831 */
832
833 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
834 static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
835 const GLubyte rgba[][4], const GLubyte mask[] )
836 {
837 STARTPROFILE
838 PWMC pwc = Current;
839
840 if (pwc->rgb_flag==GL_TRUE)
841 {
842 GLuint i;
843 HDC DC=DD_GETDC;
844 y=FLIP(y);
845 if (mask) {
846 for (i=0; i<n; i++)
847 if (mask[i])
848 wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
849 }
850 else {
851 for (i=0; i<n; i++)
852 wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
853 }
854 DD_RELEASEDC;
855 }
856 else
857 {
858 GLuint i;
859 BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
860 y = FLIP(y);
861 if (mask) {
862 for (i=0; i<n; i++)
863 if (mask[i])
864 Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
865 }
866 else {
867 for (i=0; i<n; i++)
868 Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
869 }
870 }
871 ENDPROFILE(write_rgba_span)
872
873 }
874
875 /* Write a horizontal span of RGB color pixels with a boolean mask. */
876 static void write_rgb_span( const GLcontext* ctx,
877 GLuint n, GLint x, GLint y,
878 const GLubyte rgb[][3], const GLubyte mask[] )
879 {
880 STARTPROFILE
881 PWMC pwc = Current;
882
883 if (pwc->rgb_flag==GL_TRUE)
884 {
885 GLuint i;
886 HDC DC=DD_GETDC;
887 y=FLIP(y);
888 if (mask) {
889 for (i=0; i<n; i++)
890 if (mask[i])
891 wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
892 }
893 else {
894 for (i=0; i<n; i++)
895 wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
896 }
897 DD_RELEASEDC;
898 }
899 else
900 {
901 GLuint i;
902 BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
903 y = FLIP(y);
904 if (mask) {
905 for (i=0; i<n; i++)
906 if (mask[i])
907 Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
908 }
909 else {
910 for (i=0; i<n; i++)
911 Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
912 }
913 }
914 ENDPROFILE(write_rgb_span)
915
916 }
917
918 /*
919 * Write a horizontal span of pixels with a boolean mask. The current color
920 * is used for all pixels.
921 */
922 static void write_mono_rgba_span( const GLcontext* ctx,
923 GLuint n, GLint x, GLint y,
924 const GLubyte mask[])
925 {
926 STARTPROFILE
927 GLuint i;
928 HDC DC=DD_GETDC;
929 PWMC pwc = Current;
930 assert(Current->rgb_flag==GL_TRUE);
931 y=FLIP(y);
932 if(Current->rgb_flag==GL_TRUE){
933 for (i=0; i<n; i++)
934 if (mask[i])
935 // Trying
936 wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
937 }
938 else {
939 for (i=0; i<n; i++)
940 if (mask[i])
941 SetPixel(DC, y, x+i, Current->pixel);
942 }
943 DD_RELEASEDC;
944 ENDPROFILE(write_mono_rgba_span)
945 }
946
947
948
949 /**********************************************************************/
950 /***** Array-based pixel drawing *****/
951 /**********************************************************************/
952
953
954 /* Write an array of 32-bit index pixels with a boolean mask. */
955 static void write_ci32_pixels( const GLcontext* ctx,
956 GLuint n, const GLint x[], const GLint y[],
957 const GLuint index[], const GLubyte mask[] )
958 {
959 STARTPROFILE
960 GLuint i;
961 assert(Current->rgb_flag==GL_FALSE);
962 for (i=0; i<n; i++) {
963 if (mask[i]) {
964 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
965 *Mem = index[i];
966 }
967 }
968 ENDPROFILE(write_ci32_pixels)
969 }
970
971
972
973 /*
974 * Write an array of pixels with a boolean mask. The current color
975 * index is used for all pixels.
976 */
977 static void write_mono_ci_pixels( const GLcontext* ctx,
978 GLuint n,
979 const GLint x[], const GLint y[],
980 const GLubyte mask[] )
981 {
982 STARTPROFILE
983 GLuint i;
984 assert(Current->rgb_flag==GL_FALSE);
985 for (i=0; i<n; i++) {
986 if (mask[i]) {
987 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
988 *Mem = Current->pixel;
989 }
990 }
991 ENDPROFILE(write_mono_ci_pixels)
992 }
993
994
995
996 /* Write an array of RGBA pixels with a boolean mask. */
997 static void write_rgba_pixels( const GLcontext* ctx,
998 GLuint n, const GLint x[], const GLint y[],
999 const GLubyte rgba[][4], const GLubyte mask[] )
1000 {
1001 STARTPROFILE
1002 GLuint i;
1003 PWMC pwc = Current;
1004 HDC DC=DD_GETDC;
1005 assert(Current->rgb_flag==GL_TRUE);
1006 for (i=0; i<n; i++)
1007 if (mask[i])
1008 wmSetPixel(pwc, FLIP(y[i]),x[i],rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]);
1009 DD_RELEASEDC;
1010 ENDPROFILE(write_rgba_pixels)
1011 }
1012
1013
1014
1015 /*
1016 * Write an array of pixels with a boolean mask. The current color
1017 * is used for all pixels.
1018 */
1019 static void write_mono_rgba_pixels( const GLcontext* ctx,
1020 GLuint n,
1021 const GLint x[], const GLint y[],
1022 const GLubyte mask[] )
1023 {
1024 STARTPROFILE
1025 GLuint i;
1026 PWMC pwc = Current;
1027 HDC DC=DD_GETDC;
1028 assert(Current->rgb_flag==GL_TRUE);
1029 for (i=0; i<n; i++)
1030 if (mask[i])
1031 wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),
1032 GetGValue(Current->pixel), GetBValue(Current->pixel));
1033 DD_RELEASEDC;
1034 ENDPROFILE(write_mono_rgba_pixels)
1035 }
1036
1037
1038
1039 /**********************************************************************/
1040 /***** Read spans/arrays of pixels *****/
1041 /**********************************************************************/
1042
1043
1044 /* Read a horizontal span of color-index pixels. */
1045 static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
1046 GLuint index[])
1047 {
1048 STARTPROFILE
1049 GLuint i;
1050 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
1051 assert(Current->rgb_flag==GL_FALSE);
1052 for (i=0; i<n; i++)
1053 index[i]=Mem[i];
1054 ENDPROFILE(read_ci32_span)
1055 }
1056
1057
1058
1059
1060 /* Read an array of color index pixels. */
1061 static void read_ci32_pixels( const GLcontext* ctx,
1062 GLuint n, const GLint x[], const GLint y[],
1063 GLuint indx[], const GLubyte mask[] )
1064 {
1065 STARTPROFILE
1066 GLuint i;
1067 assert(Current->rgb_flag==GL_FALSE);
1068 for (i=0; i<n; i++) {
1069 if (mask[i]) {
1070 indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
1071 }
1072 }
1073 ENDPROFILE(read_ci32_pixels)
1074 }
1075
1076
1077
1078 /* Read a horizontal span of color pixels. */
1079 static void read_rgba_span( const GLcontext* ctx,
1080 GLuint n, GLint x, GLint y,
1081 GLubyte rgba[][4] )
1082 {
1083 STARTPROFILE
1084 UINT i;
1085 COLORREF Color;
1086 HDC DC=DD_GETDC;
1087 assert(Current->rgb_flag==GL_TRUE);
1088 y=FLIP(y);
1089 for (i=0; i<n; i++) {
1090 Color=GetPixel(DC,x+i,y);
1091 rgba[i][RCOMP] = GetRValue(Color);
1092 rgba[i][GCOMP] = GetGValue(Color);
1093 rgba[i][BCOMP] = GetBValue(Color);
1094 rgba[i][ACOMP] = 255;
1095 }
1096 DD_RELEASEDC;
1097 // Brian P. Has mentioned to comment this out.
1098 // memset(alpha,0,n*sizeof(GLubyte));
1099 ENDPROFILE(read_rgba_span)
1100 }
1101
1102
1103 /* Read an array of color pixels. */
1104 static void read_rgba_pixels( const GLcontext* ctx,
1105 GLuint n, const GLint x[], const GLint y[],
1106 GLubyte rgba[][4], const GLubyte mask[] )
1107 {
1108 STARTPROFILE
1109 GLuint i;
1110 COLORREF Color;
1111 HDC DC=DD_GETDC;
1112 assert(Current->rgb_flag==GL_TRUE);
1113 for (i=0; i<n; i++) {
1114 if (mask[i]) {
1115 Color=GetPixel(DC,x[i],FLIP(y[i]));
1116 rgba[i][RCOMP] = GetRValue(Color);
1117 rgba[i][GCOMP] = GetGValue(Color);
1118 rgba[i][BCOMP] = GetBValue(Color);
1119 rgba[i][ACOMP] = 255;
1120 }
1121 }
1122 DD_RELEASEDC;
1123 // Brian P. has mentioned to comment this out.
1124 // memset(alpha,0,n*sizeof(GLint));
1125 ENDPROFILE(read_rgba_pixels)
1126 }
1127
1128
1129
1130 /**********************************************************************/
1131 /**********************************************************************/
1132
1133
1134 static const char *renderer_string(void)
1135 {
1136 return "Windows";
1137 }
1138
1139
1140
1141 void setup_DD_pointers( GLcontext* ctx )
1142 {
1143 ctx->Driver.RendererString = renderer_string;
1144 ctx->Driver.UpdateState = setup_DD_pointers;
1145 ctx->Driver.GetBufferSize = buffer_size;
1146 ctx->Driver.Finish = finish;
1147 ctx->Driver.Flush = flush;
1148
1149 ctx->Driver.ClearIndex = clear_index;
1150 ctx->Driver.ClearColor = clear_color;
1151 ctx->Driver.Clear = clear;
1152
1153 ctx->Driver.Index = set_index;
1154 ctx->Driver.Color = set_color;
1155 ctx->Driver.IndexMask = index_mask;
1156 ctx->Driver.ColorMask = color_mask;
1157
1158 ctx->Driver.LogicOp = logicop;
1159 ctx->Driver.Dither = dither;
1160
1161 ctx->Driver.SetBuffer = set_buffer;
1162 ctx->Driver.GetBufferSize = buffer_size;
1163
1164 ctx->Driver.PointsFunc = choose_points_function(ctx);
1165 ctx->Driver.LineFunc = choose_line_function(ctx);
1166 ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
1167
1168 /* Pixel/span writing functions: */
1169 ctx->Driver.WriteRGBASpan = write_rgba_span;
1170 ctx->Driver.WriteRGBSpan = write_rgb_span;
1171 ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span;
1172 ctx->Driver.WriteRGBAPixels = write_rgba_pixels;
1173 ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels;
1174 ctx->Driver.WriteCI32Span = write_ci32_span;
1175 ctx->Driver.WriteCI8Span = write_ci8_span;
1176 ctx->Driver.WriteMonoCISpan = write_mono_ci_span;
1177 ctx->Driver.WriteCI32Pixels = write_ci32_pixels;
1178 ctx->Driver.WriteMonoCIPixels = write_mono_ci_pixels;
1179
1180 ctx->Driver.ReadCI32Span = read_ci32_span;
1181 ctx->Driver.ReadRGBASpan = read_rgba_span;
1182 ctx->Driver.ReadCI32Pixels = read_ci32_pixels;
1183 ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
1184 }
1185
1186
1187 /**********************************************************************/
1188 /***** WMesa API Functions *****/
1189 /**********************************************************************/
1190
1191
1192
1193 #define PAL_SIZE 256
1194 static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
1195 {
1196 STARTPROFILE
1197 int i;
1198 HDC hdc;
1199 struct
1200 {
1201 WORD Version;
1202 WORD NumberOfEntries;
1203 PALETTEENTRY aEntries[PAL_SIZE];
1204 } Palette =
1205 {
1206 0x300,
1207 PAL_SIZE
1208 };
1209 hdc=GetDC(NULL);
1210 if (Pal!=NULL)
1211 GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
1212 else
1213 GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
1214 if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
1215 {
1216 for(i = 0; i <PAL_SIZE; i++)
1217 Palette.aEntries[i].peFlags = PC_RESERVED;
1218 Palette.aEntries[255].peRed = 255;
1219 Palette.aEntries[255].peGreen = 255;
1220 Palette.aEntries[255].peBlue = 255;
1221 Palette.aEntries[255].peFlags = 0;
1222 Palette.aEntries[0].peRed = 0;
1223 Palette.aEntries[0].peGreen = 0;
1224 Palette.aEntries[0].peBlue = 0;
1225 Palette.aEntries[0].peFlags = 0;
1226 }
1227 else
1228 {
1229 int nStaticColors;
1230 int nUsableColors;
1231 nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
1232 for (i=0; i<nStaticColors; i++)
1233 Palette.aEntries[i].peFlags = 0;
1234 nUsableColors = PAL_SIZE-nStaticColors;
1235 for (; i<nUsableColors; i++)
1236 Palette.aEntries[i].peFlags = PC_RESERVED;
1237 for (; i<PAL_SIZE-nStaticColors; i++)
1238 Palette.aEntries[i].peFlags = PC_RESERVED;
1239 for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
1240 Palette.aEntries[i].peFlags = 0;
1241 }
1242 ReleaseDC(NULL,hdc);
1243 for (i=0; i<PAL_SIZE; i++)
1244 {
1245 aRGB[i].rgbRed=Palette.aEntries[i].peRed;
1246 aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
1247 aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
1248 aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
1249 }
1250 ENDPROFILE(GetPalette)
1251 }
1252
1253
1254 WMesaContext WMesaCreateContext( HWND hWnd,
1255 HPALETTE* Pal,
1256 GLboolean rgb_flag,
1257 GLboolean db_flag )
1258 {
1259 RECT CR;
1260 WMesaContext c;
1261 GLboolean true_color_flag;
1262 c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1263 if (!c)
1264 return NULL;
1265
1266 c->Window=hWnd;
1267 c->hDC = GetDC(hWnd);
1268 true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
1269 #ifdef DDRAW
1270 if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
1271 #endif
1272
1273
1274 #ifdef DITHER
1275 if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
1276 c->dither_flag = GL_TRUE;
1277 c->hPalHalfTone = WinGCreateHalftonePalette();
1278 }
1279 else
1280 c->dither_flag = GL_FALSE;
1281 #else
1282 c->dither_flag = GL_FALSE;
1283 #endif
1284
1285
1286 if (rgb_flag==GL_FALSE)
1287 {
1288 c->rgb_flag = GL_FALSE;
1289 // c->pixel = 1;
1290 c->db_flag = db_flag =GL_TRUE; // WinG requires double buffering
1291 printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
1292 }
1293 else
1294 {
1295 c->rgb_flag = GL_TRUE;
1296 // c->pixel = 0;
1297 }
1298 GetClientRect(c->Window,&CR);
1299 c->width=CR.right;
1300 c->height=CR.bottom;
1301 if (db_flag)
1302 {
1303 c->db_flag = 1;
1304 /* Double buffered */
1305 #ifndef DDRAW
1306 // if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
1307 {
1308 wmCreateBackingStore(c, c->width, c->height);
1309
1310 }
1311 #endif
1312 }
1313 else
1314 {
1315 /* Single Buffered */
1316 if (c->rgb_flag)
1317 c->db_flag = 0;
1318 }
1319 #ifdef DDRAW
1320 if (DDInit(c,hWnd) == GL_FALSE) {
1321 free( (void *) c );
1322 exit(1);
1323 }
1324 #endif
1325
1326
1327 c->gl_visual = gl_create_visual(rgb_flag,
1328 GL_FALSE, /* software alpha */
1329 db_flag, /* db_flag */
1330 GL_FALSE, /* stereo */
1331 16, /* depth_bits */
1332 8, /* stencil_bits */
1333 8, /* accum_bits */
1334 0, /* index bits */
1335 8,8,8,8 ); /* r, g, b, a bits */
1336
1337 if (!c->gl_visual) {
1338 return NULL;
1339 }
1340
1341 /* allocate a new Mesa context */
1342 c->gl_ctx = gl_create_context( c->gl_visual, NULL, c, GL_TRUE);
1343
1344 if (!c->gl_ctx) {
1345 gl_destroy_visual( c->gl_visual );
1346 free(c);
1347 return NULL;
1348 }
1349
1350 c->gl_buffer = gl_create_framebuffer( c->gl_visual );
1351 if (!c->gl_buffer) {
1352 gl_destroy_visual( c->gl_visual );
1353 gl_destroy_context( c->gl_ctx );
1354 free(c);
1355 return NULL;
1356 }
1357
1358 c->gl_ctx->Driver.UpdateState = setup_DD_pointers;
1359
1360 // setup_DD_pointers(c->gl_ctx);
1361
1362 return c;
1363 }
1364
1365 void WMesaDestroyContext( void )
1366 {
1367 WMesaContext c = Current;
1368 ReleaseDC(c->Window,c->hDC);
1369 WC = c;
1370 if(c->hPalHalfTone != NULL)
1371 DeleteObject(c->hPalHalfTone);
1372 gl_destroy_visual( c->gl_visual );
1373 gl_destroy_framebuffer( c->gl_buffer );
1374 gl_destroy_context( c->gl_ctx );
1375
1376 if (c->db_flag)
1377 #ifdef DDRAW
1378 DDFree(c);
1379 #else
1380 wmDeleteBackingStore(c);
1381 #endif
1382 free( (void *) c );
1383 //Following code is added to enable parallel render
1384 // Parallel render only work in double buffer mode
1385 #if !defined(NO_PARALLEL)
1386 if(parallelMachine)
1387 PRDestroyRenderBuffer();
1388 #endif
1389 // End modification
1390 }
1391
1392 void WMesaMakeCurrent( WMesaContext c )
1393 {
1394 if(!c){
1395 Current = c;
1396 return;
1397 }
1398
1399 //
1400 // A little optimization
1401 // If it already is current,
1402 // don't set it again
1403 //
1404 if(Current == c)
1405 return;
1406
1407 //gl_set_context( c->gl_ctx );
1408 gl_make_current(c->gl_ctx, c->gl_buffer);
1409 setup_DD_pointers(c->gl_ctx);
1410 Current = c;
1411 if (Current->gl_ctx->Viewport.Width==0) {
1412 /* initialize viewport to window size */
1413 _mesa_set_viewport( Current->gl_ctx,
1414 0, 0, Current->width, Current->height );
1415 }
1416 if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
1417 WMesaPaletteChange(c->hPalHalfTone);
1418 }
1419 }
1420
1421 void WMesaSwapBuffers( void )
1422 {
1423 HDC DC = Current->hDC;
1424 if (Current->db_flag)
1425 wmFlush(Current);
1426 }
1427
1428 void WMesaPaletteChange(HPALETTE Pal)
1429 {
1430 int vRet;
1431 LPPALETTEENTRY pPal;
1432 if (Current && (Current->rgb_flag==GL_FALSE || Current->dither_flag == GL_TRUE))
1433 {
1434 pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
1435 Current->hPal=Pal;
1436 // GetPaletteEntries( Pal, 0, 256, pPal );
1437 GetPalette( Pal, pPal );
1438 #ifdef DDRAW
1439 Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
1440 pPal, &(Current->lpDDPal), NULL);
1441 if (Current->lpDDPal)
1442 Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,Current->lpDDPal);
1443 #else
1444 vRet = SetDIBColorTable(Current->dib.hDC,0,256,pPal);
1445 #endif
1446 free( pPal );
1447 }
1448
1449 }
1450
1451 static unsigned char threeto8[8] = {
1452 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
1453 };
1454
1455 static unsigned char twoto8[4] = {
1456 0, 0x55, 0xaa, 0xff
1457 };
1458
1459 static unsigned char oneto8[2] = {
1460 0, 255
1461 };
1462
1463 static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
1464 {
1465 unsigned char val;
1466
1467 val = i >> shift;
1468 switch (nbits) {
1469
1470 case 1:
1471 val &= 0x1;
1472 return oneto8[val];
1473
1474 case 2:
1475 val &= 0x3;
1476 return twoto8[val];
1477
1478 case 3:
1479 val &= 0x7;
1480 return threeto8[val];
1481
1482 default:
1483 return 0;
1484 }
1485 }
1486
1487 void wmCreatePalette( PWMC pwdc )
1488 {
1489 /* Create a compressed and re-expanded 3:3:2 palette */
1490 int i;
1491 LOGPALETTE *pPal;
1492 BYTE rb, rs, gb, gs, bb, bs;
1493
1494 pwdc->nColors = 0x100;
1495
1496 pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
1497 memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
1498
1499 pPal->palVersion = 0x300;
1500
1501 rb = REDBITS;
1502 rs = REDSHIFT;
1503 gb = GREENBITS;
1504 gs = GREENSHIFT;
1505 bb = BLUEBITS;
1506 bs = BLUESHIFT;
1507
1508 if (pwdc->db_flag) {
1509
1510 /* Need to make two palettes: one for the screen DC and one for the DIB. */
1511 pPal->palNumEntries = pwdc->nColors;
1512 for (i = 0; i < pwdc->nColors; i++) {
1513 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1514 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1515 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1516 pPal->palPalEntry[i].peFlags = 0;
1517 }
1518 pwdc->hGLPalette = CreatePalette( pPal );
1519 pwdc->hPalette = CreatePalette( pPal );
1520 }
1521
1522 else {
1523 pPal->palNumEntries = pwdc->nColors;
1524 for (i = 0; i < pwdc->nColors; i++) {
1525 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
1526 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
1527 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
1528 pPal->palPalEntry[i].peFlags = 0;
1529 }
1530 pwdc->hGLPalette = CreatePalette( pPal );
1531 }
1532
1533 free(pPal);
1534
1535 }
1536
1537 void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
1538 {
1539 if(Current->db_flag){
1540 LPBYTE lpb = pwc->pbPixels;
1541 LPDWORD lpdw;
1542 LPWORD lpw;
1543 UINT nBypp = pwc->cColorBits / 8;
1544 UINT nOffset = iPixel % nBypp;
1545
1546 // Move the pixel buffer pointer to the scanline that we
1547 // want to access
1548
1549 // pwc->dib.fFlushed = FALSE;
1550
1551 lpb += pwc->ScanWidth * iScanLine;
1552 // Now move to the desired pixel
1553 lpb += iPixel * nBypp;
1554 lpb = PIXELADDR(iPixel, iScanLine);
1555 lpdw = (LPDWORD)lpb;
1556 lpw = (LPWORD)lpb;
1557
1558 if(nBypp == 1){
1559 if(pwc->dither_flag)
1560 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
1561 else
1562 *lpb = BGR8(r,g,b);
1563 }
1564 else if(nBypp == 2)
1565 *lpw = BGR16(r,g,b);
1566 else if (nBypp == 3){
1567 *lpdw = BGR24(r,g,b);
1568 }
1569 else if (nBypp == 4)
1570 *lpdw = BGR32(r,g,b);
1571 }
1572 else{
1573 HDC DC = DD_GETDC;
1574 SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
1575 DD_RELEASEDC;
1576 }
1577 }
1578
1579 void wmCreateDIBSection( HDC hDC,
1580 PWMC pwc, // handle of device context
1581 CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
1582 UINT iUsage // color data type indicator: RGB values or palette indices
1583 )
1584 {
1585 DWORD dwSize = 0;
1586 DWORD dwScanWidth;
1587 UINT nBypp = pwc->cColorBits / 8;
1588 HDC hic;
1589
1590 dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
1591
1592 pwc->ScanWidth =pwc->pitch = dwScanWidth;
1593
1594 if (stereo_flag)
1595 pwc->ScanWidth = 2* pwc->pitch;
1596
1597 dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
1598
1599 pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
1600 NULL,
1601 PAGE_READWRITE | SEC_COMMIT,
1602 0,
1603 dwSize,
1604 NULL);
1605
1606 if (!pwc->dib.hFileMap)
1607 return;
1608
1609 pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
1610 FILE_MAP_ALL_ACCESS,
1611 0,
1612 0,
1613 0);
1614
1615 if(!pwc->dib.base){
1616 CloseHandle(pwc->dib.hFileMap);
1617 return;
1618 }
1619
1620 // pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
1621
1622 // pwc->dib.hDC = CreateCompatibleDC(hDC);
1623
1624 CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
1625
1626 hic = CreateIC("display", NULL, NULL, NULL);
1627 pwc->dib.hDC = CreateCompatibleDC(hic);
1628
1629
1630 /* pwc->hbmDIB = CreateDIBitmap(hic,
1631 &(pwc->bmi.bmiHeader),
1632 CBM_INIT,
1633 pwc->pbPixels,
1634 &(pwc->bmi),
1635 DIB_RGB_COLORS);
1636 */
1637 pwc->hbmDIB = CreateDIBSection(hic,
1638 &(pwc->bmi),
1639 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
1640 &(pwc->pbPixels),
1641 pwc->dib.hFileMap,
1642 0);
1643 /*
1644 pwc->hbmDIB = CreateDIBSection(hic,
1645 &(pwc->bmi),
1646 DIB_RGB_COLORS,
1647 &(pwc->pbPixels),
1648 pwc->dib.hFileMap,
1649 0);
1650 */
1651 pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
1652 pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
1653
1654 DeleteDC(hic);
1655
1656 return;
1657
1658 }
1659
1660 //
1661 // Blit memory DC to screen DC
1662 //
1663 BOOL wmFlush(PWMC pwc)
1664 {
1665 BOOL bRet = 0;
1666 DWORD dwErr = 0;
1667 #ifdef DDRAW
1668 HRESULT ddrval;
1669 #endif
1670
1671 // Now search through the torus frames and mark used colors
1672 if(pwc->db_flag){
1673 #ifdef DDRAW
1674 if (pwc->lpDDSOffScreen == NULL)
1675 if(DDCreateOffScreen(pwc) == GL_FALSE)
1676 return;
1677
1678 pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
1679
1680 while( 1 )
1681 {
1682 ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
1683 &(pwc->rectSurface), pwc->lpDDSOffScreen, &(pwc->rectOffScreen), 0, NULL );
1684
1685 if( ddrval == DD_OK )
1686 {
1687 break;
1688 }
1689 if( ddrval == DDERR_SURFACELOST )
1690 {
1691 if(!DDRestoreAll(pwc))
1692 {
1693 break;
1694 }
1695 }
1696 if( ddrval != DDERR_WASSTILLDRAWING )
1697 {
1698 break;
1699 }
1700 }
1701
1702 while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
1703 NULL, &(pwc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
1704 ;
1705
1706 if(ddrval != DD_OK)
1707 dwErr = GetLastError();
1708 #else
1709 bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
1710 pwc->dib.hDC, 0, 0, SRCCOPY);
1711 #endif
1712 }
1713
1714 return(TRUE);
1715
1716 }
1717
1718 // The following code is added by Li Wei to enable stereo display
1719
1720 #if !defined(NO_STEREO)
1721
1722 void WMesaShowStereo(GLuint list)
1723 {
1724
1725 GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
1726 GLfloat cm[16];
1727 GLint matrix_mode;
1728 // Must use double Buffer
1729 if( ! Current-> db_flag )
1730 return;
1731
1732
1733 glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
1734
1735 // glPushMatrix(); //****
1736 WMesaViewport(Current->gl_ctx,0,Current->height/2,Current->width,Current->height/2);
1737 // Current->gl_ctx->NewState = 0;
1738
1739 // glViewport(0,0,Current->width,Current->height/2);
1740 if(matrix_mode!=GL_MODELVIEW)
1741 glMatrixMode(GL_MODELVIEW);
1742
1743 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1744 glLoadIdentity();
1745 gluLookAt(viewDistance/2,0.0,0.0 ,
1746 viewDistance/2,0.0,-1.0,
1747 0.0,1.0,0.0 );
1748 // glTranslatef(viewDistance/2.0,0.,0.);
1749 glMultMatrixf( cm );
1750
1751 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
1752 //glPushMatrix();
1753 glCallList( list );
1754 //glPopMatrix();
1755
1756 glGetFloatv(GL_MODELVIEW_MATRIX,cm);
1757 glLoadIdentity();
1758 gluLookAt(-viewDistance/2,0.0,0.0 ,
1759 -viewDistance/2,0.0,-1.0,
1760 0.0,1.0,0.0 );
1761 // glTranslatef(-viewDistance/2.0,0.,0.);
1762 glMultMatrixf(cm);
1763
1764 Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
1765 glCallList(list);
1766 if(matrix_mode!=GL_MODELVIEW)
1767 glMatrixMode(matrix_mode);
1768
1769 // glPopMatrix();
1770 glFlush();
1771
1772 WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
1773 // Current->gl_ctx->NewState = 0;
1774 WMesaSwapBuffers();
1775
1776 }
1777
1778 void toggleStereoMode()
1779 {
1780 if(!Current->db_flag)
1781 return;
1782 if(!stereo_flag){
1783 stereo_flag = 1;
1784 if(stereoBuffer==GL_FALSE)
1785 #if !defined(NO_PARALLEL)
1786 if(!parallelFlag)
1787 #endif
1788 {
1789 Current->ScanWidth = Current->pitch*2;
1790 }
1791 }
1792 else {
1793 stereo_flag = 0;
1794 #if !defined(NO_PARALLEL)
1795 if(!parallelFlag)
1796 #endif
1797 Current->ScanWidth = Current->pitch;
1798 Current->pbPixels = Current->addrOffScreen;
1799 }
1800 }
1801
1802 /* if in stereo mode, the following function is called */
1803 void glShowStereo(GLuint list)
1804 {
1805 WMesaShowStereo(list);
1806 }
1807
1808 #endif // End if NO_STEREO not defined
1809
1810 #if !defined(NO_PARALLEL)
1811
1812 void toggleParallelMode(void)
1813 {
1814 if(!parallelFlag){
1815 parallelFlag = GL_TRUE;
1816 if(parallelMachine==GL_FALSE){
1817 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
1818 Current->cColorBits/8,
1819 Current->width ,Current->height,
1820 Current->ScanWidth,
1821 Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
1822 parallelMachine = GL_TRUE;
1823 }
1824 }
1825 else {
1826 parallelFlag = GL_FALSE;
1827 if(parallelMachine==GL_TRUE){
1828 PRDestroyRenderBuffer();
1829 parallelMachine=GL_FALSE;
1830 ReadyForNextFrame = GL_TRUE;
1831 }
1832
1833 /***********************************************
1834 // Seems something wrong!!!!
1835 ************************************************/
1836
1837 WMesaMakeCurrent(Current);
1838 #if !defined(NO_STEREO)
1839 stereo_flag = GL_FALSE ;
1840 #endif
1841 }
1842 }
1843
1844 void PRShowRenderResult(void)
1845 {
1846 int flag = 0;
1847 if(!glImageRendered())
1848 return;
1849
1850 if (parallelFlag)
1851 {
1852 WMesaSwapBuffers();
1853 }
1854
1855 }
1856 #endif //End if NO_PARALLEL not defined
1857
1858 //end modification
1859
1860 BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
1861 {
1862 char unsigned redtemp, greentemp, bluetemp, paletteindex;
1863
1864 //*** now, look up each value in the halftone matrix
1865 //*** using an 8x8 ordered dither.
1866 redtemp = aDividedBy51[red]
1867 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
1868 + scanline%8]);
1869 greentemp = aDividedBy51[(char unsigned)green]
1870 + (aModulo51[green] > aHalftone8x8[
1871 (pixel%8)*8 + scanline%8]);
1872 bluetemp = aDividedBy51[(char unsigned)blue]
1873 + (aModulo51[blue] > aHalftone8x8[
1874 (pixel%8)*8 +scanline%8]);
1875
1876 //*** recombine the halftoned rgb values into a palette index
1877 paletteindex =
1878 redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
1879
1880 //*** and translate through the wing halftone palette
1881 //*** translation vector to give the correct value.
1882 return aWinGHalftoneTranslation[paletteindex];
1883 }
1884
1885 #ifdef DDRAW
1886 /*
1887 * restoreAll
1888 *
1889 * restore all lost objects
1890 */
1891 static HRESULT DDRestoreAll( WMesaContext wc )
1892 {
1893 HRESULT ddrval;
1894
1895 ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
1896 if( ddrval == DD_OK )
1897 {
1898 ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
1899 }
1900 return ddrval;
1901
1902 } /* restoreAll */
1903
1904
1905 /*
1906 * This function is called if the initialization function fails
1907 */
1908 static BOOL initFail( HWND hwnd, WMesaContext wc )
1909 {
1910 DDFree(wc);
1911 MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
1912 return FALSE;
1913
1914 } /* initFail */
1915
1916
1917 static void DDDeleteOffScreen(WMesaContext wc)
1918 {
1919 if( wc->lpDDSOffScreen != NULL )
1920 {
1921 wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
1922 wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
1923 wc->lpDDSOffScreen = NULL;
1924 }
1925
1926 }
1927
1928 static void DDFreePrimarySurface(WMesaContext wc)
1929 {
1930 if( wc->lpDDSPrimary != NULL )
1931 {
1932 if(wc->db_flag == GL_FALSE)
1933 wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
1934 wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
1935 wc->lpDDSPrimary = NULL;
1936 }
1937 }
1938
1939 static BOOL DDCreatePrimarySurface(WMesaContext wc)
1940 {
1941 HRESULT ddrval;
1942 DDSCAPS ddscaps;
1943 wc->ddsd.dwSize = sizeof( wc->ddsd );
1944 wc->ddsd.dwFlags = DDSD_CAPS;
1945 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1946
1947 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), &(wc->lpDDSPrimary), NULL );
1948 if( ddrval != DD_OK )
1949 {
1950 return initFail(wc->hwnd , wc);
1951 }
1952 if(wc->db_flag == GL_FALSE)
1953 wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, wc->hDC);
1954 return TRUE;
1955 }
1956
1957 static BOOL DDCreateOffScreen(WMesaContext wc)
1958 {
1959 POINT pt;
1960 HRESULT ddrval;
1961 if(wc->lpDD == NULL)
1962 return FALSE;
1963 GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
1964 wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
1965 wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1966 wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
1967 wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
1968
1969 ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), &(wc->lpDDSOffScreen), NULL );
1970 if( ddrval != DD_OK )
1971 {
1972 return FALSE;
1973 }
1974
1975 while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
1976 ;
1977 // while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
1978 ;
1979 if(wc->ddsd.lpSurface==NULL)
1980 return initFail(wc->hwnd, wc);
1981
1982 wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = (PBYTE)(wc->ddsd.lpSurface);
1983 wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
1984 if (stereo_flag)
1985 wc->ScanWidth = wc->ddsd.lPitch*2;
1986
1987 GetClientRect( wc->hwnd, &(wc->rectSurface) );
1988 pt.x = pt.y = 0;
1989 ClientToScreen( wc->hwnd, &pt );
1990 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
1991 wmSetPixelFormat(wc, wc->hDC);
1992 return TRUE;
1993 }
1994
1995 /*
1996 * doInit - do work required for every instance of the application:
1997 * create the window, initialize data
1998 */
1999 static BOOL DDInit( WMesaContext wc, HWND hwnd)
2000 {
2001 HRESULT ddrval;
2002 DWORD dwFrequency;
2003
2004 LPDIRECTDRAW lpDD; // DirectDraw object
2005 LPDIRECTDRAW2 lpDD2;
2006
2007
2008 wc->fullScreen = displayOptions.fullScreen;
2009 wc->gMode = displayOptions.mode;
2010 wc->hwnd = hwnd;
2011 stereo_flag = displayOptions.stereo;
2012 if(wc->db_flag!= GL_TRUE)
2013 stereo_flag = GL_FALSE;
2014 /*
2015 * create the main DirectDraw object
2016 */
2017 ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
2018 if( ddrval != DD_OK )
2019 {
2020 return initFail(hwnd,wc);
2021 }
2022
2023 // Get exclusive mode if requested
2024 if(wc->fullScreen)
2025 {
2026 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
2027 }
2028 else
2029 {
2030 ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_NORMAL );
2031 }
2032 if( ddrval != DD_OK )
2033 {
2034 return initFail(hwnd , wc);
2035 }
2036
2037
2038 /* ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
2039 (LPVOID *)((wc->lpDD2)));
2040
2041 */
2042 if(ddrval != DD_OK)
2043 return initFail(hwnd , wc);
2044
2045
2046 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2047 // wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
2048 switch( wc->gMode )
2049 {
2050 case 1: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, displayOptions.bpp); break;
2051 case 2: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, displayOptions.bpp); break;
2052 case 3: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, displayOptions.bpp); break;
2053 case 4: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, displayOptions.bpp); break;
2054 case 5: ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, displayOptions.bpp); break;
2055 }
2056
2057 if( ddrval != DD_OK )
2058 {
2059 printf("Can't modify display mode, current mode used\n");
2060 // return initFail(hwnd , wc);
2061 }
2062 //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
2063 switch(ddrval){
2064 case DDERR_INVALIDOBJECT:
2065 break;
2066 case DDERR_INVALIDPARAMS:
2067 break;
2068 case DDERR_UNSUPPORTEDMODE:
2069 ;
2070 }
2071
2072 if(DDCreatePrimarySurface(wc) == GL_FALSE)
2073 return initFail(hwnd, wc);
2074
2075 if(wc->db_flag)
2076 return DDCreateOffScreen(wc);
2077 } /* DDInit */
2078
2079 static void DDFree( WMesaContext wc)
2080 {
2081 if( wc->lpDD != NULL )
2082 {
2083 DDFreePrimarySurface(wc);
2084 DDDeleteOffScreen(wc);
2085 wc->lpDD->lpVtbl->Release(wc->lpDD);
2086 wc->lpDD = NULL;
2087 }
2088 // Clean up the screen on exit
2089 RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
2090 RDW_ALLCHILDREN );
2091
2092 }
2093 #endif
2094
2095 void WMesaMove(void)
2096 {
2097 WMesaContext wc = Current;
2098 POINT pt;
2099 if (Current != NULL){
2100 GetClientRect( wc->hwnd, &(wc->rectSurface) );
2101 pt.x = pt.y = 0;
2102 ClientToScreen( wc->hwnd, &pt );
2103 OffsetRect(&(wc->rectSurface), pt.x, pt.y);
2104 }
2105 }
2106
2107
2108
2109 /*
2110 * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable
2111 * shortcut.
2112 */
2113 #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) )
2114
2115
2116 /**********************************************************************/
2117 /*** Triangle rendering ***/
2118 /**********************************************************************/
2119
2120 /*
2121 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
2122 */
2123 static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
2124 GLuint v0, GLuint v1, GLuint v2,
2125 GLuint pv )
2126 {
2127 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2128 #define INTERP_Z 1
2129 #define INTERP_RGB 1
2130 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2131 #define PIXEL_TYPE GLuint
2132 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2133 #define BYTES_PER_ROW (wmesa->ScanWidth)
2134 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2135 { \
2136 GLint i, len = RIGHT-LEFT; \
2137 for (i=0;i<len;i++) { \
2138 GLdepth z = FixedToDepth(ffz); \
2139 if (z < zRow[i]) { \
2140 pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2141 FixedToInt(ffb) ); \
2142 zRow[i] = z; \
2143 } \
2144 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2145 ffz += fdzdx; \
2146 } \
2147 }
2148 #ifdef WIN32
2149 #include "..\tritemp.h"
2150 #else
2151 #include "tritemp.h"
2152 #endif
2153 }
2154
2155
2156 /*
2157 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
2158 */
2159 static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
2160 GLuint v0, GLuint v1, GLuint v2,
2161 GLuint pv )
2162 {
2163 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2164 #define INTERP_Z 1
2165 #define INTERP_RGB 1
2166 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2167 #define PIXEL_TYPE GLuint
2168 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2169 #define BYTES_PER_ROW (wmesa->ScanWidth)
2170 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2171 { \
2172 GLint i, len = RIGHT-LEFT; \
2173 for (i=0;i<len;i++) { \
2174 GLdepth z = FixedToDepth(ffz); \
2175 if (z < zRow[i]) { \
2176 pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2177 FixedToInt(ffb) ); \
2178 zRow[i] = z; \
2179 } \
2180 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2181 ffz += fdzdx; \
2182 } \
2183 }
2184 #ifdef WIN32
2185 #include "..\tritemp.h"
2186 #else
2187 #include "tritemp.h"
2188 #endif
2189 }
2190
2191
2192
2193 /*
2194 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
2195 */
2196 static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
2197 GLuint v0, GLuint v1, GLuint v2,
2198 GLuint pv )
2199 {
2200 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2201 #define INTERP_Z 1
2202 #define INTERP_RGB 1
2203 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2204 #define PIXEL_TYPE GLushort
2205 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2206 #define BYTES_PER_ROW (wmesa->ScanWidth)
2207 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2208 { \
2209 GLint i, len = RIGHT-LEFT; \
2210 for (i=0;i<len;i++) { \
2211 GLdepth z = FixedToDepth(ffz); \
2212 if (z < zRow[i]) { \
2213 pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2214 FixedToInt(ffb) ); \
2215 zRow[i] = z; \
2216 } \
2217 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2218 ffz += fdzdx; \
2219 } \
2220 }
2221 #ifdef WIN32
2222 #include "..\tritemp.h"
2223 #else
2224 #include "tritemp.h"
2225 #endif
2226 }
2227
2228 /*
2229 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
2230 */
2231 static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
2232 GLuint v1, GLuint v2, GLuint pv )
2233 {
2234 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2235 #define INTERP_Z 1
2236 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2237 #define PIXEL_TYPE GLuint
2238 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2239 #define BYTES_PER_ROW (wmesa->ScanWidth)
2240 #define SETUP_CODE \
2241 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2242 VB->Color[pv][1], VB->Color[pv][2] );
2243 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2244 { \
2245 GLint i, len = RIGHT-LEFT; \
2246 for (i=0;i<len;i++) { \
2247 GLdepth z = FixedToDepth(ffz); \
2248 if (z < zRow[i]) { \
2249 pRow[i] = p; \
2250 zRow[i] = z; \
2251 } \
2252 ffz += fdzdx; \
2253 } \
2254 }
2255 #ifdef WIN32
2256 #include "..\tritemp.h"
2257 #else
2258 #include "tritemp.h"
2259 #endif
2260 }
2261
2262
2263 /*
2264 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
2265 */
2266 static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2267 GLuint v2, GLuint pv )
2268 {
2269 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2270 #define INTERP_Z 1
2271 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2272 #define PIXEL_TYPE GLuint
2273 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2274 #define BYTES_PER_ROW (wmesa->ScanWidth)
2275 #define SETUP_CODE \
2276 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2277 VB->Color[pv][1], VB->Color[pv][2] );
2278 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2279 { \
2280 GLint i, len = RIGHT-LEFT; \
2281 for (i=0;i<len;i++) { \
2282 GLdepth z = FixedToDepth(ffz); \
2283 if (z < zRow[i]) { \
2284 pRow[i] = p; \
2285 zRow[i] = z; \
2286 } \
2287 ffz += fdzdx; \
2288 } \
2289 }
2290 #ifdef WIN32
2291 #include "..\tritemp.h"
2292 #else
2293 #include "tritemp.h"
2294 #endif
2295 }
2296
2297
2298 /*
2299 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
2300 */
2301 static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2302 GLuint v2, GLuint pv )
2303 {
2304 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2305 #define INTERP_Z 1
2306 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2307 #define PIXEL_TYPE GLushort
2308 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2309 #define BYTES_PER_ROW (wmesa->ScanWidth)
2310 #define SETUP_CODE \
2311 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2312 VB->Color[pv][1], VB->Color[pv][2] );
2313 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2314 { \
2315 GLint i, len = RIGHT-LEFT; \
2316 for (i=0;i<len;i++) { \
2317 GLdepth z = FixedToDepth(ffz); \
2318 if (z < zRow[i]) { \
2319 pRow[i] = p; \
2320 zRow[i] = z; \
2321 } \
2322 ffz += fdzdx; \
2323 } \
2324 }
2325 #ifdef WIN32
2326 #include "..\tritemp.h"
2327 #else
2328 #include "tritemp.h"
2329 #endif
2330 }
2331
2332
2333 /*
2334 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
2335 */
2336 static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2337 GLuint v2, GLuint pv )
2338 {
2339 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2340 #define INTERP_RGB 1
2341 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2342 #define PIXEL_TYPE GLuint
2343 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2344 #define BYTES_PER_ROW (wmesa->ScanWidth)
2345 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2346 { \
2347 GLint xx; \
2348 PIXEL_TYPE *pixel = pRow; \
2349 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2350 *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \
2351 FixedToInt(ffb) ); \
2352 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2353 } \
2354 }
2355 #ifdef WIN32
2356 #include "..\tritemp.h"
2357 #else
2358 #include "tritemp.h"
2359 #endif
2360 }
2361
2362
2363 /*
2364 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
2365 */
2366 static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2367 GLuint v2, GLuint pv )
2368 {
2369 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2370 #define INTERP_RGB 1
2371 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2372 #define PIXEL_TYPE GLuint
2373 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2374 #define BYTES_PER_ROW (wmesa->ScanWidth)
2375 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2376 { \
2377 GLint xx; \
2378 PIXEL_TYPE *pixel = pRow; \
2379 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2380 *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \
2381 FixedToInt(ffb) ); \
2382 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2383 } \
2384 }
2385 #ifdef WIN32
2386 #include "..\tritemp.h"
2387 #else
2388 #include "tritemp.h"
2389 #endif
2390 }
2391
2392
2393 /*
2394 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
2395 */
2396 static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2397 GLuint v2, GLuint pv )
2398 {
2399 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2400 #define INTERP_RGB 1
2401 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2402 #define PIXEL_TYPE GLushort
2403 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2404 #define BYTES_PER_ROW (wmesa->ScanWidth)
2405 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2406 { \
2407 GLint xx; \
2408 PIXEL_TYPE *pixel = pRow; \
2409 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2410 *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \
2411 FixedToInt(ffb) ); \
2412 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2413 } \
2414 }
2415 #ifdef WIN32
2416 #include "..\tritemp.h"
2417 #else
2418 #include "tritemp.h"
2419 #endif
2420 }
2421
2422
2423
2424 /*
2425 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
2426 */
2427 static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
2428 GLuint v1, GLuint v2, GLuint pv )
2429 {
2430 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2431 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2432 #define PIXEL_TYPE GLuint
2433 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2434 #define BYTES_PER_ROW (wmesa->ScanWidth)
2435 #define SETUP_CODE \
2436 unsigned long p = PACK_8B8G8R( VB->Color[pv][0], \
2437 VB->Color[pv][1], VB->Color[pv][2] );
2438 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2439 { \
2440 GLint xx; \
2441 PIXEL_TYPE *pixel = pRow; \
2442 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2443 *pixel = p; \
2444 } \
2445 }
2446 #ifdef WIN32
2447 #include "..\tritemp.h"
2448 #else
2449 #include "tritemp.h"
2450 #endif
2451 }
2452
2453
2454 /*
2455 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
2456 */
2457 static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2458 GLuint v2, GLuint pv )
2459 {
2460 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2461 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
2462 #define PIXEL_TYPE GLuint
2463 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2464 #define BYTES_PER_ROW (wmesa->ScanWidth)
2465 #define SETUP_CODE \
2466 unsigned long p = PACK_8R8G8B( VB->Color[pv][0], \
2467 VB->Color[pv][1], VB->Color[pv][2] );
2468 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2469 { \
2470 GLint xx; \
2471 PIXEL_TYPE *pixel = pRow; \
2472 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2473 *pixel = p; \
2474 } \
2475 }
2476 #ifdef WIN32
2477 #include "..\tritemp.h"
2478 #else
2479 #include "tritemp.h"
2480 #endif
2481 }
2482
2483
2484 /*
2485 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
2486 */
2487 static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2488 GLuint v2, GLuint pv )
2489 {
2490 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2491 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
2492 #define PIXEL_TYPE GLushort
2493 //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
2494 #define BYTES_PER_ROW (wmesa->ScanWidth)
2495 #define SETUP_CODE \
2496 unsigned long p = PACK_5R6G5B( VB->Color[pv][0], \
2497 VB->Color[pv][1], VB->Color[pv][2] );
2498 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2499 { \
2500 GLint xx; \
2501 PIXEL_TYPE *pixel = pRow; \
2502 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2503 *pixel = p; \
2504 } \
2505 }
2506 #ifdef WIN32
2507 #include "..\tritemp.h"
2508 #else
2509 #include "tritemp.h"
2510 #endif
2511 }
2512
2513
2514 /*
2515 * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
2516 */
2517
2518 static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2519 GLuint v2, GLuint pv )
2520 {
2521 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2522 #define INTERP_Z 1
2523 #define INTERP_INDEX 1
2524 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2525 #define PIXEL_TYPE GLubyte
2526 #define BYTES_PER_ROW (wmesa->ScanWidth)
2527 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2528 { \
2529 GLint i, len = RIGHT-LEFT; \
2530 for (i=0;i<len;i++) { \
2531 GLdepth z = FixedToDepth(ffz); \
2532 if (z < zRow[i]) { \
2533 pRow[i] = FixedToInt(ffi); \
2534 zRow[i] = z; \
2535 } \
2536 ffi += fdidx; \
2537 ffz += fdzdx; \
2538 } \
2539 }
2540
2541 #ifdef WIN32
2542 #include "..\tritemp.h"
2543 #else
2544 #include "tritemp.h"
2545 #endif
2546 }
2547
2548
2549 /*
2550 * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
2551 */
2552
2553 static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2554 GLuint v2, GLuint pv )
2555 {
2556 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2557 #define INTERP_Z 1
2558 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2559 #define PIXEL_TYPE GLubyte
2560 #define BYTES_PER_ROW (wmesa->ScanWidth)
2561 #define SETUP_CODE \
2562 GLuint index = VB->Index[pv]; \
2563 if (!VB->MonoColor) { \
2564 /* set the color index */ \
2565 (*ctx->Driver.Index)( ctx, index ); \
2566 }
2567 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2568 { \
2569 GLint i, len = RIGHT-LEFT; \
2570 for (i=0;i<len;i++) { \
2571 GLdepth z = FixedToDepth(ffz); \
2572 if (z < zRow[i]) { \
2573 pRow[i] = index; \
2574 zRow[i] = z; \
2575 } \
2576 ffz += fdzdx; \
2577 } \
2578 }
2579 #ifdef WIN32
2580 #include "..\tritemp.h"
2581 #else
2582 #include "tritemp.h"
2583 #endif
2584 }
2585
2586
2587
2588 /*
2589 * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2590 */
2591
2592 static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2593 GLuint v2, GLuint pv )
2594 {
2595 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2596 #define INTERP_Z 1
2597 #define INTERP_INDEX 1
2598 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2599 #define PIXEL_TYPE GLubyte
2600 #define BYTES_PER_ROW (wmesa->ScanWidth)
2601 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2602 { \
2603 GLint xx; \
2604 PIXEL_TYPE *pixel = pRow; \
2605 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2606 *pixel = FixedToInt(ffi); \
2607 ffi += fdidx; \
2608 } \
2609 }
2610 #ifdef WIN32
2611 #include "..\tritemp.h"
2612 #else
2613 #include "tritemp.h"
2614 #endif
2615 }
2616
2617
2618 /*
2619 * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
2620 */
2621 static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2622 GLuint v2, GLuint pv )
2623 {
2624 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2625 #define INTERP_Z 1
2626 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2627 #define PIXEL_TYPE GLubyte
2628 #define BYTES_PER_ROW (wmesa->ScanWidth)
2629 #define SETUP_CODE \
2630 GLuint index = VB->Index[pv]; \
2631 if (!VB->MonoColor) { \
2632 /* set the color index */ \
2633 (*ctx->Driver.Index)( ctx, index ); \
2634 }
2635 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2636 { \
2637 GLint xx; \
2638 PIXEL_TYPE *pixel = pRow; \
2639 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2640 *pixel = index; \
2641 } \
2642 }
2643 #ifdef WIN32
2644 #include "..\tritemp.h"
2645 #else
2646 #include "tritemp.h"
2647 #endif
2648 }
2649
2650 /*
2651 * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
2652 */
2653 static void smooth_DITHER8_z_triangle( GLcontext *ctx,
2654 GLuint v0, GLuint v1, GLuint v2,
2655 GLuint pv )
2656 {
2657 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2658 DITHER_RGB_TO_8BIT_SETUP
2659 #define INTERP_Z 1
2660 #define INTERP_RGB 1
2661 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2662 #define PIXEL_TYPE GLubyte
2663 #define BYTES_PER_ROW (wmesa->ScanWidth)
2664 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2665 { \
2666 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2667 for (i=0;i<len;i++,xx++) { \
2668 GLdepth z = FixedToDepth(ffz); \
2669 if (z < zRow[i]) { \
2670 DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \
2671 FixedToInt(ffb), xx, yy); \
2672 pRow[i] = pixelDithered; \
2673 zRow[i] = z; \
2674 } \
2675 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2676 ffz += fdzdx; \
2677 } \
2678 }
2679 #ifdef WIN32
2680 #include "..\tritemp.h"
2681 #else
2682 #include "tritemp.h"
2683 #endif
2684 }
2685
2686 /*
2687 * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
2688 */
2689 static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2690 GLuint v2, GLuint pv )
2691 {
2692 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2693 DITHER_RGB_TO_8BIT_SETUP
2694 #define INTERP_Z 1
2695 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2696 #define PIXEL_TYPE GLubyte
2697 #define BYTES_PER_ROW (wmesa->ScanWidth)
2698
2699 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2700 { \
2701 GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \
2702 for (i=0;i<len;i++,xx++) { \
2703 GLdepth z = FixedToDepth(ffz); \
2704 if (z < zRow[i]) { \
2705 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2706 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2707 pRow[i] = pixelDithered; \
2708 zRow[i] = z; \
2709 } \
2710 ffz += fdzdx; \
2711 } \
2712 }
2713 #ifdef WIN32
2714 #include "..\tritemp.h"
2715 #else
2716 #include "tritemp.h"
2717 #endif
2718 }
2719
2720 /*
2721 * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
2722 */
2723 static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2724 GLuint v2, GLuint pv )
2725 {
2726 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2727 DITHER_RGB_TO_8BIT_SETUP
2728 #define INTERP_RGB 1
2729 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2730 #define PIXEL_TYPE GLubyte
2731 #define BYTES_PER_ROW (wmesa->ScanWidth)
2732 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2733 { \
2734 GLint xx, yy = FLIP(Y); \
2735 PIXEL_TYPE *pixel = pRow; \
2736 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2737 DITHER_RGB_TO_8BIT( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
2738 *pixel = pixelDithered; \
2739 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \
2740 } \
2741 }
2742 #ifdef WIN32
2743 #include "..\tritemp.h"
2744 #else
2745 #include "tritemp.h"
2746 #endif
2747 }
2748
2749 /*
2750 * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
2751 */
2752
2753 static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
2754 GLuint v2, GLuint pv )
2755 {
2756 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2757 DITHER_RGB_TO_8BIT_SETUP
2758 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
2759 #define PIXEL_TYPE GLubyte
2760 #define BYTES_PER_ROW (wmesa->ScanWidth)
2761
2762 #define INNER_LOOP( LEFT, RIGHT, Y ) \
2763 { \
2764 GLint xx, yy = FLIP(Y); \
2765 PIXEL_TYPE *pixel = pRow; \
2766 for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \
2767 DITHER_RGB_TO_8BIT( VB->Color[pv][0], \
2768 VB->Color[pv][1], VB->Color[pv][2], xx, yy); \
2769 *pixel = pixelDithered; \
2770 } \
2771 }
2772 #ifdef WIN32
2773 #include "..\tritemp.h"
2774 #else
2775 #include "tritemp.h"
2776 #endif
2777 }
2778
2779
2780
2781
2782 static triangle_func choose_triangle_function( GLcontext *ctx )
2783 {
2784 WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
2785 int depth = wmesa->cColorBits;
2786
2787 if (ctx->Polygon.SmoothFlag) return NULL;
2788 if (ctx->Texture.Enabled) return NULL;
2789 if (!wmesa->db_flag) return NULL;
2790 /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
2791 if ( ctx->Light.ShadeModel==GL_SMOOTH
2792 && ctx->_RasterMask==DEPTH_BIT
2793 && ctx->Depth.Func==GL_LESS
2794 && ctx->Depth.Mask==GL_TRUE
2795 && ctx->Polygon.StippleFlag==GL_FALSE) {
2796 switch (wmesa->pixelformat) {
2797 case PF_8A8B8G8R:
2798 return smooth_8A8B8G8R_z_triangle;
2799 case PF_8R8G8B:
2800 return smooth_8R8G8B_z_triangle;
2801 case PF_5R6G5B:
2802 return smooth_5R6G5B_z_triangle;
2803 case PF_DITHER8:
2804 return smooth_DITHER8_z_triangle;
2805 case PF_INDEX8:
2806 return smooth_ci_z_triangle;
2807 default:
2808 return NULL;
2809 }
2810 }
2811 if ( ctx->Light.ShadeModel==GL_FLAT
2812 && ctx->_RasterMask==DEPTH_BIT
2813 && ctx->Depth.Func==GL_LESS
2814 && ctx->Depth.Mask==GL_TRUE
2815 && ctx->Polygon.StippleFlag==GL_FALSE) {
2816 switch (wmesa->pixelformat) {
2817 case PF_8A8B8G8R:
2818 return flat_8A8B8G8R_z_triangle;
2819 case PF_8R8G8B:
2820 return flat_8R8G8B_z_triangle;
2821 case PF_5R6G5B:
2822 return flat_5R6G5B_z_triangle;
2823 case PF_DITHER8:
2824 return flat_DITHER8_z_triangle;
2825 case PF_INDEX8:
2826 return flat_ci_z_triangle;
2827 default:
2828 return NULL;
2829 }
2830 }
2831 if ( ctx->_RasterMask==0 /* no depth test */
2832 && ctx->Light.ShadeModel==GL_SMOOTH
2833 && ctx->Polygon.StippleFlag==GL_FALSE) {
2834 switch (wmesa->pixelformat) {
2835 case PF_8A8B8G8R:
2836 return smooth_8A8B8G8R_triangle;
2837 case PF_8R8G8B:
2838 return smooth_8R8G8B_triangle;
2839 case PF_5R6G5B:
2840 return smooth_5R6G5B_triangle;
2841 case PF_DITHER8:
2842 return smooth_DITHER8_triangle;
2843 case PF_INDEX8:
2844 return smooth_ci_triangle;
2845 default:
2846 return NULL;
2847 }
2848 }
2849
2850 if ( ctx->_RasterMask==0 /* no depth test */
2851 && ctx->Light.ShadeModel==GL_FLAT
2852 && ctx->Polygon.StippleFlag==GL_FALSE) {
2853 switch (wmesa->pixelformat) {
2854 case PF_8A8B8G8R:
2855 return flat_8A8B8G8R_triangle;
2856 case PF_8R8G8B:
2857 return flat_8R8G8B_triangle;
2858 case PF_5R6G5B:
2859 return flat_5R6G5B_triangle;
2860 case PF_DITHER8:
2861 return flat_DITHER8_triangle;
2862 case PF_INDEX8:
2863 return flat_ci_triangle;
2864 default:
2865 return NULL;
2866 }
2867 }
2868
2869 return NULL;
2870 }
2871 }
2872
2873 /*
2874 * Define a new viewport and reallocate auxillary buffers if the size of
2875 * the window (color buffer) has changed.
2876 */
2877 void WMesaViewport( GLcontext *ctx,
2878 GLint x, GLint y, GLsizei width, GLsizei height )
2879 {
2880 /* Save viewport */
2881 ctx->Viewport.X = x;
2882 ctx->Viewport.Width = width;
2883 ctx->Viewport.Y = y;
2884 ctx->Viewport.Height = height;
2885
2886 /* compute scale and bias values */
2887 ctx->Viewport.Sx = (GLfloat) width / 2.0F;
2888 ctx->Viewport.Tx = ctx->Viewport.Sx + x;
2889 ctx->Viewport.Sy = (GLfloat) height / 2.0F;
2890 ctx->Viewport.Ty = ctx->Viewport.Sy + y;
2891 }