home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / DEVEL5 / PCXMODEY.C < prev    next >
C/C++ Source or Header  |  1992-09-02  |  3KB  |  149 lines

  1. /* Load a PCX file in mode Y */
  2.  
  3. /* THIS CODE IS CURRENTLY MODE Y DEPENDENT!
  4.    IT WILL NOT WORK IN OTHER MODES */
  5.  
  6. /* Written by Bernie Roehl, April 1992 based on code by Dave Stampe */
  7.  
  8. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  9.    May be freely used to write software for release into the public domain;
  10.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  11.    for permission to incorporate any part of this software into their
  12.    products!
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <dos.h>
  17. #include <alloc.h>
  18.  
  19. static int getbyte(int *c, int *count, FILE *in)
  20. {
  21.     if (feof(in)) return EOF;
  22.     *c = getc(in) & 0xFF;
  23.     if ((*c & 0xC0) == 0xC0) {
  24.         *count = *c & 0x3F;
  25.         if (feof(in)) return EOF;
  26.         *c = getc(in) & 0xFF;
  27.     }
  28.     else
  29.         *count = 1;
  30.     return NULL;
  31. }
  32.  
  33. static void putbyte(int c, int count, FILE *out)
  34. {
  35.     if (count == 0)
  36.         return;
  37.     if (count > 1 || (c & 0xC0) == 0xC0)
  38.         putc(count | 0xC0, out);
  39.     putc(c, out);
  40. }
  41.  
  42. static unsigned char far *screen = MK_FP(0xA000, 0);
  43.  
  44. static void write_line(char far *buffer, char far *scr)
  45. {
  46.     int i, plane;
  47.     char *add, *buff;
  48.  
  49.     for (plane = 0; plane < 4; ++plane)
  50.     {
  51.         outport(0x3C4, (1<<(plane+8))+2);
  52.         add = scr;
  53.         buff = &buffer[plane];
  54.         for (i = 0; i < 80; ++i)
  55.         {
  56.             *add++ = *buff;
  57.             buff += 4;
  58.         }
  59.     }
  60. }
  61.  
  62. load_pcx(FILE *in, int page)
  63. {
  64.     int c, count;
  65.     char buff[330];
  66.     char *buffer = &buff[0];
  67.     char *scr = &screen[16000*page];
  68.     unsigned nread = 0;
  69.  
  70.     reset_hdwe();
  71.     fseek(in, 128L, SEEK_SET); /* skip PCX header */
  72.     while (getbyte(&c, &count, in) != EOF)
  73.         while (count--)
  74.         {
  75.             *buffer++ = c;
  76.             if (++nread == 320)
  77.             {
  78.                 write_line(&buff[0],scr);
  79.                 buffer = &buff[0];
  80.                 nread = 0;
  81.                 scr += 80;
  82.             }
  83.         }
  84.     return 0;
  85. }
  86.  
  87. struct {
  88.     unsigned char manu, hard, encod, bitpx;
  89.     unsigned int x1, y1, x2, y2;
  90.     unsigned int hres, vres;
  91.     unsigned char palette[48];
  92.     unsigned char vmode, nplanes;
  93.     unsigned int bytesPerLine;
  94.     char unused[128-68];
  95.     } pccHeader =
  96.     { 10, 5, 1, 8, 0, 0, 319, 199, 75, 75, { 0 }, 0x13, 1, 320, 0 };
  97.  
  98. struct { 
  99.     unsigned char r, g, b; 
  100.     } palbuff[256];
  101.  
  102. static char get_pixel(unsigned int adr, int page)
  103. {
  104.     outport(0x3CE, ((adr&3)<<8)+4); /* select plane to read */
  105.     return *(char *)(MK_FP(0xA000+1000*page,adr>>2));
  106. }
  107.  
  108.  
  109. save_pcx(FILE *out, int page)
  110. {
  111.     unsigned c, oldc, count;
  112.     unsigned nput = 1;
  113.     union REGS r;
  114.  
  115.     reset_hdwe();
  116.     fwrite(&pccHeader, 128, 1, out);
  117.     count = 1;
  118.     oldc = get_pixel(0,page);
  119.     while ((nput>>2) < 16000)
  120.     {
  121.         c = get_pixel(nput++, page);
  122.         if (c != oldc)
  123.         {
  124.             putbyte(oldc, count, out);
  125.             oldc = c;
  126.             count = 1;
  127.         }
  128.         else if (++count >= 63)
  129.         {
  130.             putbyte(oldc, count, out);
  131.             count = 0;
  132.         }
  133.     }
  134.     putbyte(oldc, count, out);
  135.  
  136.     putc(0x0C, out);
  137.     for (count = 0; count < 256; ++count)
  138.     {
  139.         r.x.ax = 0x1015;
  140.         r.x.bx = count; /* write pallete */
  141.         int86(0x10, &r, &r);
  142.         putc(r.h.dh<<2, out);
  143.         putc(r.h.ch<<2, out);
  144.         putc(r.h.cl<<2, out);
  145.     }
  146.     return 0;
  147. }
  148.  
  149.