home *** CD-ROM | disk | FTP | other *** search
- /*
- ** printed circuit board rat nester, 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 5/7/89 initial version
- ** randy nevin 5/7/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 <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 things don't look right, you may want to change these
- ** constants.
- */
-
- /* colors of objects */
- #define H 0xC /* hole color; scarlet */
- #define T 0x9 /* trace color; bright 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 */
-
- #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;
-
- extern int Nrows, Ncols; /* board dimensions */
-
- int JustBoard = 1; /* only need the board data structure */
- int SortConnects = 0; /* default is to not sort non-PRIORITY CONNECTs */
-
- extern int Initialize( char *, int );
- extern void ReInitWork( void );
- extern void GetWork( int *, int *, char far * far *, int *, int *,
- char far * far * );
- extern long GetCell( int, int, int );
- extern int GetMode( void );
- extern void SetMode( int );
- extern void Line( int, int, int, int, int );
- extern void Dot( int, int, int );
-
- void main( int, char *[] );
- static void doedges( void );
- static void doboard( void );
- 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 board, display rat nest on the screen */
- int argc;
- char *argv[];
- {
- char *self, *p;
- union REGS regs;
- int i;
-
- 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 );
- }
- i = Initialize( argv[1], 0 ); /* don't echo memory used */
- /* tell user what commands are available */
- 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 '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 );
- }
-
- 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 int z1; /* number of hole types */
-
- #define domap(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 );\
- } \
- } }
-
- static void doboard () { /* display the board on the screen, row by column */
- int r, c, rp, cp, rpd, cpd, z, i;
- int r2, c2, rp2, cp2;
- char far *n;
- char far *n2;
- long x;
-
- ReInitWork();
- for (z = zoomsize[zoom], GetWork( &r, &c, &n, &r2, &c2, &n2 );
- r != ILLEGAL; GetWork( &r, &c, &n, &r2, &c2, &n2 )) {
- rp = MAXVERT - ((r-Xrow)*z + z/2 + 1);
- cp = (c-Xcol)*z + z/2 + 1;
- rp2 = MAXVERT - ((r2-Xrow)*z + z/2 + 1);
- cp2 = (c2-Xcol)*z + z/2 + 1;
- Line( rp, cp, rp2, cp2, 1 );
- }
- 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 );
- if (x & HOLE) /* only map if there is a hole */
- domap( x, H ); /* plot the hole */
- }
- }
- }
-
- 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 );
- }
-
- int GetApxDist( int, int, int, int );
-
- int GetApxDist ( r1, c1, r2, c2 ) /* calculate approximate distance - stub */
- int r1, c1, r2, c2;
- {
- return( 0 );
- }
-