home *** CD-ROM | disk | FTP | other *** search
/ Teach Yourself Game Programming in 21 Days / TYGAMES_R.ISO / source / day_04 / pcxshow.c < prev    next >
Text File  |  1994-07-25  |  6KB  |  270 lines

  1.  
  2. // I N C L U D E S ///////////////////////////////////////////////////////////
  3.  
  4. #include <io.h>
  5. #include <conio.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <dos.h>
  9. #include <bios.h>
  10. #include <fcntl.h>
  11. #include <memory.h>
  12. #include <malloc.h>
  13. #include <math.h>
  14. #include <string.h>
  15.  
  16. #include "graph3.h"  // our graphics functions from day 3
  17.  
  18. // S T R U C T U R E S ///////////////////////////////////////////////////////
  19.  
  20. typedef struct pcx_header_typ
  21.         {
  22.         char manufacturer;
  23.         char version;
  24.         char encoding;
  25.         char bits_per_pixel;
  26.         int x,y;
  27.         int width,height;
  28.         int horz_res;
  29.         int vert_res;
  30.         char ega_palette[48];
  31.         char reserved;
  32.         char num_color_planes;
  33.         int bytes_per_line;
  34.         int palette_type;
  35.         char padding[58];
  36.  
  37.         } pcx_header, *pcx_header_ptr;
  38.  
  39.  
  40. typedef struct pcx_picture_typ
  41.         {
  42.         pcx_header header;
  43.         RGB_color palette[256];
  44.         char far *buffer;
  45.  
  46.         } pcx_picture, *pcx_picture_ptr;
  47.  
  48. // P R O T O T Y P E S ///////////////////////////////////////////////////////
  49.  
  50. void PCX_Init(pcx_picture_ptr image);
  51.  
  52. void PCX_Load(char *filename, pcx_picture_ptr image,int enable_palette);
  53.  
  54. void PCX_Delete(pcx_picture_ptr image);
  55.  
  56. void PCX_Show_Buffer(pcx_picture_ptr image);
  57.  
  58. // F U N C T I O N S /////////////////////////////////////////////////////////
  59.  
  60. void PCX_Init(pcx_picture_ptr image)
  61. {
  62. // this function allocates the buffer region needed to load a pcx file
  63.  
  64. if (!(image->buffer = (char far *)_fmalloc(SCREEN_WIDTH * SCREEN_HEIGHT + 1)))
  65.  
  66.    printf("\ncouldn't allocate screen buffer");
  67.  
  68. } // end PCX_Init
  69.  
  70. //////////////////////////////////////////////////////////////////////////////
  71.  
  72. void PCX_Load(char *filename, pcx_picture_ptr image,int enable_palette)
  73. {
  74. // this function loads a pcx file into a picture structure, the actual image
  75. // data for the pcx file is decompressed and expanded into a secondary buffer
  76. // within the picture structure, the separate images can be grabbed from this
  77. // buffer later.  also the header and palette are loaded
  78.  
  79. FILE *fp;
  80. int num_bytes,index;
  81. long count;
  82. unsigned char data;
  83. char far *temp_buffer;
  84.  
  85. // open the file
  86.  
  87. fp = fopen(filename,"rb");
  88.  
  89. // load the header
  90.  
  91. temp_buffer = (char far *)image;
  92.  
  93. for (index=0; index<128; index++)
  94.     {
  95.     temp_buffer[index] = (char)getc(fp);
  96.     } // end for index
  97.  
  98. // load the data and decompress into buffer
  99.  
  100. count=0;
  101.  
  102. while(count<=SCREEN_WIDTH * SCREEN_HEIGHT)
  103.      {
  104.      // get the first piece of data
  105.  
  106.      data = (unsigned char)getc(fp);
  107.  
  108.      // is this a rle?
  109.  
  110.      if (data>=192 && data<=255)
  111.         {
  112.         // how many bytes in run?
  113.  
  114.         num_bytes = data-192;
  115.  
  116.         // get the actual data for the run
  117.  
  118.         data  = (unsigned char)getc(fp);
  119.  
  120.         // replicate data in buffer num_bytes times
  121.  
  122.         while(num_bytes-->0)
  123.              {
  124.              image->buffer[count++] = data;
  125.  
  126.              } // end while
  127.  
  128.         } // end if rle
  129.      else
  130.         {
  131.         // actual data, just copy it into buffer at next location
  132.  
  133.         image->buffer[count++] = data;
  134.  
  135.         } // end else not rle
  136.  
  137.      } // end while
  138.  
  139. // move to end of file then back up 768 bytes i.e. to begining of palette
  140.  
  141. fseek(fp,-768L,SEEK_END);
  142.  
  143. // load the pallete into the palette
  144.  
  145. for (index=0; index<256; index++)
  146.     {
  147.     // get the red component
  148.  
  149.     image->palette[index].red   = (unsigned char)(getc(fp) >> 2);
  150.  
  151.     // get the green component
  152.  
  153.     image->palette[index].green = (unsigned char)(getc(fp) >> 2);
  154.  
  155.     // get the blue component
  156.  
  157.     image->palette[index].blue  = (unsigned char)(getc(fp) >> 2);
  158.  
  159.     } // end for index
  160.  
  161. fclose(fp);
  162.  
  163. // change the palette to newly loaded palette if commanded to do so
  164.  
  165. if (enable_palette)
  166.    {
  167.  
  168.    // for each palette register set to the new color values
  169.  
  170.    for (index=0; index<256; index++)
  171.        {
  172.  
  173.        Set_Palette_Register(index,(RGB_color_ptr)&image->palette[index]);
  174.  
  175.        } // end for index
  176.  
  177.    } // end if change palette
  178.  
  179. } // end PCX_Load
  180.  
  181. //////////////////////////////////////////////////////////////////////////////
  182.  
  183. void PCX_Delete(pcx_picture_ptr image)
  184. {
  185. // this function de-allocates the buffer region used for the pcx file load
  186.  
  187. _ffree(image->buffer);
  188.  
  189. } // end PCX_Delete
  190.  
  191. //////////////////////////////////////////////////////////////////////////////
  192.  
  193. void PCX_Show_Buffer(pcx_picture_ptr image)
  194. {
  195. // just copy he pcx buffer into the video buffer
  196.  
  197. char far *data;
  198.  
  199. data = image->buffer;
  200.  
  201. _asm
  202.    {
  203.    push ds               ; save the data segment
  204.    les di, video_buffer  ; point es:di to video buffer
  205.    lds si, data          ; point ds:si to data area
  206.    mov cx,320*200/2      ; move 32000 words
  207.    cld                   ; set direction to foward
  208.    rep movsw             ; do the string operation
  209.    pop ds                ; restore the data segment
  210.    }
  211.  
  212. } // end PCX_Show_Buffer
  213.  
  214. // M A I N ///////////////////////////////////////////////////////////////////
  215.  
  216. void main(int argc, char **argv)
  217. {
  218. long index;                  // loop counter
  219. pcx_picture background_pcx;  // this pcx structure holds background imagery
  220. FILE *fp;                    // used to see if file exists
  221.  
  222. // make sure there is a file name
  223.  
  224. if (argc<2)
  225.    {
  226.    printf("\nUsuage: pcxshow filename.PCX");
  227.    return;
  228.  
  229.    } // end if
  230.  
  231. // test if the file exist, but not for the .PCX extension
  232.  
  233. if (!fopen(argv[1],"rb"))
  234.    {
  235.    printf("\nFile:%s - not found!",argv[1]);
  236.    return(1);
  237.    } // end if not found
  238. else
  239.    {
  240.    fclose(fp);
  241.    } // end else found
  242.  
  243. // set video mode to 320x200 256 color mode
  244.  
  245. Set_Video_Mode(VGA256);
  246.  
  247. // load in background
  248.  
  249. PCX_Init((pcx_picture_ptr)&background_pcx);
  250.  
  251. PCX_Load(argv[1], (pcx_picture_ptr)&background_pcx,1);
  252.  
  253. PCX_Show_Buffer((pcx_picture_ptr)&background_pcx);
  254.  
  255. PCX_Delete((pcx_picture_ptr)&background_pcx);
  256.  
  257. // wait for user to hit keyboard
  258.  
  259. while(!kbhit()){}
  260.  
  261. // disolve the screen...in one line I might add!
  262.  
  263. for (index=0; index<=300000; index++,Plot_Pixel_Fast(rand()%320, rand()%200, 0));
  264.  
  265. // go back to text mode
  266.  
  267. Set_Video_Mode(TEXT_MODE);
  268.  
  269. } // end main
  270.