home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / SUPP / PCXMODEY.CPP < prev    next >
C/C++ Source or Header  |  1992-10-31  |  3KB  |  151 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. #include "vd2.hpp"
  20.  
  21. static int getbyte(int *c, int *count, FILE *in)
  22. {
  23.     if (feof(in)) return EOF;
  24.     *c = getc(in) & 0xFF;
  25.     if ((*c & 0xC0) == 0xC0) {
  26.         *count = *c & 0x3F;
  27.         if (feof(in)) return EOF;
  28.         *c = getc(in) & 0xFF;
  29.     }
  30.     else
  31.         *count = 1;
  32.     return NULL;
  33. }
  34.  
  35. static void putbyte(int c, int count, FILE *out)
  36. {
  37.     if (count == 0)
  38.         return;
  39.     if (count > 1 || (c & 0xC0) == 0xC0)
  40.         putc(count | 0xC0, out);
  41.     putc(c, out);
  42. }
  43.  
  44. static unsigned char far *screen = (unsigned char far *)MK_FP(0xA000, 0);
  45.  
  46. static void write_line(char far *buffer, char far *scr)
  47. {
  48.     int i, plane;
  49.     char *add, *buff;
  50.  
  51.     for (plane = 0; plane < 4; ++plane)
  52.     {
  53.         outport(0x3C4, (1<<(plane+8))+2);
  54.         add = scr;
  55.         buff = &buffer[plane];
  56.         for (i = 0; i < 80; ++i)
  57.         {
  58.             *add++ = *buff;
  59.             buff += 4;
  60.         }
  61.     }
  62. }
  63.  
  64. load_pcx(FILE *in, int page)
  65. {
  66.     int c, count;
  67.     char buff[330];
  68.     char *buffer = &buff[0];
  69.     char *scr = &screen[16000*page];
  70.     unsigned nread = 0;
  71.  
  72.     reset_hdwe();
  73.     fseek(in, 128L, SEEK_SET); /* skip PCX header */
  74.     while (getbyte(&c, &count, in) != EOF)
  75.         while (count--)
  76.         {
  77.             *buffer++ = c;
  78.             if (++nread == 320)
  79.             {
  80.                 write_line(&buff[0],scr);
  81.                 buffer = &buff[0];
  82.                 nread = 0;
  83.                 scr += 80;
  84.             }
  85.         }
  86.     return 0;
  87. }
  88.  
  89. struct {
  90.     unsigned char manu, hard, encod, bitpx;
  91.     unsigned int x1, y1, x2, y2;
  92.     unsigned int hres, vres;
  93.     unsigned char palette[48];
  94.     unsigned char vmode, nplanes;
  95.     unsigned int bytesPerLine;
  96.     char unused[128-68];
  97.     } pccHeader =
  98.     { 10, 5, 1, 8, 0, 0, 319, 199, 75, 75, { 0 }, 0x13, 1, 320, 0 };
  99.  
  100. struct { 
  101.     unsigned char r, g, b; 
  102.     } palbuff[256];
  103.  
  104. static char get_pixel(unsigned int adr, int page)
  105. {
  106.     outport(0x3CE, ((adr&3)<<8)+4); /* select plane to read */
  107.     return *(char *)(MK_FP(0xA000+1000*page,adr>>2));
  108. }
  109.  
  110.  
  111. save_pcx(FILE *out, int page)
  112. {
  113.     unsigned c, oldc, count;
  114.     unsigned nput = 1;
  115.     union REGS r;
  116.  
  117.     reset_hdwe();
  118.     fwrite(&pccHeader, 128, 1, out);
  119.     count = 1;
  120.     oldc = get_pixel(0,page);
  121.     while ((nput>>2) < 16000)
  122.     {
  123.         c = get_pixel(nput++, page);
  124.         if (c != oldc)
  125.         {
  126.             putbyte(oldc, count, out);
  127.             oldc = c;
  128.             count = 1;
  129.         }
  130.         else if (++count >= 63)
  131.         {
  132.             putbyte(oldc, count, out);
  133.             count = 0;
  134.         }
  135.     }
  136.     putbyte(oldc, count, out);
  137.  
  138.     putc(0x0C, out);
  139.     for (count = 0; count < 256; ++count)
  140.     {
  141.         r.x.ax = 0x1015;
  142.         r.x.bx = count; /* write pallete */
  143.         int86(0x10, &r, &r);
  144.         putc(r.h.dh<<2, out);
  145.         putc(r.h.ch<<2, out);
  146.         putc(r.h.cl<<2, out);
  147.     }
  148.     return 0;
  149. }
  150.  
  151.