home *** CD-ROM | disk | FTP | other *** search
/ Game Developers Magazine 3 / GDM003.ZIP / PCX-SHOW.C < prev    next >
C/C++ Source or Header  |  1994-02-25  |  5KB  |  247 lines

  1. // PCX-SHOW.C - Program to demonstrate viewing of 256 colour VGA PCX files
  2.  
  3. // Written by Phil Inch for Game Developers Magazine (issue 3).
  4. // Contributed to the public domain.
  5.  
  6. // This program written and compiled with Borland C++ v3.1
  7. // Compatibility with other compilers is not guaranteed.
  8.  
  9. // Usage of this program is subject to the disclaimer printed
  10. // in the magazine.  You assume all risks associated with the use
  11. // of this program.
  12.  
  13. // You may find this code more legible if you remove some of the comments,
  14. // which are intended to guide you to the correct places in the article!
  15.  
  16.  
  17. #include <stdio.h>
  18. #include <conio.h>
  19. #include <stdlib.h>
  20. #include <dos.h>
  21. #include <mem.h>
  22.  
  23. #define YES 1
  24. #define NO  0
  25.  
  26. char far *screen=MK_FP(0xA000,0);
  27.  
  28. void    SetGraphicsMode( void ) {
  29.     asm {
  30.         mov    ax,0x13
  31.     int    0x10
  32.       }
  33. }
  34.  
  35. void    SetTextMode( void ) {
  36.     asm {
  37.       mov    ax,0x03
  38.     int    0x10;
  39.     }
  40. }
  41.  
  42. void SetPoint( int X, int Y, int C ) {
  43.   *(screen+(Y*320)+X)=C;
  44. }
  45.  
  46.  
  47. /* Set a block of 'Num' palette registers */
  48.  
  49. void    SetBlockPal( char Pal, char *Array, char Num ) {
  50.   asm {
  51.       push es
  52.     les di,Array
  53.     mov dx,di
  54.     xor    ch, ch
  55.     mov    cl, Num
  56.     mov ax, 0x1012
  57.     xor    bh, bh
  58.     mov    bl, Pal
  59.     int    0x10
  60.     pop    es
  61.     }
  62. }
  63.  
  64.  
  65. /* Read and display the PCX file */
  66.  
  67. void ReadPCX( char *filename )
  68. {
  69.     FILE *fptr;
  70.   char palette[792];
  71.   char header[128];
  72.     unsigned char c, runlen;
  73.     int i, r;
  74.   int x, y, w, h;
  75.   int tx, ty;
  76.   int maxx, maxy;
  77.   int drawing;
  78.  
  79.  
  80. /* TEXT STEP 1 */
  81.  
  82.   /* Open the file */
  83.   fptr = fopen(filename,"rb");
  84.     if (fptr==NULL) {
  85.      printf( "\nError - Couldn't open PCX file %s!\n", filename );
  86.      return;
  87.      }
  88.  
  89.   /* Read the header information */
  90.   r = fread( &header, 1, 128, fptr );
  91.   if ( r != 128 ) {
  92.      printf( "\nError - Failed to read header!\n" );
  93.      fclose(fptr);
  94.      return;
  95.      }
  96.  
  97.   /* Check if this is a 256 colour file */
  98.   if ( header[1] != 5 || header[3] != 8 ) {
  99.      printf( "Error - This doesn't appear to be a 256 colour file\n" );
  100.      fclose(fptr);
  101.      return;
  102.      }
  103.  
  104.   /* C readers - this is a quick way to get an 'int' from two chars */
  105.  
  106.   /* Get the top left x and y */
  107.   memcpy( &x, &header[4], 2 );
  108.   memcpy( &y, &header[6], 2 );
  109.  
  110.   /* Get the width and height */
  111.   memcpy( &w, &header[8], 2 );
  112.   memcpy( &h, &header[10], 2 );
  113.  
  114.   /* Make sure we can fit the image on the screen */
  115.   if ( x+w > 319 || y+h > 199 ) {
  116.     printf( "Error - can't fit this image onto a 320x200 screen!\n" );
  117.     fclose(fptr);
  118.     return;
  119.     }
  120.  
  121. /* TEXT STEP 2 */
  122.  
  123.   /* Get the check marker for 256-colour files */
  124.     fseek(fptr,-769L,SEEK_END);
  125.   c = fgetc(fptr);
  126.     if (c!=0x0C) {
  127.     printf( "\nError - File is not a 256 colour VGA PCX file!\n" );
  128.         fclose(fptr);
  129.         return;
  130.         }
  131.  
  132.   /* Now we're confident this is a 256 colour VGA file, we'll set mode 13h */
  133.   SetGraphicsMode();
  134.  
  135.  
  136. /* TEXT STEP 3 */
  137.  
  138.   /* Read in the 256 colour palette */
  139.      r = fread( &palette, 1, 768, fptr );
  140.     if (r != 768) {
  141.     printf( "\nError - Failed to read palette\n" );
  142.         fclose(fptr);
  143.         return;
  144.         }
  145.  
  146.  
  147. /* TEXT STEP 4 */
  148.  
  149.   /* Divide all the values by 4 */
  150.     for (i=0;i<768;i++)    palette[i] /= 4;
  151.  
  152.  
  153. /* TEXT STEP 5 */
  154.  
  155.   SetBlockPal( 0, palette, 255 );
  156.  
  157.  
  158. /* TEXT STEP 6 */
  159.  
  160.     fseek(fptr,128L,SEEK_SET);
  161.  
  162.  
  163. /* TEXT STEP 7 */
  164.  
  165.   tx = x;
  166.   ty = y;
  167.   maxx = x+w;
  168.   maxy = y+h;
  169.  
  170.   /* as long as the variable "drawing" is set to "YES" (1), we are still
  171.      drawing the image */
  172.  
  173.   drawing = YES;
  174.     while (drawing) {
  175.  
  176. /* TEXT STEP 8 */
  177.  
  178.     c=fgetc(fptr);
  179.  
  180.     /* Check for a run */
  181.         if ((c & 0xc0) == 0xc0) {
  182.  
  183.  
  184.   /* TEXT STEP 9 */
  185.  
  186.       /* Strip off the high bits to get the run length */
  187.             runlen = c & 0x3f;
  188.  
  189.  
  190.   /* TEXT STEP 10 */
  191.  
  192.             /* get the colour of the run */
  193.             c=fgetc(fptr);
  194.             }
  195.         else
  196.       /* if it's not a run, just set the run length to 1 */
  197.       runlen = 1;
  198.  
  199.     do {
  200.  
  201.   /* TEXT STEP 11 */
  202.  
  203.       SetPoint( tx, ty, c );
  204.  
  205.  
  206.   /* TEXT STEP 12 */
  207.  
  208.       if ( ++tx > maxx ) {
  209.          tx = x;
  210.          ty++;
  211.          }
  212.  
  213.       if ( ty > maxy ) drawing = NO;
  214.  
  215.  
  216.   /* TEXT STEP 13 */
  217.  
  218.       } while ( drawing && --runlen > 0 );
  219.  
  220.     }
  221.  
  222.  
  223.   /* TEXT STEP 14 */
  224.  
  225.   fclose(fptr);
  226.  
  227.  
  228.   /* Now we'll wait for the user to press a key */
  229.   getch();
  230.  
  231.   /* and go back to text mode */
  232.   SetTextMode();
  233. }
  234.  
  235.  
  236. /* The main function */
  237.  
  238. void main( int argc, char **argv ) {
  239.  
  240.      if ( argc == 1 ) {
  241.         printf( "\nPlease specify a filename!  (eg PCX-SHOW RAPTOR.PCX)\n" );
  242.         return;
  243.         }
  244.  
  245.      /* Assume the parameter passed is a filename, and try to display it */
  246.      ReadPCX( argv[1] );
  247. }