home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Teach Yourself Game Programming in 21 Days
/
TYGAMES_R.ISO
/
source
/
day_04
/
pcxshow.c
< prev
next >
Wrap
Text File
|
1994-07-25
|
6KB
|
270 lines
// I N C L U D E S ///////////////////////////////////////////////////////////
#include <io.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <fcntl.h>
#include <memory.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include "graph3.h" // our graphics functions from day 3
// S T R U C T U R E S ///////////////////////////////////////////////////////
typedef struct pcx_header_typ
{
char manufacturer;
char version;
char encoding;
char bits_per_pixel;
int x,y;
int width,height;
int horz_res;
int vert_res;
char ega_palette[48];
char reserved;
char num_color_planes;
int bytes_per_line;
int palette_type;
char padding[58];
} pcx_header, *pcx_header_ptr;
typedef struct pcx_picture_typ
{
pcx_header header;
RGB_color palette[256];
char far *buffer;
} pcx_picture, *pcx_picture_ptr;
// P R O T O T Y P E S ///////////////////////////////////////////////////////
void PCX_Init(pcx_picture_ptr image);
void PCX_Load(char *filename, pcx_picture_ptr image,int enable_palette);
void PCX_Delete(pcx_picture_ptr image);
void PCX_Show_Buffer(pcx_picture_ptr image);
// F U N C T I O N S /////////////////////////////////////////////////////////
void PCX_Init(pcx_picture_ptr image)
{
// this function allocates the buffer region needed to load a pcx file
if (!(image->buffer = (char far *)_fmalloc(SCREEN_WIDTH * SCREEN_HEIGHT + 1)))
printf("\ncouldn't allocate screen buffer");
} // end PCX_Init
//////////////////////////////////////////////////////////////////////////////
void PCX_Load(char *filename, pcx_picture_ptr image,int enable_palette)
{
// this function loads a pcx file into a picture structure, the actual image
// data for the pcx file is decompressed and expanded into a secondary buffer
// within the picture structure, the separate images can be grabbed from this
// buffer later. also the header and palette are loaded
FILE *fp;
int num_bytes,index;
long count;
unsigned char data;
char far *temp_buffer;
// open the file
fp = fopen(filename,"rb");
// load the header
temp_buffer = (char far *)image;
for (index=0; index<128; index++)
{
temp_buffer[index] = (char)getc(fp);
} // end for index
// load the data and decompress into buffer
count=0;
while(count<=SCREEN_WIDTH * SCREEN_HEIGHT)
{
// get the first piece of data
data = (unsigned char)getc(fp);
// is this a rle?
if (data>=192 && data<=255)
{
// how many bytes in run?
num_bytes = data-192;
// get the actual data for the run
data = (unsigned char)getc(fp);
// replicate data in buffer num_bytes times
while(num_bytes-->0)
{
image->buffer[count++] = data;
} // end while
} // end if rle
else
{
// actual data, just copy it into buffer at next location
image->buffer[count++] = data;
} // end else not rle
} // end while
// move to end of file then back up 768 bytes i.e. to begining of palette
fseek(fp,-768L,SEEK_END);
// load the pallete into the palette
for (index=0; index<256; index++)
{
// get the red component
image->palette[index].red = (unsigned char)(getc(fp) >> 2);
// get the green component
image->palette[index].green = (unsigned char)(getc(fp) >> 2);
// get the blue component
image->palette[index].blue = (unsigned char)(getc(fp) >> 2);
} // end for index
fclose(fp);
// change the palette to newly loaded palette if commanded to do so
if (enable_palette)
{
// for each palette register set to the new color values
for (index=0; index<256; index++)
{
Set_Palette_Register(index,(RGB_color_ptr)&image->palette[index]);
} // end for index
} // end if change palette
} // end PCX_Load
//////////////////////////////////////////////////////////////////////////////
void PCX_Delete(pcx_picture_ptr image)
{
// this function de-allocates the buffer region used for the pcx file load
_ffree(image->buffer);
} // end PCX_Delete
//////////////////////////////////////////////////////////////////////////////
void PCX_Show_Buffer(pcx_picture_ptr image)
{
// just copy he pcx buffer into the video buffer
char far *data;
data = image->buffer;
_asm
{
push ds ; save the data segment
les di, video_buffer ; point es:di to video buffer
lds si, data ; point ds:si to data area
mov cx,320*200/2 ; move 32000 words
cld ; set direction to foward
rep movsw ; do the string operation
pop ds ; restore the data segment
}
} // end PCX_Show_Buffer
// M A I N ///////////////////////////////////////////////////////////////////
void main(int argc, char **argv)
{
long index; // loop counter
pcx_picture background_pcx; // this pcx structure holds background imagery
FILE *fp; // used to see if file exists
// make sure there is a file name
if (argc<2)
{
printf("\nUsuage: pcxshow filename.PCX");
return;
} // end if
// test if the file exist, but not for the .PCX extension
if (!fopen(argv[1],"rb"))
{
printf("\nFile:%s - not found!",argv[1]);
return(1);
} // end if not found
else
{
fclose(fp);
} // end else found
// set video mode to 320x200 256 color mode
Set_Video_Mode(VGA256);
// load in background
PCX_Init((pcx_picture_ptr)&background_pcx);
PCX_Load(argv[1], (pcx_picture_ptr)&background_pcx,1);
PCX_Show_Buffer((pcx_picture_ptr)&background_pcx);
PCX_Delete((pcx_picture_ptr)&background_pcx);
// wait for user to hit keyboard
while(!kbhit()){}
// disolve the screen...in one line I might add!
for (index=0; index<=300000; index++,Plot_Pixel_Fast(rand()%320, rand()%200, 0));
// go back to text mode
Set_Video_Mode(TEXT_MODE);
} // end main