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