/* Include file for loading an IFF/LBM compressed picture */


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

union REGS regs;

#define FORM 0x464f524dL
#define ILBM 0x494c424dL
#define BMHD 0x424d4844L
#define CMAP 0x434d4150L
#define BODY 0x424f4459L

unsigned char palbuf[768];

long read32bit();
long to32bit();



load_iff(unsigned char *fname,unsigned char far *dest)
{
FILE* f;

unsigned char trash[10];
unsigned long id,length;
unsigned char red,green,blue;
unsigned char planes,compress;
int width,height;

unsigned int i,plane;
unsigned int addr,scan,nextline;
unsigned char byte,b;

       f = fopen(fname,"rb");
       if(f == NULL)
         error("File not found!");

       id = read32bit(f);
       if(id != FORM)
          error("Not an IFF/LBM file!");

       length = read32bit(f);

       id = read32bit(f);
       if(id != ILBM)
         error("Not an IFF/LBM file!");


       while(1)
       {
               id = read32bit(f);
               length = read32bit(f);
               if(id == BMHD) break;
               fseek(f,length,SEEK_CUR);
       }

       width = read16bit(f);
       height = read16bit(f);

       fseek(f,4L,SEEK_CUR);

       planes = (unsigned char)getc(f);        /* no of bitplanes */
       getc(f);
       compress = (unsigned char)getc(f);      /* compress flag */

       if(compress == 0)
               error("Not a compressed picture!");

       fseek(f,9L,SEEK_CUR);

       while(1)
       {
               id = read32bit(f);
               length = read32bit(f);
               if(id == CMAP) break;
               fseek(f,length,SEEK_CUR);
       }

       fread(palbuf,768,1,f);
       for (i=0;i<768;i++)
         palbuf[i] >>= 2;

       regs.h.ah = 0x10;
       regs.h.al = 0x12;
       regs.x.bx = 0;
       regs.x.cx = 256;
       regs.x.dx = (unsigned)palbuf;
       int86(0x10,&regs,&regs);

       while(1)
       {
               id = read32bit(f);
               length = read32bit(f);
               if(id == BODY) break;
               fseek(f,length,SEEK_CUR);
       }


       for(scan=0;scan < height;scan++)
       {
               for(plane=0;plane < planes; plane++)              /* 8 bitplanes */
               {
                       addr = 320*scan;
                       nextline = addr + width;
                       do
                       {
                               byte = (unsigned char)getc(f);

                               if(byte < 128)
                               {
                                       for(i=0;i < byte+1; i++)
                                       {
                                               b = (unsigned char)getc(f);

                                               dest[addr++] |= (b >> 7 & 1) << plane;
                                               dest[addr++] |= (b >> 6 & 1) << plane;
                                               dest[addr++] |= (b >> 5 & 1) << plane;
                                               dest[addr++] |= (b >> 4 & 1) << plane;
                                               dest[addr++] |= (b >> 3 & 1) << plane;
                                               dest[addr++] |= (b >> 2 & 1) << plane;
                                               dest[addr++] |= (b >> 1 & 1) << plane;
                                               dest[addr++] |= (b & 1) << plane;
                                       }
                               }
                               else if(byte > 128)
                               {
                                       b = (unsigned char)getc(f);

                                       for(i=0;i < (256-byte)+1; i++)
                                       {
                                               dest[addr++] |= (b >> 7 & 1) << plane;
                                               dest[addr++] |= (b >> 6 & 1) << plane;
                                               dest[addr++] |= (b >> 5 & 1) << plane;
                                               dest[addr++] |= (b >> 4 & 1) << plane;
                                               dest[addr++] |= (b >> 3 & 1) << plane;
                                               dest[addr++] |= (b >> 2 & 1) << plane;
                                               dest[addr++] |= (b >> 1 & 1) << plane;
                                               dest[addr++] |= (b & 1) << plane;
                                       }
                               }
                       } while(addr < nextline);
               }
       }
       fclose(f);
}


error(char *errmsg)
{
       printf("Error: %s\n",errmsg);
       exit(1);
}

int read16bit(FILE* f)
{
       int c1, c2;
       c1 = getc(f);
       c2 = getc(f);
       return to16bit(c1,c2);
}

int to16bit(c1,c2)
int c1, c2;
{
       return ((c1 & 0xff ) << 8) + (c2 & 0xff);
}

long read32bit(FILE* f)
{
       int c1, c2, c3, c4;

       c1 = getc(f);
       c2 = getc(f);
       c3 = getc(f);
       c4 = getc(f);
       return to32bit(c1,c2,c3,c4);
}

long to32bit(c1,c2,c3,c4)
{
       long value = 0L;

       value = (c1 & 0xff);
       value = (value<<8) + (c2 & 0xff);
       value = (value<<8) + (c3 & 0xff);
       value = (value<<8) + (c4 & 0xff);
       return (value);
}

set_mcga()
{
       regs.h.ah = 0;
       regs.h.al = 0x13;
       int86(0x10,&regs,&regs);
}

set_text()
{
       regs.h.ah = 0;
       regs.h.al = 3;
       int86(0x10,&regs,&regs);
}