PCX to bitmap scroll plane converter (v0.1) by Charles Doty
PCX to bitmap scroll plane converter (v0.1) by Charles Doty
(cdoty@netzero.net)
PCXToSat will convert 8 bit PCX files to 8 bit bitmap scroll plane files for the Saturn. PCXToSat can output a binary or C file.
To use 'PCXToSat' type:
PCXtoSAT Filein.PCX Fileout Type [Array Name]
Filein.PCX is the name of a 8 bit PCX file.
Fileout (no extension) is the name of Saturn image to save.
Type is BIN or C. BIN produces a binary file, C produces a C array.
[Array Name] is the name of the C array. Only needed for C array files.
PCXToSat will then convert the image to the Saturn format as either a binary file or C array text file. Two files are produced an image file and a palette file.
PCXToSat will only run under Windows 9x/NT (2000 is untested), as a console application.
Also included in the archive is the source to 'PCXToSat', adn the source to a simple bitmap plane demo.
Please e-mail me (cdoty@netzero.net), if you find a problem with 'PCXToSat'.
PCXTOSAT.CPP
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define DATAPERLINE 8
typedef struct PCXHeader
{
BYTE id;
BYTE version;
BYTE rle;
BYTE bpp;
WORD xstart;
WORD ystart;
WORD xend;
WORD yend;
WORD hres;
WORD vres;
BYTE pal[48];
BYTE rsvd1;
BYTE nbitp;
WORD bytesperline;
WORD paltype;
WORD hsize;
WORD vsize;
BYTE rsvd2[54];
} PCX;
BYTE PCXBuffer[76800];
BYTE Palette[768];
WORD ConvPal[256];
long Width, Height, pal, start;
void FlipBuffer(DWORD length, WORD *buffer);
int LoadPCX(char *file, BYTE *outpix, BYTE *pal);
long FileSize(FILE *handle);
void Usage();
void main(int argc, char *argv[])
{
char filename[128];
char savefile[128];
if (argc < 4)
{
Usage();
}
strcpy(filename, argv[1]);
strcpy(savefile, argv[2]);
FILE *handle = fopen(filename, "rb");
if (NULL == handle)
{
printf("Unable to open %s\n", filename);
exit(0);
}
fseek(handle, 0, SEEK_END);
DWORD length = ftell(handle);
rewind(handle);
if (length <= 0)
{
fclose(handle);
printf("%s is not a valid file\n.", filename);
return;
}
printf("Converting File...");
LoadPCX(filename, PCXBuffer, Palette);
for (DWORD loop = 0; loop < 256; loop++)
{
BYTE Red = Palette[loop * 3] >> 3;
BYTE Green = Palette[loop * 3 + 1] >> 3;
BYTE Blue = Palette[loop * 3 + 2] >> 3;
ConvPal[loop] = (Blue << 10) | (Green << 5) | Red;
}
printf("Completed.\nWriting File...");
if (!strcmp(argv[3], "BIN"))
{
char Filename[256];
strcpy(Filename, savefile);
strcat(Filename, ".bin");
handle = fopen(Filename, "wb");
if (NULL == handle)
{
printf("Unable to create %s\n.", savefile);
return;
}
fwrite(PCXBuffer, 1, Width * Height, handle);
fclose(handle);
FlipBuffer(256, ConvPal);
strcpy(Filename, savefile);
strcat(Filename, "Pal.bin");
handle = fopen(Filename, "wb");
if (NULL == handle)
{
printf("Unable to create %s\n.", savefile);
return;
}
fwrite(ConvPal, 2, 256, handle);
fclose(handle);
}
else
{
char Filename[256];
if (argc < 5)
{
Usage();
}
strcpy(Filename, savefile);
strcat(Filename, ".c");
handle = fopen(Filename, "wt");
if (NULL == handle)
{
printf("Unable to create %s\n.", savefile);
return;
}
fprintf(handle, "// Source File: %s\n\n", argv[1]);
fprintf(handle, "unsigned char %s[] =\n", argv[4]);
fprintf(handle, "{\n ");
for (long loop = 0; loop < Width * Height; loop++)
{
fprintf(handle, "0x%02X", PCXBuffer[loop]);
if (loop < (Width * Height) - 1)
{
fprintf(handle, ", ");
if (0 == ((loop + 1) % DATAPERLINE))
{
fprintf(handle, "\n ");
}
}
}
fprintf(handle, "\n};\n\n");
fprintf(handle, "#define %sWidth = %d\n", argv[4], Width);
fprintf(handle, "#define %sHeight = %d\n", argv[4], Height);
fclose(handle);
strcpy(Filename, savefile);
strcat(Filename, "Pal.c");
handle = fopen(Filename, "wt");
if (NULL == handle)
{
printf("Unable to create %s\n.", savefile);
return;
}
fprintf(handle, "// Source File: %s\n\n", argv[1]);
fprintf(handle, "unsigned short %sPal[] = \n", argv[4]);
fprintf(handle, "{\n ");
for (loop = 0; loop < 256; loop++)
{
fprintf(handle, "0x%04X", ConvPal[loop]);
if (loop < (256) - 1)
{
fprintf(handle, ", ");
if (0 == ((loop + 1) % DATAPERLINE))
{
fprintf(handle, "\n ");
}
}
}
fprintf(handle, "\n};\n\n");
fprintf(handle, "#define %sPalSize = %d\n", argv[4], 256);
fclose(handle);
}
printf("Completed.\n");
}
void FlipBuffer(DWORD length, WORD *buffer)
{
for (DWORD loop = 0; loop < length; loop ++)
{
WORD pixel = *buffer;
*buffer = ((pixel & 0xff) << 8) | ((pixel & 0xff00) >> 8);
buffer++;
}
}
int LoadPCX(char *file, BYTE *outpix, BYTE *pal)
{
int i, w, h;
PCXHeader hdr;
long pos;
int ret = 0;
FILE *handle = fopen(file, "rb");
if (NULL == handle)
{
goto bye;
}
pos = ftell(handle);
fread (&hdr, 1, sizeof(hdr), handle);
if (hdr.id != 0x0A || hdr.version != 5 || hdr.rle != 1
|| (hdr.bpp == 8 && hdr.nbitp != 1))
goto bye;
w = hdr.xend - hdr.xstart + 1;
Width = w;
h = hdr.yend - hdr.ystart + 1;
Height = h;
if (hdr.bpp == 1 && hdr.nbitp == 4)
{
memset(pal, 0, 768);
for (i = 0; i < 48; i++)
pal[i] = hdr.pal[i] >> 2;
}
else if (hdr.bpp == 8 && hdr.nbitp == 1)
{
fseek(handle, FileSize(handle) - 768, SEEK_SET);
for (i = 0; i < 768; i++)
fread(&pal[i], 1, 1, handle);
}
else
goto bye;
ret = 1;
fseek(handle, sizeof(PCXHeader), SEEK_SET);
while (h-- > 0)
{
BYTE c;
BYTE *outpt;
int np = 0;
outpt = outpix;
memset(outpix, 0, w);
for (np = 0; np < hdr.nbitp; np++)
{
i = 0;
outpix = outpt;
do
{
c = (BYTE)getc(handle);
if ((c & 0xC0) != 0xC0)
{
if (hdr.bpp == 1)
{
int k;
for (k = 7; k >= 0; k--)
*outpix++ |= ((c >> k) & 1) << np;
i += 8;
}
else
{
*outpix++ = c;
i++;
}
}
else
{
BYTE v;
v = (BYTE)getc(handle);
c &= ~0xC0;
while (c > 0 && i < w)
{
if (hdr.bpp == 1)
{
int k;
for (k = 7; k >= 0; k--)
*outpix++ |= ((v >> k) & 1) << np;
i += 8;
}
else
{
*outpix++ = v;
i++;
}
c--;
}
}
}
while (i < w);
}
}
bye:
if (handle != NULL)
{
fclose(handle);
}
return ret;
}
long FileSize(FILE *handle)
{
long length;
fseek(handle, 0, SEEK_END);
length = ftell(handle);
rewind(handle);
return length;
}
void Usage()
{
printf("PCXtoSAT (v0.1) PCX to Saturn converter by Charles Doty (cdoty@netzero.net).\n\n");
printf(" Usage: PCXtoSAT Filein.PCX Fileout Type [Array Name]\n" );
printf(" Filein.PCX is the name of a 8 bit PCX file.\n");
printf(" Fileout (no extension) is the name of Saturn image to save.\n");
printf(" Type is BIN or C. BIN produces a binary file, C produces a C array.\n");
printf(" [Array Name] is the name of the C array. Only needed for C array files.\n");
exit(0);
}