⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vglfli.c

📁 在DOS13号中断下开发图形显示程序的例程
💻 C
字号:
/*****************************************************************************
 VGLFLI.C

 Simple (and slow) C routine to play a 320x200 .FLI file.  You specify the
 filename of the flick to be played, a pointer to a screen buffer, and a
 speed (in clock ticks).  If the screen buffer you specify is VIDMEM, you may
 get some shearing but it'll probably be faster.  Anything other than VIDMEM
 means vglUpdateW is called to update video memory with each frame.  No
 flicker, but slower (usually).

 This is an example of lousy coding.  It is slow.  I wrote it a long time ago
 and just found it again the other day.  I'm throwing it into the soup
 because it may be of some use to someone.

 This will play the .FLI in a loop until any key is pressed.

 Mark
 morley@camosun.bc.ca
*****************************************************************************/

#include <stdio.h>
#include <dos.h>
#include <time.h>

#define BUFSIZE  8192                   /* Maximum buffer to try and        */
                                        /* allocate for file reading.       */

static char far  Pal[768];              /* Our palette buffer               */
static char*     VBuf;                  /* Will point to an I/O buffer      */

#define FLI_COLOR       11              /* Types of FLI chunks              */
#define FLI_LC          12
#define FLI_BLACK       13
#define FLI_BRUN        15
#define FLI_COPY        16

typedef struct                          /* The structure of a .FLI header   */
{
   unsigned long size;
   unsigned int  magic;
   unsigned int  frames;
   unsigned int  width;
   unsigned int  height;
   unsigned int  bits;
   unsigned int  flags;
   unsigned int  speed;
   unsigned long next;
   unsigned long frit;
   unsigned char expand[102];
} FLIHDR;

typedef struct                          /* The structure of a frame header  */
{
   unsigned long size;
   unsigned int  magic;
   unsigned int  chunks;
   unsigned char expand[8];
} FRAMEHDR;

/*****************************************************************************
 A single routine to open, play, and close a .FLI file.  Slow and simple.
*****************************************************************************/
vglPlayFLI( char* file, char far* video, int speed )
{
   register unsigned x;
   register unsigned y;
   char              buf[81];
   FILE*             fp;
   FLIHDR            hdr;
   FRAMEHDR          frm;
   unsigned long     size;
   unsigned int      type;
   unsigned int      pakets;
   unsigned char     skip;
   unsigned int      cnt;
   unsigned int      lines;
   unsigned int      change;
   signed char       s;
   unsigned char     v;
   unsigned int      i;
   unsigned int      c;
   unsigned int      f;
   unsigned long     vc;
   long              RewindPos;
   clock_t           tiks;
   char far*         vid;

   /* Open up the file */
   fp = fopen( file, "rb" );
   if( !fp )
      return 0;

   /* Try and allocate a buffer to help speed up the file I/O */
   if( (VBuf = (char*) malloc( BUFSIZE )) == 0 )
      VBuf = (char*) malloc( BUFSIZE / 2 );
   if( VBuf )
      setvbuf( fp, VBuf, _IOFBF, BUFSIZE );

   /* Read the header */
   fread( &hdr, sizeof(FLIHDR), 1, fp );
   f = 0;

   while( 1 )
   {
      /* For each frame in the flick we... */
      for( ; f <= hdr.frames; f++ )
      {
         tiks = clock();

         /* Read in a frame header */
         fread( &frm, sizeof(FRAMEHDR), 1, fp );

         /* For each chunk in a frame we... */
         if( frm.size != 0L )  for( i = 0; i < frm.chunks; i++ )
         {
            fread( &size, 1, sizeof(long), fp );
            type = getw( fp );

            /* Process each chunk */
            switch( type )
            {
               case FLI_LC         : lines = getw( fp );
                                     change = getw( fp );
                                     vc = 0;
                                     y = lines;
                                     i = y * 320;
                                     for( c = 0; c < change; c++ )
                                     {
                                        vid = video + i;
                                        i += 320;
                                        pakets = getc( fp );
                                        vc++;
                                        while( pakets-- )
                                        {
                                           skip = getc( fp );
                                           vc++;
                                           vid += skip;
                                           s = getc( fp );
                                           vc++;
                                           if( s > 0 )
                                           {
                                              vc += s;
                                              while( s-- )
                                                 *vid++ = getc( fp );
                                           }
                                           else
                                           {
                                              s = -s;
                                              v = getc( fp );
                                              vc++;
                                              while( s-- )
                                                 *vid++ = v;
                                           }
                                        }
                                        y++;
                                     }
                                     if( vc & 1 )
                                        getc( fp );
                                     break;
               case FLI_BRUN       : vc = 0;
                                     vid = video;
                                     for( y = 0; y < 200; y++ )
                                     {
                                        pakets = getc( fp );
                                        while( pakets-- )
                                        {
                                           vc++;
                                           s = getc( fp );
                                           if( s < 0 )
                                           {
                                              s = -s;
                                              vc += s;
                                              while( s-- )
                                                 *vid++ = getc( fp );
                                           }
                                           else
                                           {
                                              v = getc( fp );
                                              vc++;
                                              while( s-- )
                                                 *vid++ = v;
                                           }
                                        }
                                     }
                                     if( vc & 1 )
                                        getc( fp );
                                     break;
               case FLI_COLOR      : vc = 2;
                                     pakets = getw( fp );
                                     c = 0;
                                     while( pakets-- )
                                     {
                                        skip = getc( fp );
                                        vc++;
                                        c += skip * 3;
                                        cnt = 0;
                                        cnt = getc( fp );
                                        vc++;
                                        if( cnt == 0 )
                                           cnt = 256;
                                        while( cnt-- )
                                        {
                                           Pal[c++] = getc( fp );
                                           Pal[c++] = getc( fp );
                                           Pal[c++] = getc( fp );
                                           vc += 3;
                                        }
                                     }
                                     vglSetPal( Pal );
                                     if( vc & 1 )
                                        getc( fp );
                                     break;
               case FLI_COPY       : vid = video;
                                     for( y = 0; y < 200; y++ )
                                        for( x = 0; x < 320; x++ )
                                           *vid++ = getc( fp );
                                     break;
               case FLI_BLACK      : vglClear( 0 );
                                     break;

               /* A bad or unknown chuck type (a .FLC perhaps?) */
               default             : fclose( fp );
                                     if( VBuf )
                                        free( VBuf );
                                     return 1;
            }
         }

         /* If we're writing to a virtual screen, update the real one! */
         if( video != (char far*) 0xa0000000L )
            vglUpdateW();

         /* Check for a keypress */
         if( kbhit() )
         {
            if( getch() == 0 )
               getch();
            fclose( fp );
            if( VBuf )
               free( VBuf );
            return 1;
         }

         /* Pause the specified number of clock ticks */
         while( clock() - tiks < speed );

         if( f == 0 )
            RewindPos = ftell( fp );
      }
      fseek( fp, RewindPos, 0 );
      f = 1;
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -