home *** CD-ROM | disk | FTP | other *** search
- /*
- * Bas2PCX -- Convert a BASIC BLOAD image to .PCX format
- *
- * Usage: bas2pcx <infile> [outfile]
- *
- * Where: <infile> = BLOAD image to load (.PIC extension default)
- * [outfile] = .PCX file generated. If not specified
- * input filename is used, with .PCX added.
- */
-
- /* INCLUDES */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <dir.h>
- #include <io.h>
- #include <alloc.h>
- #include <conio.h>
- #include <mem.h>
- #include <process.h>
-
-
-
- /* DEFINES */
-
- #define EGA_320_200_16 0x0D
-
- #define graph_out(index, val) \
- { \
- outp(0x3CE, index); \
- outp(0x3CF, val ); \
- }
-
- #define seq_out(index, val) \
- { \
- outp(0x3C4, index); \
- outp(0x3C5, val ); \
- }
-
-
-
-
- /* TYPEDEFS */
-
- typedef unsigned char UBYTE;
- typedef int WORD;
- typedef unsigned int UWORD;
- typedef long LONG;
- typedef unsigned long ULONG;
-
-
-
-
- /* FUNCTIONS */
-
- /*
- * get_parms() - Crack the parameters passed in from the command line.
- */
- void get_parms(int argc, char *argv[], char *fin, char *fout)
- {
- char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
-
-
- /* The first parameter is the input file. Add .PIC extension if needed. */
-
- fnsplit(argv[1], drive, dir, file, ext);
-
- if(ext[0] == '\0')
- strcpy(ext, ".PIC");
-
- fnmerge(fin, drive, dir, file, ext);
-
- /* Check for presence of next parameter */
-
- if(argc == 3)
- {
- fnsplit(argv[2], drive, dir, file, ext);
-
- if(ext[0] == '\0')
- strcpy(ext, ".PCX");
- }
- else
- strcpy(ext, ".PCX");
-
- fnmerge(fout, drive, dir, file, ".PCX");
- }
-
-
-
- /*
- * mode() - Set the video mode
- */
- void mode(WORD mode)
- {
- _AH = 0;
- _AL = mode;
-
- geninterrupt(0x10);
- }
-
-
-
- /*
- * cls() - Clear the screen to the given color
- */
- void cls(WORD color)
- {
- union REGS r;
-
-
- r.x.ax = 0x0600;
- r.x.cx = 0x0000;
- r.x.dx = 0x184F;
- r.h.bh = color;
-
- int86(0x10, &r, &r);
- }
-
-
-
- /*
- * get_pixel() - Read a pixel from the BLOAD buffer.
- */
- UBYTE get_pixel(UBYTE far *pic, int x, int y)
- {
- UBYTE byte;
- UBYTE far *mem_addr;
-
-
- mem_addr = pic + (y&0x01)*0x2000;
-
- byte = *(mem_addr + ((y & 0xFE)>>1)*0x50 + x/4);
-
- return((byte >> ((3-(x&0x03))<<1))&0x03);
- }
-
-
-
- /*
- * put_pixel() - Write a pixel to the EGA video buffer
- */
- void put_pixel(int x, int y, UBYTE color)
- {
- ULONG off;
- UBYTE far *mem_addr;
- int dummy, mask;
-
-
- off = (LONG)y * 40L + ((LONG)x / 8L);
-
- mem_addr = (UBYTE far *)(0xA0000000L + off);
-
- mask = 0x80 >> (x % 8);
-
- graph_out(8, mask);
- graph_out(3, 0x00);
-
- seq_out(2, 0x0F);
-
- dummy = *mem_addr;
-
- *mem_addr = 0;
-
- seq_out(2, color);
-
- *mem_addr = 0xFF;
-
- seq_out(2, 0x0F);
-
- graph_out(3, 0x00);
- graph_out(8, 0xFF);
- }
-
-
-
- /*
- * rd_byte() - Read a byte from the EGA screen, given the address of
- * the byte and the color plane to read from.
- */
- UBYTE rd_byte(ULONG addr, WORD clr_plane)
- {
- UBYTE far *mem_addr;
- UBYTE pixel;
-
-
- mem_addr = (UBYTE far *)(0xA0000000L + addr);
-
- outp(0x3CE, 4);
- outp(0x3CF, clr_plane);
-
- outp(0x3CE, 5);
- outp(0x3CF, 0);
-
- pixel = *mem_addr;
-
- return pixel;
- }
-
-
-
- /*
- * farload_pic() - Load a BLOAD image into a buffer in RAM.
- * Return a pointer to the buffer.
- */
- UBYTE far *farload_pic(const char *file_name)
- {
- FILE *fp;
- UBYTE far *buffer, *tbuff;
- ULONG fsize;
-
-
- if((fp = fopen(file_name,"rb")) == NULL)
- {
- printf("\nCan't find %s.\n",file_name);
- return(0);
- }
-
- fsize = filelength(fileno(fp)) - 7;
-
- buffer = (UBYTE far *)farcalloc(fsize, 1);
-
- tbuff = (UBYTE *)calloc((int)fsize, 1);
-
- fread((void *)tbuff, 1, 7, fp);
-
- fread((void *)tbuff, 1, (int)fsize, fp);
-
- movedata(FP_SEG(tbuff ), FP_OFF(tbuff ),
- FP_SEG(buffer), FP_OFF(buffer), (int)fsize);
-
- fclose(fp);
-
- free((void *)tbuff);
-
- return(buffer);
- }
-
-
-
- /*
- * save_pcx() - Save the image on EGA page 0 to a .PCX file, using
- * the default EGA palette
- */
- void save_pcx(const char *fname)
- {
- FILE *fp;
- UBYTE ch, old_ch, red, green, blue;
- int i, j, k, add1, add2, number, num_out;
- UBYTE color[16] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
- };
-
-
- if((fp = fopen(fname, "wb")) == NULL)
- {
- printf("ERROR: failure to save %s.PCX\n", fname);
- return;
- }
-
- /* Write out the standard ZSoft .PCX file header: */
-
- fputc(0x0A, fp); /* Byte 0: 0x0A = ZSoft .PCX file */
- fputc(0x05, fp); /* Byte 1: 0x05 = PC Paintbrush v3.0 */
-
- fputc(0x01, fp); /* Byte 2: 0x01 = .PCX RLE coding */
- fputc(0x01, fp); /* Byte 3: number of bits/pixel (1) */
-
- putw( 0, fp); /* Bytes 4 - 5: window left */
- putw( 0, fp); /* Bytes 6 - 7: window top */
- putw(319, fp); /* Bytes 8 - 9: window right */
- putw(199, fp); /* Bytes 10 - 11: window bottom */
-
- putw(320, fp); /* Bytes 12 - 13: Horizontal resolution */
- putw(200, fp); /* Bytes 14 - 15: Vertical resolution */
-
- ch = 0x00;
-
- /*
- * Bytes 16 - 63: Color Map. This consists of 16 consecutive blocks
- * of 3 bytes each: Redbyte, Greenbyte, Bluebyte.
- */
-
- for(i=0 ; i<16 ; i++)
- {
- red = (((color[i] & 0x20)>>5) | ((color[i] & 0x04)>>1)) * 85;
- green = (((color[i] & 0x10)>>4) | (color[i] & 0x02) ) * 85;
- blue = (((color[i] & 0x08)>>3) | ((color[i] & 0x01)<<1)) * 85;
-
- fputc(red , fp);
- fputc(green, fp);
- fputc(blue , fp);
- }
-
- fputc(0x00, fp); /* Byte 64: Reserved */
- fputc(0x04, fp); /* Byte 65: Number of planes (4) */
-
- putw(40, fp); /* Bytes 66-67: Bytes per line */
-
- putw(0x01, fp); /* Bytes 68-69: 1 = color palette */
-
- for(i=70 ; i<128 ; i++) /* Bytes 70 - 127 are unused */
- fputc(0x00, fp);
-
- for(k=0 ; k<200 ; k++)
- {
- add1 = 40 * k;
- add2 = 0;
- number = 1;
- j = 0;
- old_ch = rd_byte(add1+(add2++), 0);
-
- for(i=add2 ; i<161 ; i++)
- {
- if(i == 160)
- ch = old_ch-1;
- else
- {
- if(add2 == 40)
- {
- j++;
- add2 = 0;
- }
-
- ch = rd_byte(add1 + add2, j);
- }
-
- if((ch==old_ch) && number<63)
- number++;
- else
- {
- num_out = ((UBYTE)number | 0xC0);
-
- if((number != 1) || ((old_ch&0xC0)==0xC0))
- fputc(num_out, fp);
-
- fputc(old_ch, fp);
-
- old_ch = ch;
- number = 1;
- }
-
- add2++;
- }
- }
-
- fclose(fp);
- }
-
-
-
-
- /* MAIN */
-
- void main(int argc, char *argv[])
- {
- int x, y;
- char fin[MAXPATH], fout[MAXPATH];
- UBYTE far *picbuf; /* image buffer */
- UBYTE ega_color[4] = { 0, 11, 13, 15 }; /* EGA pos for CGA pal 0 */
-
-
- if(argc==1 || argc>3)
- {
- printf("Usage: bas2pcx <infile> [outfile]\n\n");
- printf("Where: <infile> = BLOAD image to load (.PIC extension default)\n");
- printf(" [outfile] = .PCX file generated. If not specified\n");
- printf(" input filename is used, with .PCX added.\n");
- exit(0);
- }
-
- get_parms(argc, argv, fin, fout);
-
- if((picbuf = farload_pic(fin)) == NULL)
- exit(-1);
-
- mode(EGA_320_200_16);
-
- for(y=0 ; y<200 ; y++)
- for(x=0 ; x<320 ; x++)
- put_pixel(x, y, ega_color[get_pixel(picbuf, x, y)]);
-
- putch(7);
-
- farfree((void far *)picbuf);
-
- save_pcx(fout);
-
- putch(7);
-
- getch();
-
- mode(0x03);
- }
-