]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/vga.c
fix bug: when opening d1 level 1 with oem data files, both d1 and d2 oem briefing...
[btb/d2x.git] / unused / vga / vga.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 #include "pa_enabl.h"   //$$POLY_ACC
15
16 #include <dos.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <malloc.h>
20 #include <stdio.h>
21 #include <conio.h>
22
23 #include "types.h"
24 #include "mem.h"
25 #include "error.h"
26 #include "mono.h"
27
28 //      New for VGA Library.
29 #include "gr.h"
30 #include "vga.h"
31 #include "palette.h"
32 #include "grdef.h"
33 #include "fxvesa.h"
34
35 #if defined(POLY_ACC)
36 #include "poly_acc.h"
37 #endif
38
39 // Global Variables -----------------------------------------------------------
40
41 ubyte *vga_screen_addr = NULL;
42
43 unsigned char * vga_video_memory = (unsigned char *)0xA0000;
44
45 char vga_pal_default[768];
46
47 int vga_installed = 0;
48
49 //extern int gr_palette_realized;
50 int vga_prevent_palette_loading = 0;
51
52 ubyte * pVideoMode =  (volatile ubyte *)0x449;
53 uword * pNumColumns = (volatile uword *)0x44a;
54 ubyte * pNumRows = (volatile ubyte *)0x484;
55 uword * pCharHeight = (volatile uword *)0x485;
56 uword * pCursorPos = (volatile uword *)0x450;
57 uword * pCursorType = (volatile uword *)0x460;
58 uword * pTextMemory = (volatile uword *)0xb8000;
59
60 ubyte saved_video_mode = 0;
61 uword saved_num_columns = 0;
62 ubyte saved_num_rows = 0;
63 uword saved_char_height = 0;
64 uword saved_cursor_pos = 0;
65 uword saved_cursor_type = 0;
66 ubyte saved_is_graphics = 0;
67 uword * saved_video_memory = NULL;
68
69 int cga_show_screen_info = 0;
70
71
72 //      VGA Functions --------------------------------------------------------------
73
74 ubyte vga_get_screen_mode( void )
75 {
76         union REGS regs;
77
78         regs.w.ax = 0x0f00;
79         int386( 0x10, &regs, &regs );
80         return regs.w.ax & 0xff;
81 }
82
83 void vga_set_cellheight( ubyte height )
84 {
85         ubyte temp;
86
87    outp( 0x3d4, 9 );
88         temp = inp( 0x3d5 );
89    temp &= 0xE0;
90         temp |= height;
91         outp( 0x3d5, temp );
92 }
93
94 void vga_set_linear()
95 {
96         outpw( 0x3c4, 0xE04 );            // enable chain4 mode
97         outpw( 0x3d4, 0x4014 );           // turn on dword mode
98         outpw( 0x3d4, 0xa317 );           // turn off byte mode
99 }
100
101 void vga_16_to_256()
102 {
103         outpw( 0x3ce, 0x4005 );         // set Shift reg to 1
104
105         inp( 0x3da );                                   // dummy input
106
107         outp( 0x3c0, 0x30 );
108         outp( 0x3c0, 0x61 );               // turns on PCS & PCC
109
110         inp( 0x3da );                                   // dummy input
111
112         outp( 0x3c0, 0x33 );
113         outp( 0x3c0, 0 );
114 }
115
116 void vga_turn_screen_off()
117 {
118         ubyte temp;
119         temp = inp( 0x3da );
120         outp( 0x3c0, 0 );
121 }
122
123 void vga_turn_screen_on()
124 {
125         ubyte temp;
126         temp = inp( 0x3da );
127         outp( 0x3c0, 0x20 );
128 }
129
130 void vga_set_misc_mode( uword mode )
131 {
132         union REGS regs;
133
134         regs.w.ax = mode;
135         int386( 0x10, &regs, &regs );
136
137 }
138
139 void gr_set_3dbios_mode( uint mode )
140 {
141         union REGS regs;
142         memset( &regs, 0, sizeof(regs) );
143         regs.w.ax = 0x4fd0;
144         regs.w.bx = 0x3d00 | (mode & 0xff);
145         int386( 0x10, &regs, &regs );
146 }
147
148
149 void vga_set_text_25()
150 {
151         union REGS regs;
152
153         regs.w.ax = 3;
154         int386( 0x10, &regs, &regs );
155
156 }
157
158 void vga_set_text_43()
159 {
160         union REGS regs;
161
162         regs.w.ax = 0x1201;
163         regs.w.bx = 0x30;
164         int386( 0x10, &regs, &regs );
165
166         regs.w.ax = 3;
167         int386( 0x10, &regs, &regs );
168
169         regs.w.ax = 0x1112;
170         regs.w.bx = 0x0;
171         int386( 0x10, &regs, &regs );
172 }
173
174 void vga_set_text_50()
175 {
176         union REGS regs;
177
178         regs.w.ax = 0x1202;
179         regs.w.bx = 0x30;
180         int386( 0x10, &regs, &regs );
181
182         regs.w.ax = 3;
183         int386( 0x10, &regs, &regs );
184
185         regs.w.ax = 0x1112;
186         regs.w.bx = 0x0;
187         int386( 0x10, &regs, &regs );
188 }
189
190 ubyte is_graphics_mode()
191 {
192         byte tmp;
193         tmp = inp( 0x3DA );             // Reset flip-flip
194         outp( 0x3C0, 0x30 );            // Select attr register 10
195         tmp = inp( 0x3C1 );     // Get graphics/text bit
196         return tmp & 1;
197 }
198
199 int vga_save_mode()
200 {
201         int i;
202
203         saved_video_mode = vga_get_screen_mode();
204         saved_num_columns = *pNumColumns;
205         saved_num_rows = *pNumRows+1;
206         saved_char_height = *pCharHeight;
207         saved_cursor_pos = *pCursorPos;
208         saved_cursor_type = *pCursorType;
209         saved_is_graphics = is_graphics_mode();
210
211         if (saved_is_graphics==0)
212         {
213                 MALLOC(saved_video_memory,uword, saved_num_columns*saved_num_rows );
214
215                 for (i=0; i < saved_num_columns*saved_num_rows; i++ )
216                         saved_video_memory[i] = pTextMemory[i];
217         }
218
219         if (cga_show_screen_info )
220         {
221                 printf( "Current video mode 0x%x:\n",  saved_video_mode );
222                 if (saved_is_graphics)
223                         printf( "Graphics mode\n" );
224                 else
225                         printf( "Text mode\n" );
226         
227                 printf( "( %d columns by %d rows)\n", saved_num_columns, saved_num_rows );
228                 printf( "Char height is %d pixel rows\n", saved_char_height );
229                 printf( "Cursor of type 0x%x is at (%d, %d)\n", saved_cursor_type, saved_cursor_pos & 0xFF, saved_cursor_pos >> 8 );
230         }
231
232         return 0;
233 }
234
235 int isvga()
236 {
237         union REGS regs;
238
239         regs.w.ax = 0x1a00;
240         int386( 0x10, &regs, &regs );
241
242         if ( regs.h.al != 0x1a ) return 0;
243         if ( (regs.h.bl==7) || (regs.h.bl==8)) return 1;
244         return 0;
245 }
246
247 void vga_set_cursor_type( uword ctype )
248 {
249         union REGS regs;
250
251         regs.w.ax = 0x0100;
252         regs.w.cx = ctype;
253         int386( 0x10, &regs, &regs );
254 }
255
256 void vga_enable_default_palette_loading()
257 {
258         union REGS regs;
259         regs.w.ax = 0x1200;
260         regs.w.bx = 0x31;
261         int386( 0x10, &regs, &regs );
262         vga_prevent_palette_loading = 0;
263 }
264
265 void vga_disable_default_palette_loading()
266 {
267         union REGS regs;
268         regs.w.ax = 0x1201;
269         regs.w.bx = 0x31;
270         int386( 0x10, &regs, &regs );
271         vga_prevent_palette_loading = 1;
272 }
273
274 void vga_set_cursor_position( uword position )
275 {
276         union REGS regs;
277
278         regs.w.ax = 0x0200;
279         regs.w.bx = 0;
280         regs.w.dx = position;
281         int386( 0x10, &regs, &regs );
282
283 }
284
285 void vga_restore_mode()
286 {
287         int i;
288
289         if ( saved_video_mode == 3 )
290         {
291                 switch( saved_num_rows )
292                 {
293                         case 43:        vga_set_text_43(); break;
294                         case 50:        vga_set_text_50(); break;
295                         default:        vga_set_text_25(); break;
296                 }
297         } else {
298                 vga_set_misc_mode(saved_video_mode);    
299         }
300
301         if (saved_is_graphics==0)
302         {
303                 for (i=0; i < saved_num_columns*saved_num_rows; i++ )
304                         pTextMemory[i]=saved_video_memory[i];
305                 vga_set_cursor_type( saved_cursor_type );
306                 vga_set_cursor_position( saved_cursor_pos );
307         }
308 }
309
310 short vga_close()
311 {
312 #if defined(POLY_ACC)
313         pa_reset();
314 #endif
315
316         if (vga_installed==1)
317         {
318                 vga_installed = 0;
319                 vga_restore_mode();
320                 if( saved_video_memory )
321                         free(saved_video_memory);
322         }
323
324         return 0;
325 }
326
327 int LinearSVGABuffer=0;
328
329 int vga_vesa_setmode( short mode )
330 {
331         int retcode;
332
333 #if defined(POLY_ACC)
334         Int3();
335     mprintf((0, "vga_vesa_setmode %d\n"));
336     return 0;
337 #endif
338
339         if (VesaInit (mode))  // if there is an error with linear support
340          {
341                 LinearSVGABuffer=1;
342                 return(0);
343          }
344         
345    LinearSVGABuffer=0;
346         retcode=gr_vesa_checkmode( mode );              // do the old banking way
347         if ( retcode ) return retcode;
348         return gr_vesa_setmodea( mode );
349 }
350
351 int VGA_current_mode = SM_ORIGINAL;
352 extern int VesaGetRowSize (int);
353
354 short vga_set_mode(short mode)
355 {
356         int retcode;
357         unsigned int w,h,t,data, r;
358
359 #if defined(POLY_ACC)
360 if(mode != SM_640x480x15xPA)
361 {
362     Int3();
363     mprintf((0, "vga_set_mode(%d)\n", mode));
364     return 0;
365 }
366 #endif
367
368         LinearSVGABuffer=0; 
369            
370         if (!vga_installed)
371                 return 1;
372    
373   
374         switch(mode)
375         {
376         case SM_ORIGINAL:
377                 return 0;
378
379         case SM_320x200C:
380                 if (!isvga()) return 1;
381                 vga_set_misc_mode(0x13);        
382                 w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000;
383                 break;
384         
385         case SM_640x400V:
386                 retcode = vga_vesa_setmode( 0x100 ); 
387                 //gr_enable_default_palette_loading();
388                 if (retcode !=0 ) return retcode;
389                 w = 640; r = 640; h = 400; t=BM_SVGA; data = 0;
390                 break;
391
392         case SM_640x480V:
393                 retcode = vga_vesa_setmode( 0x101 ); 
394                 //gr_enable_default_palette_loading();
395                 if (retcode !=0 ) return retcode;
396                 w = 640; r = 640; h = 480; t=BM_SVGA; data = 0;
397                 break;
398
399         case SM_800x600V:
400                 retcode = vga_vesa_setmode( 0x103 ); 
401                 //gr_enable_default_palette_loading();
402                 if (retcode !=0 ) return retcode;
403                 w = 800; h = 600; t=BM_SVGA; data = 0;
404       r=VesaGetRowSize (0x103);
405                 break;
406
407         case SM_1024x768V:
408                 retcode = vga_vesa_setmode( 0x105 ); 
409                 //gr_enable_default_palette_loading();
410                 if (retcode !=0 ) return retcode;
411                 w = 1024; r = 1024; h = 768; t=BM_SVGA; data = 0;
412       r=VesaGetRowSize (0x105);
413                 break;
414
415         case SM_1280x1024V:
416                 retcode = vga_vesa_setmode( 0x107 ); 
417                 //gr_enable_default_palette_loading();
418                 if (retcode !=0 ) return retcode;
419                 w = 1280; r = 1280; h = 1024; t=BM_SVGA; data = 0;
420       r=VesaGetRowSize (0x107);
421                 break;
422
423         case SM_640x480V15:
424                 retcode = vga_vesa_setmode( 0x110 ); 
425                 //gr_enable_default_palette_loading();
426                 if (retcode !=0 ) return retcode;
427                 w = 640; r = 640*2; h=480; t=BM_SVGA15; data = 0;
428                 break;
429
430         case SM_800x600V15:
431                 retcode = vga_vesa_setmode( 0x113 ); 
432                 //gr_enable_default_palette_loading();
433                 if (retcode !=0 ) return retcode;
434                 w = 800; r = 800*2; h=600; t=BM_SVGA15; data = 0;
435                 break;
436
437         //super-special code for 3dmax high-res mode
438         case SM_320x400_3DMAX:                  // 3dmax 320x400
439                 if (!isvga()) return 1;
440                 gr_set_3dbios_mode(0x31);
441                 //w = 320; r = 320/4; h = 400; t=BM_MODEX; data = 0;
442                 w = 320; r = 320; h = 400; t=BM_SVGA; data = 0;
443                 break;
444
445         //@@case 19:
446         //@@    if (!isvga()) return 1;
447         //@@    vga_set_misc_mode(0x13);        
448         //@@    vga_set_cellheight( 3 );
449         //@@    w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000;
450         //@@    break;
451         //@@
452         //@@case 20:
453         //@@    retcode = vga_vesa_setmode( 0x102 ); 
454         //@@    //gr_enable_default_palette_loading();
455         //@@    if (retcode !=0 ) return retcode;
456         //@@    vga_16_to_256();
457         //@@    vga_set_linear();
458         //@@    //gr_set_cellheight( 1 );
459         //@@    gr_vesa_setlogical( 400 );
460         //@@    w = 400; r = 400; h = 600; t=BM_SVGA; data = 0;
461         //@@    break;
462         //@@
463         //@@case 21:
464         //@@    if (!isvga()) return 1;
465         //@@    vga_set_misc_mode(0xd); 
466         //@@    vga_16_to_256();
467         //@@    vga_set_linear();
468         //@@    //gr_set_cellheight( 3 );
469         //@@    w = 160; r = 160; h = 200; t=BM_LINEAR; data = 0xA0000;
470         //@@    break;
471
472         case SM_320x200U:
473         case SM_320x240U:
474         case SM_360x200U:
475         case SM_360x240U:
476         case SM_376x282U:
477         case SM_320x400U:
478         case SM_320x480U:
479         case SM_360x400U:
480         case SM_360x480U:
481         case SM_360x360U:
482         case SM_376x308U:
483         case SM_376x564U:               //mode X modes
484
485                 if (!isvga()) return 1;
486                 w = gr_modex_setmode( mode );
487                 //gr_enable_default_palette_loading();
488                 h = w & 0xffff; w = w >> 16; r = w / 4;t = BM_MODEX; data = 0;
489                 break;
490
491 #if defined(POLY_ACC)
492         case SM_640x480x15xPA:
493                 pa_set_mode(mode);
494                 w = 640; r = 640*2; h=480; t=BM_LINEAR15; data = 0; //$$ data should be what?
495            #ifdef PA_3DFX_VOODOO
496                   r=2048;
497                 #endif
498                 break;
499 #endif
500
501         default:                        //unknown mode!!!  Very bad!!
502                 Error("Unknown mode %d in vga_set_mode()",mode);
503         }
504
505 //      if (vga_palette_realized  && (vga_prevent_palette_loading==0))
506 //              gr_pal_setblock( 0, 256, gr_palette);
507
508 //      return 0;
509
510         VGA_current_mode = mode;
511 #if defined(POLY_ACC)
512     vga_screen_addr = pa_get_buffer_address(0);
513 #else
514         if (LinearSVGABuffer)
515                 {
516                         mprintf ((0,"GREEEEAT!\n"));
517                         t=BM_LINEAR;
518                         vga_screen_addr=(ubyte *)VesaGetPtr();
519                 }
520         else
521                 vga_screen_addr=(ubyte *)0xa0000;
522 #endif
523
524         gr_palette_clear();
525         return gr_init_screen( t,w,h,0,0,r,vga_screen_addr);
526 }
527
528
529 short vga_init()
530 {
531         // Only do this function once!
532         if (vga_installed==1)
533                 return 1;
534
535 #if !defined(POLY_ACC)
536         if (gr_init_A0000())
537                 return 10;
538 #endif
539
540         vga_screen_addr = (ubyte *)0xa0000;             //address in memory of screen
541
542         // Save the current text screen mode
543         if (vga_save_mode()==1)
544                 return 1;
545
546 /*      if (get_selector( &vga_fade_table, 256*GR_FADE_LEVELS, &vga_fade_table_selector ))
547                 Error( "Error allocating fade table selector!" );
548
549         if (get_selector( &vga_palette, 256*3, &vga_palette_selector ))
550                 Error( "Error allocating palette selector!" );
551
552         if (get_selector( &vga_inverse_table, 32*32*32, &vga_inverse_table_selector ))
553                 Error( "Error allocating inverse table selector!" );
554 */
555
556         // Set flags indicating that this is installed.
557 //      gr_palette_clear();
558         vga_installed = 1;
559         atexit(vga_close);
560
561 #if defined(POLY_ACC)
562     pa_init();
563 #endif
564         return 0;
565 }
566
567 short vga_mode13_checkmode()
568 {
569         if (isvga()) 
570                 return 0;
571         else
572                 return 1;
573 }
574
575 //  0=Mode set OK
576 //  1=No VGA adapter installed
577 //  2=Program doesn't support this VESA granularity
578 //  3=Monitor doesn't support that VESA mode.:
579 //  4=Video card doesn't support that VESA mode.
580 //  5=No VESA driver found.
581 //  6=Bad Status after VESA call/
582 //  7=Not enough DOS memory to call VESA functions.
583 //  8=Error using DPMI.
584 //  9=Error setting logical line width.
585 // 10=Error allocating selector for A0000h
586 // 11=Not a valid mode support by gr.lib
587
588 short vga_check_mode(short mode)
589 {
590 #if defined(POLY_ACC)
591 if(mode != SM_640x480x15xPA)
592     Int3();
593 #endif
594
595         switch(mode)
596         {
597         case 19:
598         case SM_320x200C:
599         case SM_320x200U:
600         case SM_320x240U:
601         case SM_360x200U:
602         case SM_360x240U:
603         case SM_376x282U:
604         case SM_320x400U:
605         case SM_320x480U:
606         case SM_360x400U:
607         case SM_360x480U:
608         case SM_360x360U:
609         case SM_376x308U:
610         case SM_376x564U:               return vga_mode13_checkmode();
611         case SM_640x400V:               return gr_vesa_checkmode( 0x100 ); 
612         case SM_640x480V:       return gr_vesa_checkmode( 0x101 ); 
613         case SM_800x600V:       return gr_vesa_checkmode( 0x103 ); 
614         case SM_1024x768V:      return gr_vesa_checkmode( 0x105 ); 
615         case SM_640x480V15:     return gr_vesa_checkmode( 0x110 ); 
616         case SM_800x600V15:     return gr_vesa_checkmode( 0x113 ); 
617 #if defined(POLY_ACC)
618         case SM_640x480x15xPA: return pa_detect(mode);
619 #endif
620         }
621         return 11;
622 }