Initial revision
[mesa.git] / src / mesa / drivers / dos / dosmesa.c
1 /* $Id: dosmesa.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 2.3
6 * Copyright (C) 1995-1997 Brian Paul
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24 /*
25 * $Log: dosmesa.c,v $
26 * Revision 1.1 1999/08/19 00:55:41 jtg
27 * Initial revision
28 *
29 * Revision 1.2 1999/03/28 21:11:57 brianp
30 * updated SetBuffer driver function
31 *
32 * Revision 1.1 1999/02/24 03:56:31 brianp
33 * initial check-in
34 *
35 *
36 * Revision 1.5 1997/06/19 22:00:00 Brian Paul
37 * Removed all ColorShift stuff
38 *
39 * Revision 1.4 1997/06/03 19:00:00 Brian Paul
40 * Replaced VB->Unclipped[] with VB->ClipMask[]
41 *
42 * Revision 1.3 1997/05/28 07:00:00 Phil Frisbie, Jr.
43 * Now pass red/green/blue/alpha bits to gl_create_visual()
44 * Fixed DJGPP mode 13 support.
45 *
46 * Revision 1.2 1996/12/08 16:13:45 Charlie
47 * Added VESA support via Scitechs SVGA kit.
48 *
49 * Revision 1.1 1996/12/08 16:09:52 Charlie
50 * Initial revision
51 *
52 */
53
54
55 /*
56 * DOS VGA/VESA/MGL/Mesa interface.
57 *
58 */
59
60 /*
61 *
62 * TODO: (cw)
63 * Improve the colour matcher for rgb non vesa modes, its pretty bad and incorrect
64 * Keyboard interrupt.
65 * Comments and tidy up.
66 * Add support for VESA without SVGAKIT.
67 * DirectX Support.
68 * Better GLIDE Support.
69 * Clear up the #ifdef madness.
70 */
71
72 #ifdef DOSVGA
73
74 #if defined(DOSVGA) && !defined(GLIDE) && defined(DJGPP) && !defined(UNIVBE) && !defined(MGL)
75
76 /* Should help cut down on the crazy #if`s */
77 #define MODE13 1
78
79 #else
80 #undef MODE13
81 #endif
82
83 #include <stdio.h>
84 #include <stdlib.h>
85 #include <string.h>
86 #include <string.h>
87 #include <dos.h>
88
89 #ifdef DJGPP
90 #include <go32.h>
91 #endif
92
93 #ifdef MGL
94 #include <mgraph.h>
95 #endif
96
97 #include "GL/DOSmesa.h"
98 #include "context.h"
99 #include "matrix.h"
100 #include "types.h"
101
102 #ifdef GLIDE
103
104 static void glideshutdown( void );
105 #include "vb.h"
106 #include "glide.h"
107
108 /* the glide modes available, set one */
109
110 //#define GLIDE_MODE GR_RESOLUTION_
111 #define GLIDE_MODE GR_RESOLUTION_800x600
112 //#define GLIDE_MODE GR_RESOLUTION_640x480
113
114 static GrVertex gr_vtx,gr_vtx1,gr_vtx2;
115
116 #endif
117
118 #ifdef UNIVBE
119 /* You get this file from Scitechs VESA development kit */
120 #include "svga.h"
121
122 /*
123 Set these to the VESA mode you require, the first is for 256 colour modes,
124 the other is High colour modes, they must both be the same XRes and YRes.
125 */
126
127 #define VESA_256COLOUR_MODE 0x11c
128 #define VESA_HICOLOUR_MODE 0x11f
129
130 #endif
131
132 struct DOSmesa_context {
133 GLcontext *gl_ctx; /* the core Mesa context */
134 GLvisual *gl_vis; /* describes the color buffer */
135 GLframebuffer *gl_buffer; /* the ancillary buffers */
136 GLuint index; /* current color index */
137 GLint red, green, blue; /* current rgb color */
138 GLint width, height; /* size of color buffer */
139 GLint depth; /* bits per pixel (8,16,24 or 32) */
140 };
141
142 static DOSMesaContext DOSMesa = NULL; /* the current context */
143
144 #ifdef UNIVBE
145 SV_devCtx *DC=NULL;
146 int useLinear = TRUE;
147 SV_modeInfo *mi=NULL;
148 unsigned long modeNumber = 0;
149
150 int activePage = 0;
151 int visualPage = 1;
152
153 #endif
154
155 #if defined(MODE13)
156
157 /* DOSVGA With no UniVBE support */
158
159 unsigned char *video_buffer;
160
161 #define VID_BUF(x,y) *(video_buffer+x+(y*320))
162
163 #if defined(__WATCOMC__) && defined(__386__) && defined(__DOS__)
164
165 void setupcopy(void);
166 void copyscr(void);
167
168 /* Watcom C specfic, screen copy and clear */
169
170 #pragma aux setupcopy = \
171 ".386P"\
172 "push ebp" \
173 "mov esi,video_buffer" \
174 "mov edi,0xa0000" \
175 "mov ecx,2000" \
176 "xor ebp,ebp";
177
178 #pragma aux copyscr = \
179 ".386P" \
180 "lop1: mov eax,[esi]"\
181 "mov ebx,[esi+4]"\
182 "mov edx,[esi+8]"\
183 "mov [edi],eax"\
184 "mov eax,[esi+12]"\
185 "mov dword ptr [esi],ebp"\
186 "mov dword ptr [esi+4],ebp"\
187 "mov dword ptr [esi+8],ebp"\
188 "mov dword ptr [esi+12],ebp"\
189 "mov [edi+4],ebx"\
190 "mov [edi+8],edx"\
191 "mov [edi+12],eax"\
192 "mov eax,[esi+16]"\
193 "mov ebx,[esi+4+16]"\
194 "mov edx,[esi+8+16]"\
195 "mov [edi+16],eax"\
196 "mov eax,[esi+12+16]"\
197 "mov dword ptr [esi+16],ebp"\
198 "mov dword ptr [esi+4+16],ebp"\
199 "mov dword ptr [esi+8+16],ebp"\
200 "mov dword ptr [esi+12+16],ebp"\
201 "mov [edi+4+16],ebx"\
202 "mov [edi+8+16],edx"\
203 "mov [edi+12+16],eax"\
204 "add esi,32"\
205 "add edi,32"\
206 "dec ecx"\
207 "jnz lop1"\
208 "pop ebp"\
209 modify exact [edi esi eax ebx ecx] ;
210
211 #endif // WATCOM
212
213 #endif // MODE13
214
215 /*
216 * Convert Mesa window Y coordinate to VGA screen Y coordinate:
217 */
218 #define FLIP(Y) (DOSMesa->height-(Y)-1)
219
220 unsigned short vga_cindex = 32768 ;
221
222 static points_func choose_points_function( void );
223 static line_func choose_line_function( void );
224 static triangle_func choose_polygon_function( void );
225 static void fast_tri(GLcontext *ctx,GLuint v0, GLuint v1, GLuint v2, GLuint pv );
226
227 static points_func choose_points_function( void )
228 {
229 return NULL;
230 }
231
232 static line_func choose_line_function( void )
233 {
234 return NULL;
235 }
236
237 static triangle_func choose_triangle_function( void )
238 {
239 #if defined(MODE13)
240 return NULL;
241 #endif
242
243 #if defined(GLIDE)
244 return fast_tri;
245 #endif
246
247 return NULL;
248 }
249
250
251 #if defined(MODE13)
252
253 void setgfxmode(void);
254 void settextmode(void);
255
256 #ifndef DJGPP
257 #pragma aux setgfxmode = \
258 "mov ax,13h" \
259 "int 10h" \
260 modify [eax];
261
262 #pragma aux settextmode = \
263 "mov ax,3h" \
264 "int 10h" \
265 modify [eax];
266 #else
267 void setgfxmode(void)
268 {
269 union REGS in_regs,out_regs;
270
271 in_regs.x.ax = 0x13;
272 int386(0x10,&in_regs,&out_regs);
273 }
274
275 void settextmode(void)
276 {
277 union REGS in_regs,out_regs;
278
279 in_regs.x.ax = 0x3;
280 int386(0x10,&in_regs,&out_regs);
281 }
282
283 #endif
284
285 int set_video_mode(unsigned short x,unsigned short y,char mode)
286 {
287 setgfxmode();
288 return 1; /* likelyhood of this failing is very small */
289 }
290
291 void restore_video_mode(void)
292 {
293 settextmode();
294 }
295
296 int vga_getcolors(void)
297 {
298 return vga_cindex;
299 }
300
301 int vga_getxdim(void)
302 {
303 return 320;
304 }
305
306 int vga_getydim(void)
307 {
308 return 200;
309 }
310
311 static unsigned short num_rgb_alloc = 1; /* start from 1, zero is black */
312
313 /* an unlikely colour */
314 static unsigned char last_r=1,last_g=255,last_b=99;
315
316 extern void set_onecolor(int index,int R,int G,int B);
317
318 static unsigned char rgbtable[64][64][64];
319
320 void vga_setrgbcolor(int r,int g,int b)
321 {
322
323 /*
324 * make this into a translation table
325 */
326
327 DOSMesa->red = r;
328 DOSMesa->green = g ;
329 DOSMesa->blue = b ;
330
331 r/=4; g/=4; b/=4;
332
333 if( (r == last_r) && (g == last_g) && (b == last_b) ) return;
334
335 last_r = r ;
336 last_g = g ;
337 last_b = b ;
338
339 if(r+g+b == 0 ) {
340 DOSMesa->index = 0 ;
341 return ;
342 }
343
344 if( rgbtable[r][g][b] == 0 ) {
345 /* not allocated yet */
346 if(num_rgb_alloc<256) {
347 DOSMesa->index = num_rgb_alloc;
348 set_onecolor(num_rgb_alloc,r,g,b);
349 rgbtable[r][g][b] = num_rgb_alloc;
350 num_rgb_alloc++;
351 return;
352
353 } else {
354 /* need to search for a close colour */
355 {
356 unsigned short pass ;
357
358 for(pass=0;pass<64;pass++) {
359 if(r-pass>0) {
360 if( rgbtable[r-pass][g][b] !=0 ) {
361 rgbtable[r][g][b] = rgbtable[r-pass][g][b];
362 DOSMesa->index = rgbtable[r-pass][g][b];
363 return;
364 }
365 }
366 if(r+pass<64) {
367 if( rgbtable[r+pass][g][b] !=0 ) {
368 rgbtable[r][g][b] = rgbtable[r+pass][g][b];
369 DOSMesa->index = rgbtable[r+pass][g][b];
370 return;
371 }
372 }
373 }
374 }
375 rgbtable[r][g][b] = rand()%255;
376 }
377 }
378 DOSMesa->index = rgbtable[r][g][b];
379 }
380
381 #if defined(DJGPP)
382 static int dos_seg;
383 #endif
384
385 void vga_clear(void)
386 {
387
388 /* Check if we`re using watcom and DOS */
389 #if defined(__WATCOMC__) && defined(__386__) && defined(__DOS__)
390 setupcopy();
391 copyscr();
392 #else
393
394 #if defined (DJGPP)
395
396
397 asm ("
398 pusha
399 pushw %es
400
401 movw _dos_seg, %es
402
403 movl _video_buffer, %esi
404 movl $0xa0000, %edi
405
406 movl $64000, %ecx
407
408 rep ; movsb
409
410 popw %es
411 popa
412 ");
413
414 #else
415
416 /* copy the RAM buffer to the Video memory */
417 memcpy((unsigned char *)0xa0000,video_buffer, vga_getxdim()*vga_getydim() );
418
419 #endif //DJGPP
420
421 /* clear the RAM buffer */
422 memset(video_buffer,0, vga_getxdim()*vga_getydim() );
423
424 #endif //WATCOMC
425
426 }
427
428 #ifndef DEBUG
429 #define vga_drawpixel(x,y) { VID_BUF(x,y) = DOSMesa->index; }
430 #else
431 void vga_drawpixel(x,y)
432 {
433 VID_BUF(x,y) = DOSMesa->index;
434 }
435 #endif
436
437 int vga_getpixel(int x,int y)
438 {
439 return 1;
440 }
441
442 void vga_flip(void)
443 {
444
445 }
446
447 void vga_setcolor(int index)
448 {
449 /* does something, what i`ve no idea */
450 DOSMesa->index = index;
451
452 }
453
454 #endif
455
456 #if defined(UNIVBE)
457
458 /* UniVBE VESA support */
459
460 void set_video_mode(unsigned short x,unsigned short y,char mode)
461 {
462 if( setup_vesa_mode(x,y,mode) == FALSE ) {
463 fprintf(stderr,"VESA: Set mode failed\n");
464 exit(1);
465 }
466 }
467
468 /*
469 This is problematic as we don`t know what resolution the user program
470 wants when we reach here. This is why the 256 colour and HiColour modes
471 should be the same resolution, perhaps i`ll make this an environment
472 variable
473 */
474
475
476 void check_mi(void)
477 {
478 if(mi!=0) return;
479
480 if(DC==NULL) {
481 DC = SV_init( TRUE );
482 }
483
484 if(modeNumber == 0 ) {
485 modeNumber = VESA_HICOLOUR_MODE;
486 }
487
488 SV_getModeInfo(modeNumber,mi);
489
490 return;
491 }
492
493 int setup_vesa_mode(short height,short width,short depth)
494 {
495 if(DC==NULL) {
496 DC = SV_init( TRUE );
497 /* how many bits per pixel */
498 if( depth == 0)
499 modeNumber = VESA_256COLOUR_MODE;
500 else
501 modeNumber = VESA_HICOLOUR_MODE;
502 }
503
504 /* Check if correct VESA Version is available */
505 if( !DC || DC->VBEVersion < 0x0102) {
506 fprintf(stderr,"Require a VESA VBE version 1.2 or higher\n");
507 return FALSE;
508 }
509
510 /* Check for LFB Supprt */
511 if(DC->VBEVersion < 0x0200 ) {
512 useLinear = FALSE;
513 } else {
514 useLinear = TRUE ;
515 }
516
517 /* Get desired mode info */
518 if(!SV_getModeInfo( modeNumber, mi))
519 return FALSE;
520
521 /* Set VESA mode */
522 if(!SV_setMode(modeNumber | svMultiBuffer, FALSE, TRUE, mi->NumberOfPages) )
523 return FALSE;
524
525 return TRUE;
526 }
527
528 void restore_video_mode(void)
529 {
530 SV_restoreMode();
531 }
532
533 void vga_clear(void)
534 {
535 SV_clear(0);
536 }
537
538 void vga_flip(void)
539 {
540 activePage = 1-activePage;
541 visualPage = 1-activePage;
542
543 SV_setActivePage(activePage);
544
545 /*
546 Change false to true if you`re getting flickering
547 even in double buffer mode, ( sets wait for Vertical retrace )
548 */
549 SV_setVisualPage(visualPage,false);
550 }
551
552 int vga_getcolors(void)
553 {
554 check_mi();
555 switch ( mi->BitsPerPixel ) {
556 case 8:
557 return 256;
558 case 15:
559 case 16:
560 return 32768;
561 default:
562 return 64000;
563 }
564 }
565
566 int vga_getxdim(void)
567 {
568 check_mi();
569 return mi->XResolution;
570 }
571
572 int vga_getydim(void)
573 {
574 check_mi();
575 return mi->YResolution;
576 }
577
578 unsigned long current_color = 255;
579
580 void vga_setrgbcolor(int r,int g,int b)
581 {
582 DOSMesa->red = r;
583 DOSMesa->green = g ;
584 DOSMesa->blue = b ;
585 current_color = SV_rgbColor(r,g,b);
586 }
587
588 void vga_setcolor(int index)
589 {
590 DOSMesa->index = index;
591 current_color = index;
592 }
593
594 void vga_drawpixel(x,y)
595 {
596 SV_putPixel(x,y,current_color);
597 }
598
599 /* TODO: */
600 int vga_getpixel(x,y)
601 {
602 /* return (int)SV_getPixel(x,y); */
603 fprintf(stderr,"vga_getpixel: Not implemented yet\n");
604 return 1;
605 }
606
607 /* End of UNIVBE section */
608 #endif
609
610 /* Scitechs MegaGraphicsLibrary http://www.scitechsoft.com/ */
611
612 #if defined(MGL)
613
614 /* MGL support */
615 struct MI {
616 unsigned short BitsPerPixel;
617 unsigned long XResolution;
618 unsigned long YResolution;
619 };
620
621 struct MI*mi;
622
623 static MGLDC*DC;
624 static int activePage = 0;
625 static int visualPage = 1;
626 static int modeNumber = 0;
627
628 void set_video_mode(unsigned short xres,unsigned short yres,char mode)
629 {
630 int i,driver = grDETECT,dmode = grDETECT;
631 event_t evt;
632
633 /* Start the MGL with only the SVGA 16m driver active */
634 MGL_registerDriver(MGL_SVGA16NAME,SVGA16_driver);
635 if (!MGL_init(&driver,&dmode,"..\\..\\"))
636 MGL_fatalError(MGL_errorMsg(MGL_result()));
637 if ((DC = MGL_createDisplayDC(false)) == NULL)
638 MGL_fatalError(MGL_errorMsg(MGL_result()));
639 MGL_makeCurrentDC(DC);
640 }
641
642 /*
643 This is problematic as we don`t know what resolution the user program
644 wants when we reach here. This is why the 256 colour and HiColour modes
645 should be the same resolution, perhaps i`ll make this an environment
646 variable
647 */
648
649 #define MGL_HICOLOUR_MODE 0
650
651
652 void check_mi(void)
653 {
654 if(mi!=0) return;
655
656 if(DC==NULL) {
657 // DC = SV_init( TRUE );
658 }
659
660 if(modeNumber == 0 ) {
661 modeNumber = MGL_HICOLOUR_MODE;
662 }
663
664 // SV_getModeInfo(modeNumber,mi);
665
666 return;
667 }
668
669 void restore_video_mode(void)
670 {
671 MGL_exit();
672 }
673
674 void vga_clear(void)
675 {
676 MGL_clearDevice();
677 }
678
679 void vga_flip(void)
680 {
681 activePage = 1-activePage;
682 visualPage = 1-activePage;
683
684 // SV_setActivePage(activePage);
685
686 /*
687 Change false to true if you`re getting flickering
688 even in double buffer mode, ( sets wait for Vertical retrace )
689 */
690 // SV_setVisualPage(visualPage,false);
691 }
692
693 int vga_getcolors(void)
694 {
695 check_mi();
696 switch ( mi->BitsPerPixel ) {
697 case 8:
698 return 256;
699 case 15:
700 case 16:
701 return 32768;
702 default:
703 return 64000;
704 }
705 }
706
707 int vga_getxdim(void)
708 {
709 check_mi();
710 return mi->XResolution;
711 }
712
713 int vga_getydim(void)
714 {
715 check_mi();
716 return mi->YResolution;
717 }
718
719 unsigned long current_color = 255;
720
721 void vga_setrgbcolor(int r,int g,int b)
722 {
723 DOSMesa->red = r;
724 DOSMesa->green = g ;
725 DOSMesa->blue = b ;
726 current_color = MGL_rgbColor(DC,r,g,b);
727 }
728
729 void vga_setcolor(int index)
730 {
731 DOSMesa->index = index;
732 current_color = index;
733 }
734
735 void vga_drawpixel(x,y)
736 {
737 MGL_pixelCoord(x,y);
738 }
739
740 /* TODO: */
741 int vga_getpixel(x,y)
742 {
743 /* return (int)SV_getPixel(x,y); */
744 fprintf(stderr,"vga_getpixel: Not implemented yet\n");
745 return 1;
746 }
747
748 /* End of UNIVBE section */
749 #endif
750
751 #ifdef GLIDE
752
753 /* GLIDE support */
754
755 static GrHwConfiguration hwconfig;
756
757 void set_video_mode(unsigned short x,unsigned short y,char mode)
758 {
759 grGlideInit();
760 if( grSstQueryHardware( &hwconfig ) ) {
761 grSstSelect( 0 ) ;
762 if( !grSstOpen( GLIDE_MODE,
763 GR_REFRESH_60Hz,
764 GR_COLORFORMAT_ABGR,
765 GR_ORIGIN_UPPER_LEFT,
766 GR_SMOOTHING_ENABLE,
767 2 ) ) {
768 fprintf(stderr,"Detected 3DFX board, but couldn`t initialize!");
769 exit(1);
770 }
771
772 grBufferClear( 0, 0, GR_WDEPTHVALUE_FARTHEST);
773
774 grDisableAllEffects();
775 atexit( glideshutdown );
776
777 // guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
778 // grTexCombineFunction( GR_TMU0, GR_TEXTURECOMBINE_ZERO);
779 }
780 }
781
782 void restore_video_mode(void)
783 {
784 }
785
786 static void glideshutdown( void )
787 {
788 grGlideShutdown() ;
789 }
790
791 void vga_clear(void)
792 {
793 grBufferSwap(0);
794 grBufferClear( 0, 0, GR_WDEPTHVALUE_FARTHEST);
795 }
796
797 void vga_flip(void)
798 {
799 }
800
801 int vga_getcolors(void)
802 {
803 return 32768;
804 }
805
806 int vga_getxdim(void)
807 {
808 #if GLIDE_MODE == GR_RESOLUTION_800x600
809 return 800;
810 #else
811 return 640;
812 #endif
813 }
814
815 int vga_getydim(void)
816 {
817 #if GLIDE_MODE == GR_RESOLUTION_800x600
818 return 600;
819 #else
820 return 480;
821 #endif
822 }
823
824 unsigned long current_color = 255;
825
826 void vga_setrgbcolor(int r,int g,int b)
827 {
828 DOSMesa->red = r;
829 DOSMesa->green = g ;
830 DOSMesa->blue = b ;
831 }
832
833 void vga_setcolor(int index)
834 {
835 DOSMesa->index = index;
836 }
837
838 void vga_drawpixel(x,y)
839 {
840
841 gr_vtx.x = x;
842 gr_vtx.y = y;
843 gr_vtx.z = 0;
844 gr_vtx.r = DOSMesa->red;
845 gr_vtx.g = DOSMesa->green;
846 gr_vtx.b = DOSMesa->blue;
847
848 grDrawPoint( &gr_vtx );
849 }
850
851 static void fast_tri(GLcontext *ctx,GLuint v0, GLuint v1, GLuint v2, GLuint pv )
852 {
853 struct vertex_buffer *VB = ctx->VB;
854
855 gr_vtx.z = 0;
856 gr_vtx1.z = 0;
857 gr_vtx2.z = 0;
858
859 if (VB->MonoColor) {
860 gr_vtx.r = DOSMesa->red;
861 gr_vtx.g = DOSMesa->green;
862 gr_vtx.b = DOSMesa->blue;
863 gr_vtx1.r = DOSMesa->red;
864 gr_vtx1.g = DOSMesa->green;
865 gr_vtx1.b = DOSMesa->blue;
866 gr_vtx2.r = DOSMesa->red;
867 gr_vtx2.g = DOSMesa->green;
868 gr_vtx2.b = DOSMesa->blue;
869 } else {
870 if(ctx->Light.ShadeModel == GL_SMOOTH ) {
871 gr_vtx.r = FixedToInt( VB->Color[v0][0] );
872 gr_vtx.g = FixedToInt( VB->Color[v0][1] );
873 gr_vtx.b = FixedToInt( VB->Color[v0][2] );
874
875 gr_vtx1.r = FixedToInt( VB->Color[v1][0] );
876 gr_vtx1.g = FixedToInt( VB->Color[v1][1] );
877 gr_vtx1.b = FixedToInt( VB->Color[v1][2] );
878
879 gr_vtx2.r = FixedToInt( VB->Color[v2][0] );
880 gr_vtx2.g = FixedToInt( VB->Color[v2][1] );
881 gr_vtx2.b = FixedToInt( VB->Color[v2][2] );
882 } else {
883 gr_vtx.r = VB->Color[pv][0];
884 gr_vtx.g = VB->Color[pv][1];
885 gr_vtx.b = VB->Color[pv][2];
886
887 gr_vtx1.r = VB->Color[pv][0];
888 gr_vtx1.g = VB->Color[pv][1];
889 gr_vtx1.b = VB->Color[pv][2];
890
891 gr_vtx2.r = VB->Color[pv][0];
892 gr_vtx2.g = VB->Color[pv][1];
893 gr_vtx2.b = VB->Color[pv][2];
894 }
895 }
896
897 gr_vtx.x = (VB->Win[v0][0] );
898 gr_vtx.y = FLIP( (VB->Win[v0][1] ) );
899 gr_vtx1.x = (VB->Win[v1][0] );
900 gr_vtx1.y = FLIP( (VB->Win[v1][1] ) );
901 gr_vtx2.x = (VB->Win[v2][0] );
902 gr_vtx2.y = FLIP( (VB->Win[v2][1] ) );
903
904 if(gr_vtx.x <0 || gr_vtx.x > 639 )
905 return;
906 if(gr_vtx1.x <0 || gr_vtx1.x > 639 )
907 return;
908 if(gr_vtx2.x <0 || gr_vtx2.x > 639 )
909 return;
910
911 if(gr_vtx.y <0 || gr_vtx.y > 479 )
912 return;
913 if(gr_vtx1.y <0 || gr_vtx1.y > 479 )
914 return;
915 if(gr_vtx2.y <0 || gr_vtx2.y > 479 )
916 return;
917
918 grDrawTriangle( &gr_vtx,&gr_vtx1,&gr_vtx2);
919 }
920
921 void fast_plot(GLcontext *ctx,GLuint first,GLuint last )
922 {
923 struct vertex_buffer *VB = ctx->VB;
924 register GLuint i;
925
926 if(VB->MonoColor) {
927 /* all same color */
928
929 gr_vtx.r = DOSMesa->red;
930 gr_vtx.g = DOSMesa->green;
931 gr_vtx.b = DOSMesa->blue;
932
933 for(i=first;i<last;i++) {
934 if(VB->ClipMask[i]==0) {
935 gr_vtx.x = VB->Win[i][0];
936 gr_vtx.y = FLIP(VB->Win[i][1]);
937 }
938 }
939 }
940 }
941
942 /* TODO: */
943 int vga_getpixel(x,y)
944 {
945 /* return (int)SV_getPixel(x,y); */
946 fprintf(stderr,"vga_getpixel: Not implemented yet\n");
947 return 1;
948 }
949
950 /* End of GLIDE section */
951
952 #endif // GLIDE
953 /**********************************************************************/
954 /***** Miscellaneous functions *****/
955 /**********************************************************************/
956
957
958 static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
959 {
960 *width = DOSMesa->width = vga_getxdim();
961 *height = DOSMesa->height = vga_getydim();
962 }
963
964
965 /* Set current color index */
966 static void set_index( GLcontext *ctx, GLuint index )
967 {
968 DOSMesa->index = index;
969 /*vga_setcolor( index );*/
970 }
971
972
973 /* Set current drawing color */
974 static void set_color( GLcontext *ctx,
975 GLubyte red, GLubyte green,
976 GLubyte blue, GLubyte alpha )
977 {
978 DOSMesa->red = red;
979 DOSMesa->green = green;
980 DOSMesa->blue = blue;
981 vga_setrgbcolor( red, green, blue );
982 }
983
984
985 static void clear_index( GLcontext *ctx, GLuint index )
986 {
987 /* TODO: Implements glClearIndex() */
988 }
989
990
991 static void clear_color( GLcontext *ctx,
992 GLubyte red, GLubyte green,
993 GLubyte blue, GLubyte alpha )
994 {
995 /* TODO: Implements glClearColor() */
996 }
997
998
999 static void clear( GLcontext *ctx,
1000 GLboolean all,
1001 GLint x, GLint y, GLint width, GLint height )
1002 {
1003 vga_clear();
1004 }
1005
1006
1007 static GLboolean set_buffer( GLcontext *ctx,
1008 GLenum mode )
1009 {
1010 /* TODO: implement double buffering and use this function to select */
1011 /* between front and back buffers. */
1012 if (buffer == GL_FRONT_LEFT)
1013 return GL_TRUE;
1014 else if (buffer == GL_BACK_LEFT)
1015 return GL_TRUE;
1016 else
1017 return GL_FALSE;
1018 }
1019
1020
1021
1022
1023 /**********************************************************************/
1024 /***** Write spans of pixels *****/
1025 /**********************************************************************/
1026
1027
1028 static void write_index_span( GLcontext *ctx,
1029 GLuint n, GLint x, GLint y,
1030 const GLuint index[],
1031 const GLubyte mask[] )
1032 {
1033 int i;
1034 y = FLIP(y);
1035 #ifdef UNIVBE
1036 SV_beginPixel();
1037 #endif
1038 for (i=0;i<n;i++,x++) {
1039 if (mask[i]) {
1040 #ifdef UNIVBE
1041 SV_putPixelFast(x,y,current_color);
1042 #else
1043 vga_setcolor( index[i] );
1044 vga_drawpixel( x, y );
1045 #endif
1046 }
1047 }
1048
1049 #ifdef UNIVBE
1050 SV_endPixel();
1051 #endif
1052
1053 }
1054
1055
1056
1057 static void write_monoindex_span( GLcontext *ctx,
1058 GLuint n, GLint x, GLint y,
1059 const GLubyte mask[] )
1060 {
1061 int i;
1062 y = FLIP(y);
1063 /* use current color index */
1064 vga_setcolor( DOSMesa->index );
1065 #ifdef UNIVBE
1066 SV_beginPixel();
1067 #endif
1068 for (i=0;i<n;i++,x++) {
1069 if (mask[i]) {
1070 #ifdef UNIVBE
1071 SV_putPixelFast(x,y,current_color);
1072 #else
1073 vga_drawpixel( x, y );
1074 #endif
1075 }
1076 }
1077 #ifdef UNIVBE
1078 SV_endPixel();
1079 #endif
1080 }
1081
1082
1083
1084 static void write_color_span( GLcontext *ctx,
1085 GLuint n, GLint x, GLint y,
1086 const GLubyte red[], const GLubyte green[],
1087 const GLubyte blue[], const GLubyte alpha[],
1088 const GLubyte mask[] )
1089 {
1090 int i;
1091 y=FLIP(y);
1092 #ifdef UNIVBE
1093 SV_beginPixel();
1094 #endif
1095 if (mask) {
1096 /* draw some pixels */
1097 for (i=0; i<n; i++, x++) {
1098 if (mask[i]) {
1099 #ifdef UNIVBE
1100 SV_putPixelFast(x,y,SV_rgbColor(red[i], green[i], blue[i]) );
1101 #else
1102 vga_setrgbcolor( red[i], green[i], blue[i] );
1103 vga_drawpixel( x, y );
1104 #endif
1105 }
1106 }
1107 }
1108 else {
1109 /* draw all pixels */
1110 for (i=0; i<n; i++, x++) {
1111 #ifdef UNIVBE
1112 SV_putPixelFast(x,y,SV_rgbColor(red[i], green[i], blue[i]) );
1113 #else
1114 vga_setrgbcolor( red[i], green[i], blue[i] );
1115 vga_drawpixel( x, y );
1116 #endif
1117 }
1118 }
1119 #ifdef UNIVBE
1120 SV_endPixel();
1121 #endif
1122 }
1123
1124
1125
1126 static void write_monocolor_span( GLcontext *ctx,
1127 GLuint n, GLint x, GLint y,
1128 const GLubyte mask[])
1129 {
1130 int i;
1131 y=FLIP(y);
1132 #ifdef UNIVBE
1133 SV_beginPixel();
1134 #endif
1135 /* use current rgb color */
1136 vga_setrgbcolor( DOSMesa->red, DOSMesa->green, DOSMesa->blue );
1137 for (i=0; i<n; i++, x++) {
1138 if (mask[i]) {
1139 #ifdef UNIVBE
1140 SV_putPixelFast(x,y,current_color);
1141 #else
1142 vga_drawpixel( x, y );
1143 #endif
1144 }
1145 }
1146 #ifdef UNIVBE
1147 SV_endPixel();
1148 #endif
1149 }
1150
1151
1152
1153 /**********************************************************************/
1154 /***** Read spans of pixels *****/
1155 /**********************************************************************/
1156
1157
1158 static void read_index_span( GLcontext *ctx,
1159 GLuint n, GLint x, GLint y, GLuint index[])
1160 {
1161 int i;
1162 y = FLIP(y);
1163 for (i=0; i<n; i++,x++) {
1164 index[i] = vga_getpixel( x, y );
1165 }
1166 }
1167
1168
1169
1170 static void read_color_span( GLcontext *ctx,
1171 GLuint n, GLint x, GLint y,
1172 GLubyte red[], GLubyte green[],
1173 GLubyte blue[], GLubyte alpha[] )
1174 {
1175 int i;
1176 for (i=0; i<n; i++, x++) {
1177 /* TODO */
1178 }
1179 }
1180
1181
1182
1183 /**********************************************************************/
1184 /***** Write arrays of pixels *****/
1185 /**********************************************************************/
1186
1187
1188 static void write_index_pixels( GLcontext *ctx,
1189 GLuint n, const GLint x[], const GLint y[],
1190 const GLuint index[], const GLubyte mask[] )
1191 {
1192 int i;
1193 #ifdef UNIVBE
1194 SV_beginPixel();
1195 #endif
1196 for (i=0; i<n; i++) {
1197 if (mask[i]) {
1198 #ifdef UNIVBE
1199 SV_putPixelFast(x[i], FLIP(y[i]), index[i] );
1200 #else
1201 vga_setcolor( index[i] );
1202 vga_drawpixel( x[i], FLIP(y[i]) );
1203 #endif
1204 }
1205 }
1206 #ifdef UNIVBE
1207 SV_endPixel();
1208 #endif
1209 }
1210
1211
1212
1213 static void write_monoindex_pixels( GLcontext *ctx,
1214 GLuint n,
1215 const GLint x[], const GLint y[],
1216 const GLubyte mask[] )
1217 {
1218 int i;
1219 /* use current color index */
1220 vga_setcolor( DOSMesa->index );
1221 #ifdef UNIVBE
1222 SV_beginPixel();
1223 #endif
1224 for (i=0; i<n; i++) {
1225 if (mask[i]) {
1226 #ifdef UNIVBE
1227 SV_putPixelFast(x[i], FLIP(y[i]), DOSMesa->index);
1228 #else
1229 vga_drawpixel( x[i], FLIP(y[i]) );
1230 #endif
1231 }
1232 }
1233 #ifdef UNIVBE
1234 SV_endPixel();
1235 #endif
1236 }
1237
1238
1239
1240 static void write_color_pixels( GLcontext *ctx,
1241 GLuint n, const GLint x[], const GLint y[],
1242 const GLubyte r[], const GLubyte g[],
1243 const GLubyte b[], const GLubyte a[],
1244 const GLubyte mask[] )
1245 {
1246 int i;
1247 #ifdef UNIVBE
1248 SV_beginPixel();
1249 #endif
1250 for (i=0; i<n; i++) {
1251 if (mask[i]) {
1252 #ifdef UNIVBE
1253 SV_putPixelFast(x[i], FLIP(y[i]), SV_rgbColor(r[i], g[i], b[i]) );
1254 #else
1255 vga_setrgbcolor( r[i], g[i], b[i] );
1256 vga_drawpixel( x[i], FLIP(y[i]) );
1257 #endif
1258 }
1259 }
1260 #ifdef UNIVBE
1261 SV_endPixel();
1262 #endif
1263 }
1264
1265 static void write_monocolor_pixels( GLcontext *ctx,
1266 GLuint n,
1267 const GLint x[], const GLint y[],
1268 const GLubyte mask[] )
1269 {
1270 int i;
1271 /* use current rgb color */
1272 vga_setrgbcolor( DOSMesa->red, DOSMesa->green, DOSMesa->blue );
1273 #ifdef UNIVBE
1274 SV_beginPixel();
1275 #endif
1276 for (i=0; i<n; i++) {
1277 if (mask[i]) {
1278 #ifdef UNIVBE
1279 SV_putPixelFast(x[i], FLIP(y[i]), current_color );
1280 #else
1281 vga_drawpixel( x[i], FLIP(y[i]) );
1282 #endif
1283 }
1284 }
1285 #ifdef UNIVBE
1286 SV_endPixel();
1287 #endif
1288 }
1289
1290 /**********************************************************************/
1291 /***** Read arrays of pixels *****/
1292 /**********************************************************************/
1293
1294 /* Read an array of color index pixels. */
1295 static void read_index_pixels( GLcontext *ctx,
1296 GLuint n, const GLint x[], const GLint y[],
1297 GLuint index[], const GLubyte mask[] )
1298 {
1299 int i;
1300 for (i=0; i<n; i++) {
1301 index[i] = vga_getpixel( x[i], FLIP(y[i]) );
1302 }
1303 }
1304
1305
1306
1307 static void read_color_pixels( GLcontext *ctx,
1308 GLuint n, const GLint x[], const GLint y[],
1309 GLubyte red[], GLubyte green[],
1310 GLubyte blue[], GLubyte alpha[],
1311 const GLubyte mask[] )
1312 {
1313 /* TODO */
1314 }
1315
1316 static void DOSmesa_setup_DD_pointers( GLcontext *ctx )
1317 {
1318 /* Initialize all the pointers in the DD struct. Do this whenever */
1319 /* a new context is made current or we change buffers via set_buffer! */
1320
1321 ctx->Driver.UpdateState = DOSmesa_setup_DD_pointers;
1322
1323 ctx->Driver.ClearIndex = clear_index;
1324 ctx->Driver.ClearColor = clear_color;
1325 ctx->Driver.Clear = clear;
1326
1327 ctx->Driver.Index = set_index;
1328 ctx->Driver.Color = set_color;
1329
1330 ctx->Driver.SetBuffer = set_buffer;
1331 ctx->Driver.GetBufferSize = get_buffer_size;
1332
1333 ctx->Driver.PointsFunc = choose_points_function();
1334 ctx->Driver.LineFunc = choose_line_function();
1335 ctx->Driver.TriangleFunc = choose_triangle_function();
1336
1337
1338 /* Pixel/span writing functions: */
1339 /* TODO: use different funcs for 8, 16, 32-bit depths */
1340 ctx->Driver.WriteColorSpan = write_color_span;
1341 ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
1342 ctx->Driver.WriteColorPixels = write_color_pixels;
1343 ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
1344 ctx->Driver.WriteIndexSpan = write_index_span;
1345 ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
1346 ctx->Driver.WriteIndexPixels = write_index_pixels;
1347 ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
1348
1349 /* Pixel/span reading functions: */
1350 /* TODO: use different funcs for 8, 16, 32-bit depths */
1351 ctx->Driver.ReadIndexSpan = read_index_span;
1352 ctx->Driver.ReadColorSpan = read_color_span;
1353 ctx->Driver.ReadIndexPixels = read_index_pixels;
1354 ctx->Driver.ReadColorPixels = read_color_pixels;
1355 }
1356
1357 /*
1358 * Create a new VGA/Mesa context and return a handle to it.
1359 */
1360 DOSMesaContext DOSMesaCreateContext( void )
1361 {
1362 DOSMesaContext ctx;
1363 GLboolean rgb_flag;
1364 GLfloat redscale, greenscale, bluescale, alphascale;
1365 GLboolean db_flag = GL_FALSE;
1366 GLboolean alpha_flag = GL_FALSE;
1367 int colors;
1368 GLint index_bits;
1369 GLint redbits, greenbits, bluebits, alphabits;
1370
1371 #if !defined(UNIVBE) && !defined(GLIDE) && !defined(MGL)
1372 video_buffer = (unsigned char *) malloc( vga_getxdim() * vga_getydim() );
1373
1374 memset(video_buffer,0, vga_getxdim() * vga_getydim() );
1375
1376 memset(rgbtable,0,sizeof( rgbtable ) );
1377 #endif
1378
1379 #if defined( DJGPP ) && !defined(UNIVBE) && !defined(GLIDE)
1380 dos_seg = _go32_conventional_mem_selector();
1381 #endif
1382
1383 /* determine if we're in RGB or color index mode */
1384 colors = vga_getcolors();
1385 if (colors==32768) {
1386 rgb_flag = GL_TRUE;
1387 redscale = greenscale = bluescale = alphascale = 255.0;
1388 redbits = greenbits = bluebits = 8;
1389 alphabits = 0;
1390 index_bits = 0;
1391 }
1392 else if (colors==256) {
1393 rgb_flag = GL_FALSE;
1394 redscale = greenscale = bluescale = alphascale = 0.0;
1395 redbits = greenbits = bluebits = alphabits = 0;
1396 index_bits = 8;
1397 }
1398 else {
1399 restore_video_mode();
1400 fprintf(stderr,"[%d] >16 bit color not implemented yet!\n",colors);
1401 return NULL;
1402 }
1403
1404 ctx = (DOSMesaContext) calloc( 1, sizeof(struct DOSmesa_context) );
1405 if (!ctx) {
1406 return NULL;
1407 }
1408
1409 ctx->gl_vis = gl_create_visual( rgb_flag,
1410 alpha_flag,
1411 db_flag,
1412 16, /* depth_size */
1413 8, /* stencil_size */
1414 16, /* accum_size */
1415 index_bits,
1416 redscale,
1417 greenscale,
1418 bluescale,
1419 alphascale,
1420 redbits, greenbits,
1421 bluebits, alphabits);
1422
1423 ctx->gl_ctx = gl_create_context( ctx->gl_vis,
1424 NULL, /* share list context */
1425 (void *) ctx
1426 );
1427
1428 ctx->gl_buffer = gl_create_framebuffer( ctx->gl_vis );
1429
1430 ctx->index = 1;
1431 ctx->red = ctx->green = ctx->blue = 255;
1432
1433 ctx->width = ctx->height = 0; /* temporary until first "make-current" */
1434
1435 return ctx;
1436 }
1437
1438 /*
1439 * Destroy the given VGA/Mesa context.
1440 */
1441 void DOSMesaDestroyContext( DOSMesaContext ctx )
1442 {
1443 if (ctx) {
1444 gl_destroy_visual( ctx->gl_vis );
1445 gl_destroy_context( ctx->gl_ctx );
1446 gl_destroy_framebuffer( ctx->gl_buffer );
1447 free( ctx );
1448 if (ctx==DOSMesa) {
1449 DOSMesa = NULL;
1450 }
1451 }
1452 }
1453
1454
1455
1456 /*
1457 * Make the specified VGA/Mesa context the current one.
1458 */
1459 void DOSMesaMakeCurrent( DOSMesaContext ctx )
1460 {
1461 DOSMesa = ctx;
1462 gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
1463 DOSmesa_setup_DD_pointers( ctx->gl_ctx );
1464
1465 if (ctx->width==0 || ctx->height==0) {
1466 /* setup initial viewport */
1467 ctx->width = vga_getxdim();
1468 ctx->height = vga_getydim();
1469 gl_Viewport( ctx->gl_ctx, 0, 0, ctx->width, ctx->height );
1470 }
1471 }
1472
1473
1474
1475 /*
1476 * Return a handle to the current VGA/Mesa context.
1477 */
1478 DOSMesaContext DOSMesaGetCurrentContext( void )
1479 {
1480 return DOSMesa;
1481 }
1482
1483
1484 /*
1485 * Swap front/back buffers for current context if double buffered.
1486 */
1487 void DOSMesaSwapBuffers( void )
1488 {
1489 #if !defined(UNIVBE)
1490 /* Assume double buffering is available if in UNIVBE,
1491 if it isn`t its taken care of anyway */
1492 // if (DOSMesa->gl_vis->DBflag)
1493 #endif
1494 {
1495 vga_flip();
1496 }
1497 }
1498
1499
1500 #else
1501
1502 /*
1503 * Need this to provide at least one external definition when DOS is
1504 * not defined on the compiler command line.
1505 */
1506
1507 int gl_DOS_dummy_function(void)
1508 {
1509 return 0;
1510 }
1511
1512 #endif /*DOS*/
1513