/********************************************************/ /* */ /* */ /* XGA Adapter Demonstration Program */ /* */ /* Compile this module, then link to CALLAFI.OBJ */ /* */ /* Version 1.01 7/30/91 */ /* */ /********************************************************/ /**************************************************/ /* */ /* Include files */ /* */ /**************************************************/ /* C library includes */ #include #include #include #include #include #include #include #include #include #include #include #include /* Adaper interface include file */ #include #undef toupper /**************************************************/ /* */ /* Global defines and variables */ /* */ /**************************************************/ #define TRUE 1 #define FALSE 0 #define byte unsigned char #define word unsigned int #define ENTER 0xD /* Colors for non standard palette */ #define GREY 2 #define WHITE 3 #define CYAN 4 #define LT_CYAN 5 #define BROWN 6 #define YELLOW 7 #define BLUE 8 #define LT_BLUE 9 #define RED 0x0a #define LT_RED 0x0b #define MAGENTA 0x0c #define LT_MAGENTA 0x0d #define GREEN 0x0e #define LT_GREEN 0x0f /* Data for small ( 640 * 480 screen resolution ) shapes */ /* color length coordinate pairs */ int /* ( bytes ) */ quad1_s[] = { CYAN, 16, 98, 141, 107, 127, 232, 343, 214, 343 }, quad2_s[] = { LT_CYAN, 16, 110, 121, 118, 106, 255, 343, 237, 343 }, quad3_s[] = { BROWN, 16, 178, 200, 295, 0, 312, 0, 187, 216 }, quad4_s[] = { YELLOW, 16, 190, 221, 318, 0, 335, 0, 199, 236 }, quad5_s[] = { BLUE, 16, 284, 96, 514, 96, 523, 112, 275, 112 }, quad6_s[] = { LT_BLUE, 16, 273, 117, 526, 117, 535, 133, 263, 133 }, quad7_s[] = { RED, 16, 408, 139, 426, 139, 542, 337, 533, 353 }, quad8_s[] = { LT_RED, 16, 385, 139, 403, 139, 530, 358, 521, 373 }, quad9_s[] = { MAGENTA, 16, 454, 266, 463, 282, 348, 479, 330, 479 }, quad10_s[] = { LT_MAGENTA, 16, 442, 246, 451, 261, 325, 479, 307, 479 }, quad11_s[] = { GREEN, 16, 116, 367, 366, 367, 357, 382, 124, 382 }, quad12_s[] = { LT_GREEN, 16, 104, 348, 376, 348, 369, 362, 113, 362 }, hex_s[] = { GREY, 24, 201, 240, 260, 139, 380, 139, 439, 240, 380, 343, 260, 343 }; int * small_shapes[] = { quad1_s, quad2_s, quad3_s, quad4_s, quad5_s, quad6_s, quad7_s, quad8_s, quad9_s, quad10_s, quad11_s, quad12_s, hex_s }; /* Data for large ( 1024 * 768 screen resolution ) shapes */ /* color length coordinate pairs */ int /* ( bytes ) */ quad1_l[] = { CYAN, 16, 159, 228, 172, 205, 371, 548, 344, 548 }; quad2_l[] = { LT_CYAN, 16, 177, 196, 191, 172, 409, 548, 381, 548 }; quad3_l[] = { BROWN, 16, 286, 320, 469, 0, 497, 0 , 300, 343 }; quad4_l[] = { YELLOW, 16, 304, 351, 506, 0, 535, 0 , 319, 375 }; quad5_l[] = { BLUE, 16, 454, 156, 824, 156, 837, 180, 439, 180 }; quad6_l[] = { LT_BLUE, 16, 434, 188, 842, 188, 856, 212, 421, 212 }; quad7_l[] = { RED, 16, 654, 220, 681, 220, 865, 540, 851, 565 }; quad8_l[] = { LT_RED, 16, 617, 220, 644, 220, 846, 573, 832, 597 }; quad9_l[] = { MAGENTA, 16, 723, 424, 738, 448, 551, 767, 527, 767 }; quad10_l[] = { LT_MAGENTA, 16, 705, 392, 719, 416, 516, 767, 488, 767 }; quad11_l[] = { GREEN, 16, 188, 588, 583, 588, 569, 612, 202, 612 }; quad12_l[] = { LT_GREEN, 16, 169, 556, 602, 556, 588, 580, 183, 580 }; hex_l[] = { GREY, 24, 323, 383, 417, 220, 607, 220, 701, 383, 607, 548, 417, 548 }; int * large_shapes[] = { quad1_l, quad2_l, quad3_l, quad4_l, quad5_l, quad6_l, quad7_l, quad8_l, quad9_l, quad10_l, quad11_l, quad12_l, hex_l }; #define NUM_SHAPES sizeof( large_shapes ) / sizeof( large_shapes[ 0 ] ) static char palette_data[][4] = { /* R B G */ 0, 0 , 0, 0, /* black 0 */ 0x24, 0x24 , 0x24, 0, /* lt black 1 */ 0x94, 0x94 , 0x94, 0, /* grey 2 */ 0xfc, 0xfc , 0xfc, 0, /* lt white 3 */ 0, 0x70 , 0x70, 0, /* cyan 4 */ 0, 0xfc , 0xfc, 0, /* lt cyan 5 */ 0x70, 0 , 0x48, 0, /* brown 6 */ 0xfc, 0x24 , 0xfc, 0, /* yellow 7 */ 0, 0x70 , 0, 0, /* blue 8 */ 0, 0xfc , 0, 0, /* lt blue 9 */ 0x70, 0 , 0, 0, /* red a */ 0xfc, 0x24 , 0x24, 0, /* lt red b */ 0x70, 0x70 , 0, 0, /* magenta c */ 0xb0, 0xfc , 0, 0, /* lt magenta d */ 0, 0 , 0x70, 0, /* green e */ 0x24, 0x24 , 0xfc, 0, /* lt green f */ 0, 0 , 0, 0, /* 2 spare to allow for shuffling */ 0, 0 , 0, 0 }; /* linked list of message file lines */ typedef struct LINE_S { struct LINE_S * next_ptr; char line[ 1 ]; } LINE_T; #define DEMO_LOGO_MSG 0 #define NO_ADAPTER_MSG 1 #define OPEN_FAILED_MSG 2 #define NO_FONT_MSG 3 char * demo_files[] = { "xgademo0.msg", "xgademo1.msg", "xgademo2.msg", "xgademo3.msg" }; static char xga_path[ 120 ]; static char file_path[ 120 ]; static int cell_height; static char far * state_buf; /**************************************************/ /* */ /* XGA interface parameter blocks */ /* */ /**************************************************/ HQDPS_DATA hqdps_data = { 14 }; /* Query state */ HSPAL_DATA * save_pal_data; /* save palette */ HOPEN_DATA hopen_data = { 3, 0, 0, 0 }; /* open adapter */ HCLOSE_DATA hclose_data = { 1, 0 }; /* close adapter */ HINIT_DATA hinit_data = { 2, 0 }; /* initialise adapter */ HQMODE_DATA hqmode_data = { 18 }; /* query mode */ HEAR_DATA hear_data = { 1, 0 }; /* end area */ HSCOL_DATA hscol_data = { 4, 0 }; /* set colour */ HINT_DATA hint_data = { 4, 0x80000000 }; /* wait for event */ HSCS_DATA hscs_data = { 4, 0 }; /* set character set */ HCHST_DATA( 128 ) hchst_data; /* write string */ HLDPAL_DATA hldpal_data = { 10, 0, 0, 0, 16, /* load palette */ ( byte far * )palette_data }; /**************************************************/ /* */ /* Function declarations */ /* */ /**************************************************/ void main( int, char ** ); static void get_xga_path( int, char ** ); static void init_adapter( void ); static void draw_shapes( void ); static void run_demo( void ); static LINE_T * get_msg( int ); static void error_exit( int, int ); struct CharSetDef * load_font( char * ); /*****************************************************************************/ /* */ /* */ /* main */ /* ÍÍÍÍ */ /* */ /*****************************************************************************/ void main( argc, argv ) int argc; char ** argv; { /*-----------------------------------------------------------*/ get_xga_path( argc, argv ); init_adapter(); draw_shapes(); run_demo(); } /************************************************************/ /* */ /* */ /* get_xga_path */ /* ÍÍÍÍÍÍÍÍÍÍÍÍ */ /* */ /* Create a directory path where message files should be. */ /* */ /************************************************************/ void get_xga_path( argc, argv ) int argc; char ** argv; { /*----------------------------------------------------------*/ /* If a parameter is passed to this program, it should */ /* represent the directory where the XGA Adapter software */ /* was installed. */ if ( argc >= 2 ) { strcpy( xga_path, argv[ 1 ] ); /* add \ to end of string */ if ( xga_path[ strlen( xga_path ) - 1 ] != '\\' ) strcat( xga_path, "\\" ); } else { strcpy( xga_path, argv[ 0 ] ); /* remove name of this program from path */ *( strrchr( xga_path, '\\' ) + 1 ) = '\0'; } } /************************************************************/ /* */ /* */ /* init_adapter */ /* ÍÍÍÍÍÍÍÍÍÍÍÍ */ /* */ /* Open and Initialise XGA adapter */ /* */ /************************************************************/ void init_adapter() { char * font_file; /*----------------------------------------------------------*/ if ( getafi() == NULL ) error_exit( NO_ADAPTER_MSG, 0 ); /* Allocate Adapter interface task dependent buffer */ HQDPS( &hqdps_data ); state_buf = ( char far * ) malloc( hqdps_data.size + 15 ); /* Allocate palette save restore buffer */ save_pal_data = malloc( hqdps_data.palbufsize + 2 ); save_pal_data->length = hqdps_data.palbufsize; /* save palette */ HSPAL( save_pal_data ); /* Attempt to open XGA adapter in mode 0 ( 1024 * 768 ). If the attached */ /* monitor does not support this mode, or there is insufficient vram, */ /* then the XGA adapter may open in another mode. */ HOPEN( &hopen_data ); if ( hopen_data.iflags ) error_exit( OPEN_FAILED_MSG, ( byte )hopen_data.iflags ); /* Make sure that task dependent buffer is situated on a */ /* 16 byte boundary. */ hinit_data.segment = FP_SEG( state_buf ) + ( ( FP_OFF( state_buf ) + 15) >> 4 ); /* initialise XGA adapter */ HINIT( &hinit_data ); /* load palette for demo */ HLDPAL( palette_data ); /* Find out mode and associated data */ HQMODE( &hqmode_data ); /* Select a font depending on character size for mode */ switch ( hqmode_data.ac_h ) { case 14: font_file = "stan0814.fnt"; break; case 15: font_file = "stan0715.fnt"; break; case 20: font_file = "stan1220.fnt"; break; case 23: font_file = "stan1223.fnt"; break; } /* read font definition from file, then load adapter character set */ if ( hscs_data.address = load_font( font_file ) ) HSCS( &hscs_data ); } /************************************************************/ /* */ /* */ /* draw_shapes */ /* ÍÍÍÍÍÍÍÍÍÍÍ */ /* */ /* Draw all shapes in shape list, and write text in */ /* center of hexagon. */ /* */ /************************************************************/ void draw_shapes() { int offset_x = 0; int offset_y = 0; int shape_id; int coord_id; int * shape_ptr; coord_pr * coord_ptr; LINE_T * line_ptr; /*----------------------------------------------------------*/ /* Draw each shape */ for ( shape_id = 0; shape_id < NUM_SHAPES; ++shape_id ) { /* if screen size > 1024 * 768, offset shapes to center of screen */ if ( hqmode_data.width >= 1024 || hqmode_data.height >= 768 ) { shape_ptr = large_shapes[ shape_id ]; hchst_data.coord.x_coord = 323; hchst_data.coord.y_coord = 220; offset_x = ( ( hqmode_data.width - 1024 ) / 2 ); offset_y = ( ( hqmode_data.height - 768 ) / 2 ); for ( coord_id = 0, coord_ptr = ( coord_pr * )&shape_ptr[ 2 ]; coord_id < shape_ptr[ 1 ] / sizeof( coord_pr ); ++coord_id ) { coord_ptr->x_coord += offset_x; coord_ptr++->y_coord += offset_y; } } else { shape_ptr = small_shapes[ shape_id ]; hchst_data.coord.x_coord = 201; hchst_data.coord.y_coord = 139; } /* set colour for shape */ hscol_data.index = shape_ptr[ 0 ]; HSCOL( &hscol_data ); /* draw shape */ HBAR(); shape_ptr++; HLINE( shape_ptr ); HEAR( &hear_data ); } /* write text in bright white */ hscol_data.index = WHITE; HSCOL( &hscol_data ); /* write text in the middle of hexagon */ if ( ( line_ptr = get_msg( DEMO_LOGO_MSG ) ) && hscs_data.address ) { while ( line_ptr != NULL ) { /* write each line to xga screen */ hchst_data.length = sizeof(coord_pr) + strlen( line_ptr->line ) - 1; memcpy( hchst_data.string, line_ptr->line, strlen( line_ptr->line ) - 1 ); HCHST( &hchst_data ); /* position next line down by character cell height */ hchst_data.coord.y_coord += cell_height; line_ptr = line_ptr->next_ptr; } } } /************************************************************/ /* */ /* */ /* run_demo */ /* ÍÍÍÍÍÍÍÍ */ /* */ /* Change colours of logo by rotating palette values */ /* once per second. */ /* */ /************************************************************/ void run_demo() { static long time_now; static long previous_time = 0; /*----------------------------------------------------------*/ while ( ( !kbhit() ) || ( getch() != ENTER ) ) { /* shuffle palette entries to rotate symbol */ memmove( palette_data[ 6 ], palette_data[ 4 ], 48 ); memmove( palette_data[ 4 ], palette_data[ 16 ], 8 ); /* Wait for frame flyback, the load shuffled palette */ HINT( &hint_data ); HLDPAL( &hldpal_data ); /* wait until time changes */ while ( previous_time == time( &time_now ) ); previous_time = time_now; } /* close adapter and restore palette */ HCLOSE( &hclose_data ); HRPAL( save_pal_data ); } /************************************************************/ /* */ /* */ /* error_exit */ /* ÍÍÍÍÍÍÍÍÍÍ */ /* */ /* On error : Close adapter, restore previous palette, */ /* then display error message on VGA screen. */ /* */ /************************************************************/ void error_exit( msg_id, error_num ) int msg_id; int error_num; { LINE_T * msg_ptr; /*----------------------------------------------------------*/ /* close adapter and restore palette */ if ( msg_id != NO_ADAPTER_MSG ) { HCLOSE( &hclose_data ); HRPAL( save_pal_data ); } msg_ptr = get_msg( msg_id ); while( msg_ptr != NULL ) { printf( "%s", msg_ptr->line ); msg_ptr = msg_ptr->next_ptr; } if ( error_num ) printf(" %2xh", error_num ); exit( 1 ); } /************************************************************/ /* */ /* */ /* get_msg */ /* ÍÍÍÍÍÍÍ */ /* */ /* open and read message file for particular language. */ /* */ /************************************************************/ LINE_T * get_msg( msg_id ) int msg_id; { char * file_name; FILE * f_id; LINE_T * msg_ptr; LINE_T * new_ptr, * line_ptr; static char line_buf[ 128 ]; /*----------------------------------------------------------*/ file_name = demo_files[ msg_id ]; msg_ptr = NULL; if ( ( f_id = fopen( file_name, "r" ) ) == NULL ) { /* Can't find file in current directory so try xga path. */ strcpy( file_path, xga_path ); strcat( file_path, file_name ); if ( ( f_id = fopen( file_path, "r" ) ) == NULL ) { /* Can't find file in xga path, so try \XGAPCDOS. */ strcpy( file_path, "\\XGAPCDOS\\" ); strcat( file_path, file_name ); f_id = fopen( file_path, "r" ); } } if ( f_id != NULL ) { /* file opened successfully so read message */ while ( fgets( line_buf, sizeof( line_buf ), f_id ) != NULL ) { new_ptr = malloc( strlen( line_buf ) + sizeof( LINE_T ) ); if ( msg_ptr == NULL ) msg_ptr = line_ptr = new_ptr; else { line_ptr->next_ptr = new_ptr; line_ptr = new_ptr; } strcpy( line_ptr->line, line_buf ); } /* indicate last line by NULL next ptr */ line_ptr->next_ptr = NULL; fclose( f_id ); } return msg_ptr; } /************************************************************/ /* */ /* */ /* Load_font */ /* ÍÍÍÍÍÍÍÍÍ */ /* */ /* Read a font file definition into memory. */ /* */ /************************************************************/ struct CharSetDef * load_font( font_file ) char * font_file; { int font_fid; static char font_path[ 120 ]; word font_file_len; struct FontFileDefn * ffd_ptr; struct CharSetDef * csd_ptr = NULL; /*----------------------------------------------------------*/ /* Open font file as binary, read only */ font_fid = open( font_file, O_RDONLY | O_BINARY ); if ( font_fid == -1 ) { /* Can't find file in current directory so try xga path. */ strcpy( font_path, xga_path ); strcat( font_path, font_file ); font_fid = open( font_path, O_RDONLY | O_BINARY ); if ( font_fid == -1 ) { /* Can't find file in xga path, so try \XGAPCDOS. */ strcpy( font_path, "\\XGAPCDOS\\" ); strcat( font_path, font_file ); font_fid = open( font_path, O_RDONLY | O_BINARY ); } } if ( font_fid != -1 ) { /* Calculate length of font file */ font_file_len = ( word ) lseek( font_fid, 0L, SEEK_END ); ffd_ptr = ( struct FontFileDefn * ) calloc( font_file_len, 1 ); /* read font file into memory */ lseek( font_fid, 0L, SEEK_SET ); read( font_fid, ( char * ) ffd_ptr, font_file_len ); /* Set up pointer to character set definition. */ csd_ptr = ( struct CharSetDef * ) ( ( char * ) ffd_ptr + ffd_ptr->page_array[ ffd_ptr->def_page ].csd_offset ); /* Set up internal csd pointers */ csd_ptr->chardef1 = ( byte far * ) ffd_ptr + ( long )csd_ptr->chardef1; csd_ptr->chardef2 = ( byte far * ) ffd_ptr + ( long )csd_ptr->chardef2; csd_ptr->chardef3 = ( byte far * ) ffd_ptr + ( long )csd_ptr->chardef3; csd_ptr->indextbl = ( word far * ) ( ( byte far * )ffd_ptr + ( long )csd_ptr->indextbl ); csd_ptr->enveltbl = ( ( byte far * )ffd_ptr + ( long )csd_ptr->enveltbl ); /* Finished with font file. */ close( font_fid ); cell_height = csd_ptr->cellheight; } return csd_ptr; }