Metropoli BBS
VIEWER: xgademo.c MODE: TEXT (CP437)
    /********************************************************/
    /*                                                      */
    /*                                                      */
    /*            XGA Adapter Demonstration Program         */
    /*                                                      */
    /*     Compile this module, then link to CALLAFI.OBJ    */
    /*                                                      */
    /*               Version 1.01  7/30/91                  */
    /*                                                      */
    /********************************************************/



/**************************************************/
/*                                                */
/*          Include files                         */
/*                                                */
/**************************************************/

   /* C library includes                          */

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
#include <stdlib.h>
#include <process.h>



   /* Adaper interface include file               */

#include <ibmafi.h>

#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;
}
[ RETURN TO DIRECTORY ]