home *** CD-ROM | disk | FTP | other *** search
- /*
- * A2B.C -- Program to convert Apple// Hi-Res Screen Dumps to
- * 320x200x4 .PIC format IBM graphics files. The result is an
- * IBM memory map (i.e., a BASIC BLOAD picture).
- *
- * Program assumes that the input file is an uncompressed
- * 280x192 color picture (Apple// HGR memory BSAVE) that
- * has already been ported to the IBM environment.
- *
- * Usage: a2i <applefile> [WAIT]
- *
- * If no extension is given, an extension of .RAW is assumed.
- * Output file generated uses same name as input file, with
- * a .PIC extension.
- *
- * If you add "WAIT" to the command line (or anything really,
- * as all I check for is a 2nd parameter) the program will beep
- * and wait for a keypress before exiting. Leaving this off the
- * command line makes the program work from a batch file for
- * multiple conversions.
- */
-
- /* INCLUDES */
-
- #include <stdio.h>
- #include <process.h>
- #include <dir.h>
- #include <conio.h>
- #include <dos.h>
-
- #include "cga.h"
-
-
-
-
- /* DEFINES */
-
- #define ERROR -1
- #define A_OK 0
-
- /*
- * The following are the color equivalents in the CGA pallette that
- * closely (relatively) approximate the Apple screen colors. This
- * program example thinks in the cyan/magenta/white pallette, but can
- * easily be adapted to the green/red/yellow.
- */
-
- #define _A_BLACK 0
-
- #define _A_VIOLET _RED
- #define _A_GREEN _BLUE
- #define _A_BLUE _BLUE
- #define _A_ORANGE _RED
- #define _A_WHITE _WHITE
-
-
-
-
- /* GLOBALS */
-
- UBYTE apple_memory[192][40]; /* Apple "memory" map */
-
- int apple_lines[8][3] = {
- { 0, 64, 128 },
- { 8, 72, 136 },
- { 16, 80, 144 },
- { 24, 88, 152 },
- { 32, 96, 160 },
- { 40, 104, 168 },
- { 48, 112, 176 },
- { 56, 120, 184 }
- }; /* Index table for Apple memory */
-
- /*
- * The Apple HGR screen is wonderfully convoluted (in several ways). For
- * instance, the color of a particular pixel on the Apple screen depends
- * upon THREE (3) things:
- *
- * 1) Is the Apple screen byte an EVEN or ODD byte on the scanline?
- * 2) Is the MSB of the screen byte SET?
- * 3) Is the pixel/bit in question on an EVEN or ODD column?
- *
- * Pretty confusing, huh? a2i_colors[][][] handles this as follows:
- *
- * Pixel_color = a2i_colors[EVEN/ODD byte?][MSB SET?][EVEN/ODD column?]
- */
-
- int a2i_colors[2][2][2] = {
- { /* EVEN byte */
- { _A_VIOLET, _A_GREEN }, /* MSB not set */
- { _A_BLUE , _A_ORANGE } /* MSB set */
- },
- { /* ODD byte */
- { _A_GREEN , _A_VIOLET }, /* MSB not set */
- { _A_ORANGE, _A_BLUE } /* MSB set */
- }
- };
-
-
-
-
- /* FUNCTIONS */
-
- /*
- * load_apple_raw() -- Take a raw BSAVE file and load it into the temporary
- * memory buffer. This routine unscrambles Apple's
- * memory mapping at the same time, so that the buffer
- * becomes consecutive, as opposed to Apple's convoluted
- * skipping from block to block.
- */
- int load_apple_raw(const char *fname)
- {
- int i, vline, block, mline = 0;
- FILE *fsave;
-
-
- if((fsave = fopen(fname, "rb")) == NULL)
- return ERROR;
-
- rewind(fsave);
-
- /*
- * Even though we're dealing with Apple graphics, the screen map is still
- * heavily tied to the text screen layout. Apple's HGR screen is divided
- * into 24 "blocks" of 8 lines per block (the main reason why when you do
- * a BLOAD to the HGR screen, you get the infamous "venetian blind" load.
- * Unfortunately, we end up stepping through memory (scanline-wise) as
- * follows:
- *
- * 0, 64, 128, 8, 72, 136, ..., 184, 1, 65, 129, ...
- *
- * (i.e. line 0 is the first line of the file, line 1 is the 25th line of
- * the file...wonderful, right?)
- *
- * If that isn't enough, every there are an additional 8 bytes of garbage
- * space every 3 scanlines (reminiscent of IBM's CGA architecture).
- *
- * The easiest way I found to handle this is to create the apple_lines[][]
- * table of base scanlines and index off of them.
- */
-
- for(block=0;block<8;block++)
- for(mline=0;mline<24;mline++)
- {
- vline = apple_lines[mline / 3][mline % 3] + block;
-
- for(i=0;i<40;i++)
- apple_memory[vline][i] = fgetc(fsave);
-
- if((mline % 3) == 2)
- for(i=0;i<8;i++)
- fgetc(fsave);
- }
-
- fclose(fsave);
-
- return A_OK;
- }
-
-
-
- /*
- * apple_2_ibm() -- Take the "Apple map" image in the apple_memory[][]
- * array and translate it into an CGA mode 4 image on
- * the display. xoff and yoff are pixel offsets on the
- * CGA screen that result in the Apple image (280x192)
- * being displayed dead center on the CGA screen (320x200).
- */
- void apple_2_ibm(void)
- {
- int xoff = 20, yoff = 4;
- int i, j, k, which, line[280];
- UBYTE abyte, abit;
-
-
- for(i=0;i<192;i++) /* 192 lines in an Apple HGR screen */
- {
-
- /*
- * The first thing we do is convert an Apple scanline to a CGA scanline,
- * meaning that we must decode each Apple byte (7 pixels per byte) into
- * CGA pixels. line[] is the line buffer, each index holding one pixel's
- * color value.
- */
-
- for(j=0;j<40;j++) /* 280 pixels/line = 40 Apple bytes */
- {
- abyte = apple_memory[i][j]; /* Get an Apple byte */
-
- which = (abyte & 0x80) == 0x80; /* Which Apple color scheme? */
-
- /*
- * Now, cycle through the Apple byte one pixel at a time. Since Apple
- * bytes are encoded "backwards" to IBM screenlines, the least significant
- * bit of the Apple byte is the far right pixel of the IBM byte.
- * Therefore, the decompression process works as follows:
- *
- * 1) Grab LSB of Apple byte.
- * 2) Set equivalent EGA pixel to correct Apple color (remember, Apple
- * colors depend upon: A) whether the pixel is in an even or odd
- * column (on the Apple screen), and B) whether the high bit of the
- * Apple byte is set or not.
- * 3) Shift Apple byte right one bit.
- * 4) Repeat steps 1-3 for remaining 6 pixels in Apple byte
- */
-
- for(k=0;k<7;k++) /* 7 pixels per Apple byte */
- {
- abit = abyte & 0x01;
-
- line[j*7 + k] = a2i_colors[j % 2][which][k % 2] * abit;
-
- abyte >>= 1;
- }
- }
-
- /*
- * Now that we've built a CGA screen line, write it out to screen memory.
- * The actual color displayed on the Apple screen depends not only on
- * whether a given pixel is set or not, but also on whether adjacent
- * pixels are set (if two adjacent pixels are on, the resulting color is
- * WHITE, *not* the individual pixel colors). The algorithm is:
- *
- * IF (current pixel first on scanline)
- * Check the next pixel
- * IF (both pixels aren't black)
- * Write out a white pixel
- * ELSE
- * Write out the color of the first pixel
- * ELSE IF (current pixel last on scanline)
- * Check the previous pixel
- * IF (both pixels aren't black)
- * Write out white pixel
- * ELSE
- * Write out the color of the last pixel
- * ELSE
- * IF (current pixel not black) AND (previous OR next pixel not black)
- * Write out a white pixel
- * ELSE IF (current pixel black) AND (previous pixel same color as
- * next pixel)
- * Write out color of previous pixel
- * ELSE
- * Write out color of current pixel
- *
- * The convoluted part of the algorithm (the last part of the main IF
- * structure) is because 2 ON pixels with 1 OFF pixel between them on
- * the Apple screen are seen as a solid color (no gaps).
- */
-
- for(k=0;k<280;k++)
- {
- if(k == 0)
- {
- if(line[k]!=_A_BLACK && line[k+1]!=_A_BLACK)
- put_pixel(k + xoff, i + yoff, _A_WHITE);
- else
- put_pixel(k + xoff, i + yoff, line[k] );
- }
- else
- if(k == 279)
- {
- if(line[k]!=_A_BLACK && line[k-1]!=_A_BLACK)
- put_pixel(k + xoff, i + yoff, _A_WHITE);
- else
- put_pixel(k + xoff, i + yoff, line[k] );
- }
- else
- {
- if(line[k]!=_A_BLACK && (line[k-1]!=_A_BLACK || line[k+1]!=_A_BLACK))
- put_pixel(k + xoff, i + yoff, _A_WHITE );
- else
- if(line[k]==_A_BLACK && line[k-1]==line[k+1])
- put_pixel(k + xoff, i + yoff, line[k-1]);
- else
- put_pixel(k + xoff, i + yoff, line[k] );
- }
- }
- }
- }
-
-
-
-
- /* MAIN */
-
- void main(int argc, char **argv)
- {
- char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
- char infile[13], outfile[13];
-
-
- if(argc == 1)
- {
- printf("Usage: a2b <applefile> [WAIT]\n");
- exit(0);
- }
-
- init_cgfx(0x04); /* Initialize CGA mode 4 */
- fnsplit(argv[1], drive, dir, file, ext);
-
- if(ext[0] == '\0')
- fnmerge(infile, "", "", file, ".RAW");
- else
- fnmerge(infile, "", "", file, ext );
-
- fnmerge(outfile, "", "", file, ".PIC");
-
- gotoxy(12, 10); printf("Loading...");
-
- if(load_apple_raw(infile) != ERROR)
- {
- gotoxy(12, 10); printf("Converting...");
-
- apple_2_ibm();
-
- sleep(2);
-
- save_pic(outfile);
-
- cls();
-
- fload_pic(outfile);
-
- if(argc == 3)
- {
- putch(7);
-
- getch();
- }
- }
- else
- printf("Error...");
-
- mode(3);
- }
-