home *** CD-ROM | disk | FTP | other *** search
- /*
- ** printed circuit board displayer, Copyright (C) Randy Nevin 1989, 1990.
- **
- ** you may give this software to anyone, make as many copies as you like, and
- ** post it on public computer bulletin boards and file servers. you may not
- ** sell it or charge any fee for distribution (except for media and postage),
- ** remove this comment or the copyright notice from the code, or claim that
- ** you wrote this code or anything derived from it. you may modify the code as
- ** much as you want (please document clearly with comments, and maintain the
- ** coding style), but programs which are derived from this one are subject to
- ** the conditions stated here. i am providing this code so that people can
- ** learn from it, so if you distribute it, please include source code, not
- ** just executables. contact me to report bugs or suggest enhancements; i do
- ** not guarantee support, but i will make an effort to help you, and i want to
- ** act as a central clearing house for future versions. you should contact me
- ** before undertaking a significant development effort, to avoid reinventing
- ** the wheel. if you come up with an enhancement you consider particularly
- ** useful, i would appreciate being informed so that it can be incorporated in
- ** future versions. my address is: Randy Nevin, 1731 211th PL NE, Redmond,
- ** WA 98053, USA. this code is available directly from the author; just send a
- ** 360k floppy and a self-addressed floppy mailer with sufficient postage.
- **
- ** HISTORY
- ** (name date description)
- ** ----------------------------------------------------
- ** randy nevin 2/1/89 initial version
- ** randy nevin 2/11/89 released version 1.00
- ** randy nevin 12/27/89 fixed graphics dot-drawing bugs
- ** randy nevin 12/27/89 released version 1.10
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <io.h>
- #include <conio.h>
- #include <string.h>
- #include <dos.h>
- #include "cell.h"
-
- /* WARNING: the code below assumes 640x350 16-color ega */
-
- /* 0=black 1=blue 2=green 3=light blue */
- /* 4=red 5=purple 6=brown 7=grey */
- /* 8=black 9=bright blue A=bright green B=bright light blue */
- /* C=scarlet D=purple E=yellow F=white */
-
- /*
- ** the colors below work fine for me, but may not for your particular ega and
- ** monitor. if bright blue and light blue look the same to you, or some traces
- ** appear to be missing, you may want to change these constants.
- **
- ** on some egas, there appear to be gaps in the traces; i don't know why. on
- ** other egas, the traces look fine. this happened to me on the maximum zoom,
- ** but not on any other zoom level. apparently some problem with the int 10h
- ** interface.
- */
-
- /* colors of objects */
- #define H 0xC /* hole color; scarlet */
- #define F 0x9 /* frontside trace color; bright blue */
- #define B 0x3 /* backside trace color; light blue */
- #define E 0xE /* edge color; yellow */
-
- /* screen limits */
- #define MINHORZ 0 /* left-most pixel */
- #define MAXHORZ 639 /* right-most pixel */
- #define MINVERT 0 /* top-most pixel */
- #define MAXVERT 349 /* bottom-most pixel */
-
- static int mode; /* for saving original screen mode */
- static int sides = 3; /* 0=holes only, 1=front only, 2=back only, 3=all */
-
- #define MAXZOOM 3 /* maximum zoom number; minimum is 0 */
-
- #define ZOOM0 3 /* 3x3 pixels per cell */
- #define ZOOM1 6 /* 6x6 pixels per cell */
- #define ZOOM2 10 /* 10x10 pixels per cell */
- #define ZOOM3 18 /* 18x18 pixels per cell */
-
- static int zoom = 1; /* 0=3x3, 1=6x6, 2=10x10, 3=18x18 */
- static int zoomsize[MAXZOOM+1] = { ZOOM0, ZOOM1, ZOOM2, ZOOM3 };
-
- /* current lower-left position */
- static int Xrow = 0;
- static int Xcol = 0;
-
- int JustBoard = 1; /* only need the board data structure */
-
- extern int Nrows, Ncols; /* board dimensions */
-
- extern void InitBoard( void );
- extern long GetCell( int, int, int );
- extern void SetCell( int, int, int, long );
- extern int GetMode( void );
- extern void SetMode( int );
- extern void Dot( int, int, int );
-
- void main( int, char *[] );
- static void doedges( void );
- static void doboard( void );
- static void map( int, int, long, long );
- static void plot0( int, int, char [ZOOM0][ZOOM0], int );
- static void plot1( int, int, char [ZOOM1][ZOOM1], int );
- static void plot2( int, int, char [ZOOM2][ZOOM2], int );
- static void plot3( int, int, char [ZOOM3][ZOOM3], int );
-
- void main ( argc, argv ) /* input routed board, display it on the screen */
- int argc;
- char *argv[];
- {
- char *self, *p;
- int r, c, rp, cp, i1, i2, i3, i4;
- FILE *fp;
- long x;
- union REGS regs;
-
- printf( "Copyright (C) Randy Nevin, 1989, 1990. Version 1.10\n" );
- printf( "See source code for rights granted.\n\n" );
- self = argv[0];
- /* get rid of initial part of path */
- if ((p = strrchr( self, '\\' )) || (p = strrchr( self, ':' )))
- self = ++p;
- /* get rid of extension */
- if ((p = strrchr( self, '.' )) && !stricmp( p, ".EXE" ))
- *p = 0;
- if (argc != 2) { /* need infile */
- fprintf( stderr, "usage: %s infile\n", self );
- exit( -1 );
- }
- if (!(fp = fopen( argv[1], "rb" ))) {
- fprintf( stderr, "can't open %s\n", argv[1] );
- exit( -1 );
- }
- /* fetch the board dimensions */
- if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
- fprintf( stderr, "premature eof\n" );
- exit( -1 );
- }
- Nrows = (rp & 0xFF) | ((cp << 8) & 0xFF00);
- if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
- fprintf( stderr, "premature eof\n" );
- exit( -1 );
- }
- Ncols = (rp & 0xFF) | ((cp << 8) & 0xFF00);
- InitBoard(); /* allocate memory for data structures */
- for (r = 0; r < Nrows; r++) { /* read in the board, row by column */
- for (c = 0; c < Ncols; c++) {
- /* first, do frontside */
- if ((i1 = getc( fp )) == EOF
- || (i2 = getc( fp )) == EOF
- || (i3 = getc( fp )) == EOF
- || (i4 = getc( fp )) == EOF) {
- fprintf( stderr, "premature eof\n" );
- exit( -1 );
- }
- x = (long)i1;
- x |= (((long)i2) << 8);
- x |= (((long)i3) << 16);
- x |= (((long)i4) << 24);
- SetCell( r, c, TOP, x );
- /* then do backside */
- if ((i1 = getc( fp )) == EOF
- || (i2 = getc( fp )) == EOF
- || (i3 = getc( fp )) == EOF
- || (i4 = getc( fp )) == EOF) {
- fprintf( stderr, "premature eof\n" );
- exit( -1 );
- }
- x = (long)i1;
- x |= (((long)i2) << 8);
- x |= (((long)i3) << 16);
- x |= (((long)i4) << 24);
- SetCell( r, c, BOTTOM, x );
- }
- }
- /* tell user what commands are available */
- printf( "\t0 = holes only\n" );
- printf( "\t1 = holes and top traces\n" );
- printf( "\t2 = holes and bottom traces\n" );
- printf( "\t3 = holes and all traces\n" );
- printf( "\tz/Z = zoom one level / maximum zoom\n" );
- printf( "\ts/S = shrink one level / minimum shrink\n" );
- printf( "\tl/L = move left by one / move left by ten\n" );
- printf( "\tr/R = move right by one / move right by ten\n" );
- printf( "\tu/U = move up by one / move up by ten\n" );
- printf( "\td/D = move down by one / move down by ten\n" );
- printf( "\tany other key exits the program\n" );
- printf( "\nPress ENTER to continue, or ^C to exit " );
- regs.h.ah = 0x8; /* character input without echo */
- intdos( ®s, ®s ); /* call dos to get a keystroke */
- mode = GetMode(); /* save mode so can restore later */
- SetMode( 0x10 ); /* 640x350 16-color mode */
- doedges(); /* display board edges */
- doboard(); /* display the board */
- for (;;) { /* process until unrecognized keystroke */
- regs.h.ah = 0x8; /* character input without echo */
- intdos( ®s, ®s ); /* call dos to get a keystroke */
- switch (regs.h.al) { /* determine what it is */
- case '0': /* just show holes */
- if (sides == 0)
- continue;
- sides = 0;
- break;
- case '1': /* show holes and top-side traces */
- if (sides == 1)
- continue;
- sides = 1;
- break;
- case '2': /* show holes and bottom-side traces */
- if (sides == 2)
- continue;
- sides = 2;
- break;
- case '3': /* show holes and all traces */
- if (sides == 3)
- continue;
- sides = 3;
- break;
- case 'Z': /* zoom to the limit */
- if (zoom == MAXZOOM)
- continue;
- zoom = MAXZOOM;
- break;
- case 'z': /* zoom by one */
- if (zoom == MAXZOOM)
- continue;
- zoom++;
- break;
- case 'S': /* shrink to the limit */
- if (zoom == 0)
- continue;
- zoom = 0;
- break;
- case 's': /* shrink by one */
- if (zoom == 0)
- continue;
- zoom--;
- break;
- case 'L': /* left by 10 */
- if (Xcol == 0)
- continue;
- if (Xcol <= 10)
- Xcol = 0;
- else
- Xcol -= 10;
- break;
- case 'l': /* left by one */
- if (Xcol == 0)
- continue;
- Xcol--;
- break;
- case 'R': /* right by 10 */
- if (Xcol == Ncols-1)
- continue;
- if (Xcol >= Ncols-11)
- Xcol = Ncols-1;
- else
- Xcol += 10;
- break;
- case 'r': /* right by one */
- if (Xcol == Ncols-1)
- continue;
- Xcol++;
- break;
- case 'U': /* up by 10 */
- if (Xrow == Nrows-1)
- continue;
- if (Xrow >= Nrows-11)
- Xrow = Nrows-1;
- else
- Xrow += 10;
- break;
- case 'u': /* up by one */
- if (Xrow == Nrows-1)
- continue;
- Xrow++;
- break;
- case 'D': /* down by 10 */
- if (Xrow == 0)
- continue;
- if (Xrow <= 10)
- Xrow = 0;
- else
- Xrow -= 10;
- break;
- case 'd': /* down by one */
- if (Xrow == 0)
- continue;
- Xrow--;
- break;
- default:
- SetMode( mode ); /* restore original screen mode */
- exit( 0 );
- break;
- }
- SetMode( 0x10 ); /* clear screen */
- doedges(); /* display board edges */
- doboard(); /* display the board */
- }
- }
-
- static void doedges () { /* display the board edges */
- int r1, c1, r2, c2, i, z;
-
- z = zoomsize[zoom];
- /* first, calculate their virtual screen positions */
- r1 = MAXVERT+(Xrow*z); /* bottom edge */
- c1 = MINHORZ-(Xcol*z); /* left edge */
- r2 = MAXVERT-1-((Nrows-Xrow)*z); /* top edge */
- c2 = MINHORZ+1+((Ncols-Xcol)*z); /* right edge */
- if (r1 >= MINVERT && r1 <= MAXVERT) /* draw bottom edge */
- for (i = c1; i <= c2; i++)
- if (i >= MINHORZ && i <= MAXHORZ)
- Dot( E, r1, i );
- if (c1 >= MINHORZ && c1 <= MAXHORZ) /* draw left edge */
- for (i = r1; i >= r2; i--)
- if (i >= MINVERT && i <= MAXVERT)
- Dot( E, i, c1 );
- if (r2 >= MINVERT && r2 <= MAXVERT) /* draw top edge */
- for (i = c1; i <= c2; i++)
- if (i >= MINHORZ && i <= MAXHORZ)
- Dot( E, r2, i );
- if (c2 >= MINHORZ && c2 <= MAXHORZ) /* draw right edge */
- for (i = r1; i >= r2; i--)
- if (i >= MINVERT && i <= MAXVERT)
- Dot( E, i, c2 );
- }
-
- static void doboard () { /* display the board on the screen, row by column */
- int r, c, rp, cp, rpd, cpd, z;
- long x, y;
-
- z = zoomsize[zoom];
- rpd = MINVERT+z; /* top-most plottable row */
- cpd = MAXHORZ-z; /* right-most plottable column */
- for (r = Xrow, rp = MAXVERT-1; r < Nrows && rp >= rpd; r++, rp -= z) {
- for (c = Xcol, cp = MINHORZ+1; c < Ncols && cp <= cpd;
- c++, cp += z) {
- x = GetCell( r, c, TOP );
- y = GetCell( r, c, BOTTOM );
- if (x || y) /* only map if something is there */
- map( rp, cp, x, y );
- }
- }
- }
-
- struct x { /* group the bit templates for an object */
- long t; /* the object type */
- char t0[ZOOM0][ZOOM0]; /* tiny zoom template */
- char t1[ZOOM1][ZOOM1]; /* small zoom template */
- char t2[ZOOM2][ZOOM2]; /* medium zoom template */
- char t3[ZOOM3][ZOOM3]; /* large zoom template */
- };
-
- extern struct x y1[]; /* hole templates */
- extern struct x y2[]; /* hole-related templates */
- extern struct x y3[]; /* non-hole-related templates */
-
- extern int z1; /* number of hole types */
- extern int z2; /* number of hole-related types */
- extern int z3; /* number of non-hole-related types */
-
- #define domap1(v,c) { for (i = 0; i < z1; i++) { \
- if (v & (y1[i].t)) { \
- if (zoom == 0) \
- plot0( rp, cp, y1[i].t0, c );\
- else if (zoom == 1) \
- plot1( rp, cp, y1[i].t1, c );\
- else if (zoom == 2) \
- plot2( rp, cp, y1[i].t2, c );\
- else if (zoom == 3) \
- plot3( rp, cp, y1[i].t3, c );\
- } \
- } } \
-
- #define domap2(v,c) { for (i = 0; i < z2; i++) { \
- if (v & (y2[i].t)) { \
- if (zoom == 0) \
- plot0( rp, cp, y2[i].t0, c );\
- else if (zoom == 1) \
- plot1( rp, cp, y2[i].t1, c );\
- else if (zoom == 2) \
- plot2( rp, cp, y2[i].t2, c );\
- else if (zoom == 3) \
- plot3( rp, cp, y2[i].t3, c );\
- } \
- } } \
-
- #define domap3(v,c) { for (i = 0; i < z3; i++) { \
- if (v & (y3[i].t)) { \
- if (zoom == 0) \
- plot0( rp, cp, y3[i].t0, c );\
- else if (zoom == 1) \
- plot1( rp, cp, y3[i].t1, c );\
- else if (zoom == 2) \
- plot2( rp, cp, y3[i].t2, c );\
- else if (zoom == 3) \
- plot3( rp, cp, y3[i].t3, c );\
- } \
- } } \
-
- static void map ( rp, cp, v0, v1 ) /* map a cell */
- int rp, cp;
- long v0, v1;
- {
- int i;
-
- if (v0 & HOLE) {
- domap1( v0, H ); /* plot the hole */
- if (v1 && (sides & 2)) /* plot backside? */
- domap2( v1, B );
- if (v0 && (sides & 1)) /* plot frontside? */
- domap2( v0, F );
- }
- else {
- if (v1 && (sides & 2)) /* plot backside? */
- domap3( v1, B );
- if (v0 && (sides & 1)) /* plot frontside? */
- domap3( v0, F );
- }
- }
-
- static void plot0 ( rp, cp, obj, color ) /* plot a 3x3 template */
- int rp, cp;
- char obj[ZOOM0][ZOOM0];
- int color;
- {
- int r, c;
-
- for (r = 0; r < ZOOM0; r++)
- for (c = 0; c < ZOOM0; c++)
- if (obj[r][c])
- Dot( color, rp-r, cp+c );
- }
-
- static void plot1 ( rp, cp, obj, color ) /* plot a 6x6 template */
- int rp, cp;
- char obj[ZOOM1][ZOOM1];
- int color;
- {
- int r, c;
-
- for (r = 0; r < ZOOM1; r++)
- for (c = 0; c < ZOOM1; c++)
- if (obj[r][c])
- Dot( color, rp-r, cp+c );
- }
-
- static void plot2 ( rp, cp, obj, color ) /* plot a 10x10 template */
- int rp, cp;
- char obj[ZOOM2][ZOOM2];
- int color;
- {
- int r, c;
-
- for (r = 0; r < ZOOM2; r++)
- for (c = 0; c < ZOOM2; c++)
- if (obj[r][c])
- Dot( color, rp-r, cp+c );
- }
-
- static void plot3 ( rp, cp, obj, color ) /* plot an 18x18 template */
- int rp, cp;
- char obj[ZOOM3][ZOOM3];
- int color;
- {
- int r, c;
-
- for (r = 0; r < ZOOM3; r++)
- for (c = 0; c < ZOOM3; c++)
- if (obj[r][c])
- Dot( color, rp-r, cp+c );
- }
-