2 * $Source: /cvs/cvsroot/d2x/arch/dos/gr.c,v $
5 * $Date: 2001-10-25 08:25:33 $
7 * Graphics functions for DOS.
9 * $Log: not supported by cvs2svn $
10 * Revision 1.2 2001/01/29 13:47:51 bradleyb
11 * Fixed build, some minor cleanups.
35 #include <sys/nearptr.h>
38 static int last_r=0, last_g=0, last_b=0;
41 unsigned char * gr_video_memory = (unsigned char *)0xa0000;
43 char gr_pal_default[768];
47 volatile ubyte * pVideoMode = (volatile ubyte *)0x449;
48 volatile ushort * pNumColumns = (volatile ushort *)0x44a;
49 volatile ubyte * pNumRows = (volatile ubyte *)0x484;
50 volatile ushort * pCharHeight = (volatile ushort *)0x485;
51 volatile ushort * pCursorPos = (volatile ushort *)0x450;
52 volatile ushort * pCursorType = (volatile ushort *)0x460;
53 volatile ushort * pTextMemory = (volatile ushort *)0xb8000;
55 typedef struct screen_save {
61 ubyte cursor_x, cursor_y;
62 ubyte cursor_sline, cursor_eline;
63 ushort * video_memory;
66 screen_save gr_saved_screen;
68 int gr_show_screen_info = 0;
69 extern int VGA_current_mode;
71 void gr_set_cellheight( ubyte height )
84 outpw( 0x3c4, 0xE04 ); // enable chain4 mode
85 outpw( 0x3d4, 0x4014 ); // turn on dword mode
86 outpw( 0x3d4, 0xa317 ); // turn off byte mode
91 outpw( 0x3ce, 0x4005 ); // set Shift reg to 1
93 inp( 0x3da ); // dummy input
96 outp( 0x3c0, 0x61 ); // turns on PCS & PCC
98 inp( 0x3da ); // dummy input
104 void gr_turn_screen_off()
111 void gr_turn_screen_on()
118 void gr_set_misc_mode( uint mode )
122 memset( ®s, 0, sizeof(regs) );
124 int386( 0x10, ®s, ®s );
128 void gr_set_3dbios_mode( uint mode )
131 memset( ®s, 0, sizeof(regs) );
133 regs.w.bx = 0x3d00 | (mode & 0xff);
134 int386( 0x10, ®s, ®s );
139 void gr_set_text_25()
144 int386( 0x10, ®s, ®s );
148 void gr_set_text_43()
154 int386( 0x10, ®s, ®s );
157 int386( 0x10, ®s, ®s );
161 int386( 0x10, ®s, ®s );
164 void gr_set_text_50()
170 int386( 0x10, ®s, ®s );
173 int386( 0x10, ®s, ®s );
177 int386( 0x10, ®s, ®s );
180 ubyte is_graphics_mode()
183 tmp = inp( 0x3DA ); // Reset flip-flip
184 outp( 0x3C0, 0x30 ); // Select attr register 10
185 tmp = inp( 0x3C1 ); // Get graphics/text bit
189 void gr_setcursor(ubyte x, ubyte y, ubyte sline, ubyte eline)
193 memset( ®s, 0, sizeof(regs) );
198 int386( 0x10, ®s, ®s );
200 memset( ®s, 0, sizeof(regs) );
202 regs.h.ch = sline & 0xf;
203 regs.h.cl = eline & 0xf;
204 int386( 0x10, ®s, ®s );
207 void gr_getcursor(ubyte *x, ubyte *y, ubyte * sline, ubyte * eline)
211 memset( ®s, 0, sizeof(regs) );
214 int386( 0x10, ®s, ®s );
226 gr_saved_screen.is_graphics = is_graphics_mode();
227 gr_saved_screen.video_mode = *pVideoMode;
229 if (!gr_saved_screen.is_graphics) {
230 gr_saved_screen.width = *pNumColumns;
231 gr_saved_screen.height = *pNumRows+1;
232 gr_saved_screen.char_height = *pCharHeight;
233 gr_getcursor(&gr_saved_screen.cursor_x, &gr_saved_screen.cursor_y, &gr_saved_screen.cursor_sline, &gr_saved_screen.cursor_eline );
234 MALLOC(gr_saved_screen.video_memory,ushort, gr_saved_screen.width*gr_saved_screen.height );
235 for (i=0; i < gr_saved_screen.width*gr_saved_screen.height; i++ )
236 gr_saved_screen.video_memory[i] = pTextMemory[i];
239 if (gr_show_screen_info ) {
240 printf( "Current video mode 0x%x:\n", gr_saved_screen.video_mode );
241 if (gr_saved_screen.is_graphics)
242 printf( "Graphics mode\n" );
244 printf( "Text mode\n" );
245 printf( "( %d columns by %d rows)\n", gr_saved_screen.width, gr_saved_screen.height );
246 printf( "Char height is %d pixel rows\n", gr_saved_screen.char_height );
247 printf( "Cursor of type 0x%x,0x%x is at (%d, %d)\n", gr_saved_screen.cursor_sline, gr_saved_screen.cursor_eline,gr_saved_screen.cursor_x, gr_saved_screen.cursor_y );
258 memset( ®s, 0, sizeof(regs) );
260 int386( 0x10, ®s, ®s );
262 if ( regs.h.al == 0x1a )
268 void gr_restore_mode()
275 gr_palette_fade_out( gr_palette, 32, 0 );
276 gr_palette_set_gamma(0);
277 if ( gr_saved_screen.video_mode == 3 ) {
278 switch( gr_saved_screen.height ) {
279 case 43: gr_set_text_43(); break;
280 case 50: gr_set_text_50(); break;
281 default: gr_set_text_25(); break;
284 gr_set_misc_mode(gr_saved_screen.video_mode);
286 if (gr_saved_screen.is_graphics==0) {
289 gr_palette_read( gr_pal_default );
291 for (i=0; i < gr_saved_screen.width*gr_saved_screen.height; i++ )
292 pTextMemory[i]=gr_saved_screen.video_memory[i];
293 gr_setcursor( gr_saved_screen.cursor_x, gr_saved_screen.cursor_y, gr_saved_screen.cursor_sline, gr_saved_screen.cursor_eline );
294 gr_palette_faded_out = 1;
295 gr_palette_fade_in( gr_pal_default, 32, 0 );
308 if( gr_saved_screen.video_memory ) {
309 free(gr_saved_screen.video_memory);
310 gr_saved_screen.video_memory = NULL;
316 int gr_vesa_setmode( int mode )
320 retcode=gr_vesa_checkmode( mode );
321 if ( retcode ) return retcode;
323 return gr_vesa_setmodea( mode );
328 int gr_set_mode(u_int32_t mode)
331 unsigned int w,h,t,data, r;
333 //JOHNgr_disable_default_palette_loading();
341 case SM(320,200)://0:
342 if (!isvga()) return 1;
343 gr_set_misc_mode(0x13);
344 w = 320; r = 320; h = 200; t=BM_LINEAR; data = (int)gr_video_memory;
346 case SM(640,400)://SM_640x400V:
347 retcode = gr_vesa_setmode( 0x100 );
348 if (retcode !=0 ) return retcode;
349 w = 640; r = 640; h = 400; t=BM_SVGA; data = 0;
351 case SM(640,480)://SM_640x480V:
352 retcode = gr_vesa_setmode( 0x101 );
353 if (retcode !=0 ) return retcode;
354 w = 640; r = 640; h = 480; t=BM_SVGA; data = 0;
356 case SM(800,600)://SM_800x600V:
357 retcode = gr_vesa_setmode( 0x103 );
358 if (retcode !=0 ) return retcode;
359 w = 800; r = 800; h = 600; t=BM_SVGA; data = 0;
361 case SM(1024,768)://SM_1024x768V:
362 retcode = gr_vesa_setmode( 0x105 );
363 if (retcode !=0 ) return retcode;
364 w = 1024; r = 1024; h = 768; t=BM_SVGA; data = 0;
366 /* case SM_640x480V15:
367 retcode = gr_vesa_setmode( 0x110 );
368 if (retcode !=0 ) return retcode;
369 w = 640; r = 640*2; h=480; t=BM_SVGA15; data = 0;
372 retcode = gr_vesa_setmode( 0x113 );
373 if (retcode !=0 ) return retcode;
374 w = 800; r = 800*2; h=600; t=BM_SVGA15; data = 0;
378 if (!isvga()) return 1;
379 gr_set_misc_mode(0x13);
386 gr_set_cellheight( 3 );
388 w = 320; r = 320; h = 100; t=BM_LINEAR; data = (int)gr_video_memory;
391 retcode = gr_vesa_setmode( 0x102 );
392 //gr_enable_default_palette_loading();
393 if (retcode !=0 ) return retcode;
396 //gr_set_cellheight( 1 );
397 gr_vesa_setlogical( 400 );
398 w = 400; r = 400; h = 600; t=BM_SVGA; data = 0;
401 if (!isvga()) return 1;
402 gr_set_misc_mode(0xd);
405 gr_set_cellheight( 3 );
406 w = 160; r = 160; h = 100; t=BM_LINEAR; data = (int)gr_video_memory;
408 case //22: // 3dmax 320x400
409 if (!isvga()) return 1;
410 gr_set_3dbios_mode(0x31);
411 //w = 320; r = 320/4; h = 400; t=BM_MODEX; data = 0;
412 w = 320; r = 320; h = 400; t=BM_SVGA; data = 0;
415 if (!isvga()) return 1;
416 if (mode==SM(320,240))
417 w = gr_modex_setmode( 2 );
418 else if (mode==SM(320,400))
419 w = gr_modex_setmode( 6 );
421 Error("unhandled vid mode\n");
422 //gr_enable_default_palette_loading();
423 h = w & 0xffff; w = w >> 16; r = w / 4;t = BM_MODEX; data = 0;
428 memset( grd_curscreen, 0, sizeof(grs_screen));
429 grd_curscreen->sc_mode = mode;
430 grd_curscreen->sc_w = w;
431 grd_curscreen->sc_h = h;
432 grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4);
433 grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0;
434 grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0;
435 grd_curscreen->sc_canvas.cv_bitmap.bm_w = w;
436 grd_curscreen->sc_canvas.cv_bitmap.bm_h = h;
437 grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = r;
438 grd_curscreen->sc_canvas.cv_bitmap.bm_type = t;
439 grd_curscreen->sc_canvas.cv_bitmap.bm_data = (unsigned char *)data;
440 VGA_current_mode = mode;
441 gr_set_current_canvas(NULL);
443 //gr_enable_default_palette_loading();
444 // gamefont_choose_game_font(w,h);
453 int mode = SM(320,200);
455 // Only do this function once!
460 if (!__djgpp_nearptr_enable()) {
461 printf("nearptr enable=%x\n", __dpmi_error);
465 gr_video_memory = (unsigned char *)(__djgpp_conventional_base + 0xa0000);
467 gr_video_memory=(unsigned char *)-1;
469 pVideoMode = (volatile ubyte *)(__djgpp_conventional_base+0x449);
470 pNumColumns = (volatile ushort *)(__djgpp_conventional_base+0x44a);
471 pNumRows = (volatile ubyte *)(__djgpp_conventional_base+0x484);
472 pCharHeight = (volatile ushort *)(__djgpp_conventional_base+0x485);
473 pCursorPos = (volatile ushort *)(__djgpp_conventional_base+0x450);
474 pCursorType = (volatile ushort *)(__djgpp_conventional_base+0x460);
475 pTextMemory = (volatile ushort *)(__djgpp_conventional_base+0xb8000);
482 // Save the current text screen mode
483 if (gr_save_mode()==1)
487 // Save the current palette, and fade it out to black.
488 gr_palette_read( gr_pal_default );
489 gr_palette_faded_out = 0;
490 org_gamma = gr_palette_get_gamma();
491 gr_palette_set_gamma( 0 );
492 gr_palette_fade_out( gr_pal_default, 32, 0 );
494 gr_palette_set_gamma( org_gamma );
501 __djgpp_nearptr_disable();
505 MALLOC( grd_curscreen,grs_screen,1 );
506 memset( grd_curscreen, 0, sizeof(grs_screen));
509 if ((retcode=gr_set_mode(mode)))
514 //JOHNgr_disable_default_palette_loading();
516 // Set all the screen, canvas, and bitmap variables that
517 // aren't set by the gr_set_mode call:
518 grd_curscreen->sc_canvas.cv_color = 0;
519 grd_curscreen->sc_canvas.cv_drawmode = 0;
520 grd_curscreen->sc_canvas.cv_font = NULL;
521 grd_curscreen->sc_canvas.cv_font_fg_color = 0;
522 grd_curscreen->sc_canvas.cv_font_bg_color = 0;
523 gr_set_current_canvas( &grd_curscreen->sc_canvas );
526 if (!dpmi_allocate_selector( &gr_fade_table, 256*GR_FADE_LEVELS, &gr_fade_table_selector ))
527 Error( "Error allocating fade table selector!" );
529 if (!dpmi_allocate_selector( &gr_palette, 256*3, &gr_palette_selector ))
530 Error( "Error allocating palette selector!" );
533 // if (!dpmi_allocate_selector( &gr_inverse_table, 32*32*32, &gr_inverse_table_selector ))
534 // Error( "Error allocating inverse table selector!" );
537 // Set flags indicating that this is installed.
541 atexit((void (*)) gr_close);
548 int gr_mode13_checkmode()
557 // 1=No VGA adapter installed
558 // 2=Program doesn't support this VESA granularity
559 // 3=Monitor doesn't support that VESA mode.:
560 // 4=Video card doesn't support that VESA mode.
561 // 5=No VESA driver found.
562 // 6=Bad Status after VESA call/
563 // 7=Not enough DOS memory to call VESA functions.
564 // 8=Error using DPMI.
565 // 9=Error setting logical line width.
566 // 10=Error allocating selector for A0000h
567 // 11=Not a valid mode support by gr.lib
569 int gr_check_mode(u_int32_t mode)
573 case SM(320,100)://19:
585 case SM(376,564): return gr_mode13_checkmode();
586 case SM(640,400): return gr_vesa_checkmode( 0x100 );
587 case SM(640,480): return gr_vesa_checkmode( 0x101 );
588 case SM(800,600): return gr_vesa_checkmode( 0x103 );
589 case SM(1024,768): return gr_vesa_setmode( 0x105 );
590 // case SM_640x480V15: return gr_vesa_setmode( 0x110 );
591 // case SM_800x600V15: return gr_vesa_setmode( 0x113 );
596 /* Palette Stuff Starts Here... */
598 void gr_palette_step_up( int r, int g, int b )
604 if (gr_palette_faded_out) return;
606 if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
608 last_r = r; last_g = g; last_b = b;
614 for (i=0; i<256; i++ ) {
615 temp = (int)(*p++) + r + gr_palette_gamma;
617 else if (temp>63) temp=63;
619 temp = (int)(*p++) + g + gr_palette_gamma;
621 else if (temp>63) temp=63;
623 temp = (int)(*p++) + b + gr_palette_gamma;
625 else if (temp>63) temp=63;
631 void gr_palette_clear()
636 for (i=0; i<768; i++ ) {
639 gr_palette_faded_out = 1;
642 void gr_palette_load( ubyte * pal )
648 for (i=0; i<768; i++ ) {
649 c = pal[i] + gr_palette_gamma;
650 if ( c > 63 ) c = 63;
652 gr_current_pal[i] = pal[i];
654 gr_palette_faded_out = 0;
656 init_computed_colors();
660 int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys )
664 fix fade_palette[768];
665 fix fade_palette_delta[768];
667 if (gr_palette_faded_out) return 0;
670 pal = gr_current_pal;
672 for (i=0; i<768; i++ ) {
673 fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
674 fade_palette_delta[i] = fade_palette[i] / nsteps;
677 for (j=0; j<nsteps; j++ ) {
681 for (i=0; i<768; i++ ) {
682 fade_palette[i] -= fade_palette_delta[i];
683 if (fade_palette[i] < 0 )
685 c = f2i(fade_palette[i]);
686 if ( c > 63 ) c = 63;
690 gr_palette_faded_out = 1;
694 int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)
698 fix fade_palette[768];
699 fix fade_palette_delta[768];
702 if (!gr_palette_faded_out) return 0;
704 for (i=0; i<768; i++ ) {
705 gr_current_pal[i] = pal[i];
707 fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps;
710 for (j=0; j<nsteps; j++ ) {
714 for (i=0; i<768; i++ ) {
715 fade_palette[i] += fade_palette_delta[i];
716 if (fade_palette[i] > i2f(pal[i]+gr_palette_gamma) )
717 fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
718 c = f2i(fade_palette[i]);
719 if ( c > 63 ) c = 63;
723 gr_palette_faded_out = 0;
727 void gr_palette_read(ubyte * palette)
732 for (i=0; i<768; i++ ) {
733 *palette++ = inp( 0x3c9 );