home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Developers Magazine 3
/
GDM003.ZIP
/
PCX-SHOW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-25
|
5KB
|
247 lines
// PCX-SHOW.C - Program to demonstrate viewing of 256 colour VGA PCX files
// Written by Phil Inch for Game Developers Magazine (issue 3).
// Contributed to the public domain.
// This program written and compiled with Borland C++ v3.1
// Compatibility with other compilers is not guaranteed.
// Usage of this program is subject to the disclaimer printed
// in the magazine. You assume all risks associated with the use
// of this program.
// You may find this code more legible if you remove some of the comments,
// which are intended to guide you to the correct places in the article!
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
#define YES 1
#define NO 0
char far *screen=MK_FP(0xA000,0);
void SetGraphicsMode( void ) {
asm {
mov ax,0x13
int 0x10
}
}
void SetTextMode( void ) {
asm {
mov ax,0x03
int 0x10;
}
}
void SetPoint( int X, int Y, int C ) {
*(screen+(Y*320)+X)=C;
}
/* Set a block of 'Num' palette registers */
void SetBlockPal( char Pal, char *Array, char Num ) {
asm {
push es
les di,Array
mov dx,di
xor ch, ch
mov cl, Num
mov ax, 0x1012
xor bh, bh
mov bl, Pal
int 0x10
pop es
}
}
/* Read and display the PCX file */
void ReadPCX( char *filename )
{
FILE *fptr;
char palette[792];
char header[128];
unsigned char c, runlen;
int i, r;
int x, y, w, h;
int tx, ty;
int maxx, maxy;
int drawing;
/* TEXT STEP 1 */
/* Open the file */
fptr = fopen(filename,"rb");
if (fptr==NULL) {
printf( "\nError - Couldn't open PCX file %s!\n", filename );
return;
}
/* Read the header information */
r = fread( &header, 1, 128, fptr );
if ( r != 128 ) {
printf( "\nError - Failed to read header!\n" );
fclose(fptr);
return;
}
/* Check if this is a 256 colour file */
if ( header[1] != 5 || header[3] != 8 ) {
printf( "Error - This doesn't appear to be a 256 colour file\n" );
fclose(fptr);
return;
}
/* C readers - this is a quick way to get an 'int' from two chars */
/* Get the top left x and y */
memcpy( &x, &header[4], 2 );
memcpy( &y, &header[6], 2 );
/* Get the width and height */
memcpy( &w, &header[8], 2 );
memcpy( &h, &header[10], 2 );
/* Make sure we can fit the image on the screen */
if ( x+w > 319 || y+h > 199 ) {
printf( "Error - can't fit this image onto a 320x200 screen!\n" );
fclose(fptr);
return;
}
/* TEXT STEP 2 */
/* Get the check marker for 256-colour files */
fseek(fptr,-769L,SEEK_END);
c = fgetc(fptr);
if (c!=0x0C) {
printf( "\nError - File is not a 256 colour VGA PCX file!\n" );
fclose(fptr);
return;
}
/* Now we're confident this is a 256 colour VGA file, we'll set mode 13h */
SetGraphicsMode();
/* TEXT STEP 3 */
/* Read in the 256 colour palette */
r = fread( &palette, 1, 768, fptr );
if (r != 768) {
printf( "\nError - Failed to read palette\n" );
fclose(fptr);
return;
}
/* TEXT STEP 4 */
/* Divide all the values by 4 */
for (i=0;i<768;i++) palette[i] /= 4;
/* TEXT STEP 5 */
SetBlockPal( 0, palette, 255 );
/* TEXT STEP 6 */
fseek(fptr,128L,SEEK_SET);
/* TEXT STEP 7 */
tx = x;
ty = y;
maxx = x+w;
maxy = y+h;
/* as long as the variable "drawing" is set to "YES" (1), we are still
drawing the image */
drawing = YES;
while (drawing) {
/* TEXT STEP 8 */
c=fgetc(fptr);
/* Check for a run */
if ((c & 0xc0) == 0xc0) {
/* TEXT STEP 9 */
/* Strip off the high bits to get the run length */
runlen = c & 0x3f;
/* TEXT STEP 10 */
/* get the colour of the run */
c=fgetc(fptr);
}
else
/* if it's not a run, just set the run length to 1 */
runlen = 1;
do {
/* TEXT STEP 11 */
SetPoint( tx, ty, c );
/* TEXT STEP 12 */
if ( ++tx > maxx ) {
tx = x;
ty++;
}
if ( ty > maxy ) drawing = NO;
/* TEXT STEP 13 */
} while ( drawing && --runlen > 0 );
}
/* TEXT STEP 14 */
fclose(fptr);
/* Now we'll wait for the user to press a key */
getch();
/* and go back to text mode */
SetTextMode();
}
/* The main function */
void main( int argc, char **argv ) {
if ( argc == 1 ) {
printf( "\nPlease specify a filename! (eg PCX-SHOW RAPTOR.PCX)\n" );
return;
}
/* Assume the parameter passed is a filename, and try to display it */
ReadPCX( argv[1] );
}