/////////////////////////////////////////////
//                                         //
// Rutina para:                            //
//              Ficheros PCX               //
// (Modelos Compact, Medium o Huge)        //
//                                         //
/////////////////////////////////////////////


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


void carga_pcx(const char *, char *);
void descomprime_pcx(char *);
void volcado_a_vga(char *);

char *dir_pcx; //puntero a la zona de memoria donde se guardar  la imagen
char *dir_temporal; //zona donde se guardar  el gr fico comprimido

void main(void)
    {
     //primero reservamos memoria para las dos pantallas
     if ((dir_pcx=(char *)malloc(320*200))==NULL) printf("\nNo hay memoria");
     if ((dir_temporal=(char *)malloc(320*200))==NULL) printf("\nNo hay memoria");

     //asignamos el modo de video 13h
     asm mov ax,0x13
     asm int 0x10

     //luego cargamos el fichero en dir_temporal
     carga_pcx("PRUEBA.PCX",dir_temporal);

     //luego lo descomprimimos y lo guardamos en dir_pcx
     descomprime_pcx(dir_pcx);

     //por ultimo lo dibujamos en la VGA
     volcado_a_vga(dir_pcx);
     
     //pulsa RETURN
     while (getchar()==13);

     //modo texto
     asm mov ax,0x3
     asm int 0x10
    }

void carga_pcx(const char *nombre_fichero, char *dir_pcx)
{
 char *puntero;         
 FILE *dir_fichero;
 long tamano=0;   //tama¤o
 if ((dir_fichero=fopen(nombre_fichero,"rb"))==NULL)
    {
      printf("\nError en fichero %s",nombre_fichero);
      exit(1);
    }
 puntero=dir_pcx;
 while( !feof(dir_fichero) )
      {
        *puntero=getc(dir_fichero);
        puntero++;
        tamano++;
      }
 fclose(dir_fichero);
 }

void descomprime_pcx(char *destino)
     {
      char *origen;
      int h,v,c;
      unsigned char byt;
      origen=dir_temporal+128;
      for(v=200;v>0;v--)
         {
          h=320;
          destino-=h;
          destino+=320;
          while(h>0)
               {
                byt=(unsigned)*origen++;
                if(byt<=192)
                  {*destino++=byt;h--;}
                else
                  {
                   c=byt&63;byt=*origen++;
                   for(;c>0;c--)
                      {*destino++=byt;h--;}
                   }
               }
        }
      origen++;
     {
      /*aqui asignamos la paleta*/
      unsigned int n;
      long int dir;
      char *color;
      struct SREGS seg;
      union REGS met,sac;
      color=origen;
      for(n=256*3;n>0;n--)
         {
          *color=*color>>2;
          color++;
         }
          dir=(long)origen;seg.es=(int)(dir>>16);
          met.h.al=18;met.h.ah=16;met.x.bx=0;met.x.cx=256;met.x.dx=(int)origen;
          int86x(0x10,&met,&sac,&seg);
     }
   }
 
void volcado_a_vga(char *dir)
   {
   asm{
      push ds
      lds  si, dir
      mov  ax,0xA000
      mov  es,ax
      xor  di,di
      mov  cx,32000
      rep movsw
      pop ds
      }
   }


