home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
cad
/
pcb.arc
/
PCBVIEW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-05
|
15KB
|
485 lines
/*
** printed circuit board displayer, Copyright (C) Randy Nevin 1989.
**
** 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 in good faith 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. this code is available directly from
** the author; just send a floppy and a self-addressed floppy mailer with
**
** HISTORY
** (name date description)
** ----------------------------------------------------
** randy nevin 2/1/89 initial version
** randy nevin 2/11/89 released version 1.00
*/
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <conio.h>
#include <string.h>
#include <dos.h>
/* #include <signal.h> enable this to catch ^C */
#include "cell.h"
/*
** ^C handling is disabled because on my system enabling it seems to interfere
** with int 10h processing, which is needed to plot pixels. you should enable
** it and see what happens on your system.
*/
/* 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 */
/* board dimensions */
extern int Nrows;
extern int Ncols;
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 control_C( void ); enable this to catch ^C */
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. Version 1.00\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;
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 | (((long)i2) << 8)
| (((long)i3) << 16) | (((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 | (((long)i2) << 8)
| (((long)i3) << 16) | (((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 */
/* signal( SIGINT, control_C ); enable this to catch ^C */
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 */
}
}
/*
** enable this to catch ^C
**
**static void control_C () { / * handle ^C * /
** SetMode( mode ); / * restore original screen mode * /
** exit( 0 );
** }
*/
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 );
}