home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / tech / pcbsrcs2 / pcbview.c < prev    next >
C/C++ Source or Header  |  1991-02-07  |  14KB  |  474 lines

  1. /*
  2. ** printed circuit board displayer, Copyright (C) Randy Nevin 1989, 1990.
  3. **
  4. ** you may give this software to anyone, make as many copies as you like, and
  5. ** post it on public computer bulletin boards and file servers. you may not
  6. ** sell it or charge any fee for distribution (except for media and postage),
  7. ** remove this comment or the copyright notice from the code, or claim that
  8. ** you wrote this code or anything derived from it. you may modify the code as
  9. ** much as you want (please document clearly with comments, and maintain the
  10. ** coding style), but programs which are derived from this one are subject to
  11. ** the conditions stated here. i am providing this code so that people can
  12. ** learn from it, so if you distribute it, please include source code, not
  13. ** just executables. contact me to report bugs or suggest enhancements; i do
  14. ** not guarantee support, but i will make an effort to help you, and i want to
  15. ** act as a central clearing house for future versions. you should contact me
  16. ** before undertaking a significant development effort, to avoid reinventing
  17. ** the wheel. if you come up with an enhancement you consider particularly
  18. ** useful, i would appreciate being informed so that it can be incorporated in
  19. ** future versions. my address is: Randy Nevin, 1731 211th PL NE, Redmond,
  20. ** WA 98053, USA. this code is available directly from the author; just send a
  21. ** 360k floppy and a self-addressed floppy mailer with sufficient postage.
  22. **
  23. ** HISTORY
  24. ** (name        date        description)
  25. ** ----------------------------------------------------
  26. ** randy nevin        2/1/89        initial version
  27. ** randy nevin        2/11/89        released version 1.00
  28. ** randy nevin        12/27/89    fixed graphics dot-drawing bugs
  29. ** randy nevin        12/27/89    released version 1.10
  30. */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <io.h>
  35. #include <conio.h>
  36. #include <string.h>
  37. #include <dos.h>
  38. #include "cell.h"
  39.  
  40. /* WARNING: the code below assumes 640x350 16-color ega */
  41.  
  42. /* 0=black    1=blue        2=green        3=light blue        */
  43. /* 4=red    5=purple    6=brown        7=grey            */
  44. /* 8=black    9=bright blue    A=bright green    B=bright light blue    */
  45. /* C=scarlet    D=purple    E=yellow    F=white            */
  46.  
  47. /*
  48. ** the colors below work fine for me, but may not for your particular ega and
  49. ** monitor. if bright blue and light blue look the same to you, or some traces
  50. ** appear to be missing, you may want to change these constants.
  51. **
  52. ** on some egas, there appear to be gaps in the traces; i don't know why. on
  53. ** other egas, the traces look fine. this happened to me on the maximum zoom,
  54. ** but not on any other zoom level. apparently some problem with the int 10h
  55. ** interface.
  56. */
  57.  
  58. /* colors of objects */
  59. #define H    0xC    /* hole color; scarlet            */
  60. #define F    0x9    /* frontside trace color; bright blue    */
  61. #define B    0x3    /* backside trace color; light blue    */
  62. #define E    0xE    /* edge color; yellow            */
  63.  
  64. /* screen limits */
  65. #define MINHORZ    0    /* left-most pixel    */
  66. #define MAXHORZ    639    /* right-most pixel    */
  67. #define MINVERT    0    /* top-most pixel    */
  68. #define MAXVERT    349    /* bottom-most pixel    */
  69.  
  70. static int mode; /* for saving original screen mode */
  71. static int sides = 3; /* 0=holes only, 1=front only, 2=back only, 3=all */
  72.  
  73. #define MAXZOOM    3    /* maximum zoom number; minimum is 0 */
  74.  
  75. #define ZOOM0    3    /* 3x3 pixels per cell        */
  76. #define ZOOM1    6    /* 6x6 pixels per cell        */
  77. #define ZOOM2    10    /* 10x10 pixels per cell    */
  78. #define ZOOM3    18    /* 18x18 pixels per cell    */
  79.  
  80. static int zoom = 1; /* 0=3x3, 1=6x6, 2=10x10, 3=18x18 */
  81. static int zoomsize[MAXZOOM+1] = { ZOOM0, ZOOM1, ZOOM2, ZOOM3 };
  82.  
  83. /* current lower-left position */
  84. static int Xrow = 0;
  85. static int Xcol = 0;
  86.  
  87. int JustBoard = 1; /* only need the board data structure */
  88.  
  89. extern int Nrows, Ncols; /* board dimensions */
  90.  
  91. extern void InitBoard( void );
  92. extern long GetCell( int, int, int );
  93. extern void SetCell( int, int, int, long );
  94. extern int GetMode( void );
  95. extern void SetMode( int );
  96. extern void Dot( int, int, int );
  97.  
  98. void main( int, char *[] );
  99. static void doedges( void );
  100. static void doboard( void );
  101. static void map( int, int, long, long );
  102. static void plot0( int, int, char [ZOOM0][ZOOM0], int );
  103. static void plot1( int, int, char [ZOOM1][ZOOM1], int );
  104. static void plot2( int, int, char [ZOOM2][ZOOM2], int );
  105. static void plot3( int, int, char [ZOOM3][ZOOM3], int );
  106.  
  107. void main ( argc, argv ) /* input routed board, display it on the screen */
  108.     int argc;
  109.     char *argv[];
  110.     {
  111.     char *self, *p;
  112.     int r, c, rp, cp, i1, i2, i3, i4;
  113.     FILE *fp;
  114.     long x;
  115.     union REGS regs;
  116.  
  117.     printf( "Copyright (C) Randy Nevin, 1989, 1990. Version 1.10\n" );
  118.     printf( "See source code for rights granted.\n\n" );
  119.     self = argv[0];
  120.     /* get rid of initial part of path */
  121.     if ((p = strrchr( self, '\\' )) || (p = strrchr( self, ':' )))
  122.         self = ++p;
  123.     /* get rid of extension */
  124.     if ((p = strrchr( self, '.' )) && !stricmp( p, ".EXE" ))
  125.         *p = 0;
  126.     if (argc != 2) { /* need infile */
  127.         fprintf( stderr, "usage: %s infile\n", self );
  128.         exit( -1 );
  129.         }
  130.     if (!(fp = fopen( argv[1], "rb" ))) {
  131.         fprintf( stderr, "can't open %s\n", argv[1] );
  132.         exit( -1 );
  133.         }
  134.     /* fetch the board dimensions */
  135.     if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
  136.         fprintf( stderr, "premature eof\n" );
  137.         exit( -1 );
  138.         }
  139.     Nrows = (rp & 0xFF) | ((cp << 8) & 0xFF00);
  140.     if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
  141.         fprintf( stderr, "premature eof\n" );
  142.         exit( -1 );
  143.         }
  144.     Ncols = (rp & 0xFF) | ((cp << 8) & 0xFF00);
  145.     InitBoard(); /* allocate memory for data structures */
  146.     for (r = 0; r < Nrows; r++) { /* read in the board, row by column */
  147.         for (c = 0; c < Ncols; c++) {
  148.             /* first, do frontside */
  149.             if ((i1 = getc( fp )) == EOF
  150.                 || (i2 = getc( fp )) == EOF
  151.                 || (i3 = getc( fp )) == EOF
  152.                 || (i4 = getc( fp )) == EOF) {
  153.                 fprintf( stderr, "premature eof\n" );
  154.                 exit( -1 );
  155.                 }
  156.             x = (long)i1;
  157.             x |= (((long)i2) << 8);
  158.             x |= (((long)i3) << 16);
  159.             x |= (((long)i4) << 24);
  160.             SetCell( r, c, TOP, x );
  161.             /* then do backside */
  162.             if ((i1 = getc( fp )) == EOF
  163.                 || (i2 = getc( fp )) == EOF
  164.                 || (i3 = getc( fp )) == EOF
  165.                 || (i4 = getc( fp )) == EOF) {
  166.                 fprintf( stderr, "premature eof\n" );
  167.                 exit( -1 );
  168.                 }
  169.             x = (long)i1;
  170.             x |= (((long)i2) << 8);
  171.             x |= (((long)i3) << 16);
  172.             x |= (((long)i4) << 24);
  173.             SetCell( r, c, BOTTOM, x );
  174.             }
  175.         }
  176.     /* tell user what commands are available */
  177.     printf( "\t0   = holes only\n" );
  178.     printf( "\t1   = holes and top traces\n" );
  179.     printf( "\t2   = holes and bottom traces\n" );
  180.     printf( "\t3   = holes and all traces\n" );
  181.     printf( "\tz/Z = zoom one level / maximum zoom\n" );
  182.     printf( "\ts/S = shrink one level / minimum shrink\n" );
  183.     printf( "\tl/L = move left by one / move left by ten\n" );
  184.     printf( "\tr/R = move right by one / move right by ten\n" );
  185.     printf( "\tu/U = move up by one / move up by ten\n" );
  186.     printf( "\td/D = move down by one / move down by ten\n" );
  187.     printf( "\tany other key exits the program\n" );
  188.     printf( "\nPress ENTER to continue, or ^C to exit " );
  189.     regs.h.ah = 0x8; /* character input without echo */
  190.     intdos( ®s, ®s ); /* call dos to get a keystroke */
  191.     mode = GetMode(); /* save mode so can restore later */
  192.     SetMode( 0x10 ); /* 640x350 16-color mode */
  193.     doedges(); /* display board edges */
  194.     doboard(); /* display the board */
  195.     for (;;) { /* process until unrecognized keystroke */
  196.         regs.h.ah = 0x8; /* character input without echo */
  197.         intdos( ®s, ®s ); /* call dos to get a keystroke */
  198.         switch (regs.h.al) { /* determine what it is */
  199.         case '0': /* just show holes */
  200.             if (sides == 0)
  201.                 continue;
  202.             sides = 0;
  203.             break;
  204.         case '1': /* show holes and top-side traces */
  205.             if (sides == 1)
  206.                 continue;
  207.             sides = 1;
  208.             break;
  209.         case '2': /* show holes and bottom-side traces */
  210.             if (sides == 2)
  211.                 continue;
  212.             sides = 2;
  213.             break;
  214.         case '3': /* show holes and all traces */
  215.             if (sides == 3)
  216.                 continue;
  217.             sides = 3;
  218.             break;
  219.         case 'Z': /* zoom to the limit */
  220.             if (zoom == MAXZOOM)
  221.                 continue;
  222.             zoom = MAXZOOM;
  223.             break;
  224.         case 'z': /* zoom by one */
  225.             if (zoom == MAXZOOM)
  226.                 continue;
  227.             zoom++;
  228.             break;
  229.         case 'S': /* shrink to the limit */
  230.             if (zoom == 0)
  231.                 continue;
  232.             zoom = 0;
  233.             break;
  234.         case 's': /* shrink by one */
  235.             if (zoom == 0)
  236.                 continue;
  237.             zoom--;
  238.             break;
  239.         case 'L': /* left by 10 */
  240.             if (Xcol == 0)
  241.                 continue;
  242.             if (Xcol <= 10)
  243.                 Xcol = 0;
  244.             else
  245.                 Xcol -= 10;
  246.             break;
  247.         case 'l': /* left by one */
  248.             if (Xcol == 0)
  249.                 continue;
  250.             Xcol--;
  251.             break;
  252.         case 'R': /* right by 10 */
  253.             if (Xcol == Ncols-1)
  254.                 continue;
  255.             if (Xcol >= Ncols-11)
  256.                 Xcol = Ncols-1;
  257.             else
  258.                 Xcol += 10;
  259.             break;
  260.         case 'r': /* right by one */
  261.             if (Xcol == Ncols-1)
  262.                 continue;
  263.             Xcol++;
  264.             break;
  265.         case 'U': /* up by 10 */
  266.             if (Xrow == Nrows-1)
  267.                 continue;
  268.             if (Xrow >= Nrows-11)
  269.                 Xrow = Nrows-1;
  270.             else
  271.                 Xrow += 10;
  272.             break;
  273.         case 'u': /* up by one */
  274.             if (Xrow == Nrows-1)
  275.                 continue;
  276.             Xrow++;
  277.             break;
  278.         case 'D': /* down by 10 */
  279.             if (Xrow == 0)
  280.                 continue;
  281.             if (Xrow <= 10)
  282.                 Xrow = 0;
  283.             else
  284.                 Xrow -= 10;
  285.             break;
  286.         case 'd': /* down by one */
  287.             if (Xrow == 0)
  288.                 continue;
  289.             Xrow--;
  290.             break;
  291.         default:
  292.             SetMode( mode ); /* restore original screen mode */
  293.             exit( 0 );
  294.             break;
  295.             }
  296.         SetMode( 0x10 ); /* clear screen */
  297.         doedges(); /* display board edges */
  298.         doboard(); /* display the board */
  299.         }
  300.     }
  301.  
  302. static void doedges () { /* display the board edges */
  303.     int r1, c1, r2, c2, i, z;
  304.  
  305.     z = zoomsize[zoom];
  306.     /* first, calculate their virtual screen positions */
  307.     r1 = MAXVERT+(Xrow*z); /* bottom edge */
  308.     c1 = MINHORZ-(Xcol*z); /* left edge */
  309.     r2 = MAXVERT-1-((Nrows-Xrow)*z); /* top edge */
  310.     c2 = MINHORZ+1+((Ncols-Xcol)*z); /* right edge */
  311.     if (r1 >= MINVERT && r1 <= MAXVERT) /* draw bottom edge */
  312.         for (i = c1; i <= c2; i++)
  313.             if (i >= MINHORZ && i <= MAXHORZ)
  314.                 Dot( E, r1, i );
  315.     if (c1 >= MINHORZ && c1 <= MAXHORZ) /* draw left edge */
  316.         for (i = r1; i >= r2; i--)
  317.             if (i >= MINVERT && i <= MAXVERT)
  318.                 Dot( E, i, c1 );
  319.     if (r2 >= MINVERT && r2 <= MAXVERT) /* draw top edge */
  320.         for (i = c1; i <= c2; i++)
  321.             if (i >= MINHORZ && i <= MAXHORZ)
  322.                 Dot( E, r2, i );
  323.     if (c2 >= MINHORZ && c2 <= MAXHORZ) /* draw right edge */
  324.         for (i = r1; i >= r2; i--)
  325.             if (i >= MINVERT && i <= MAXVERT)
  326.                 Dot( E, i, c2 );
  327.     }
  328.  
  329. static void doboard () { /* display the board on the screen, row by column */
  330.     int r, c, rp, cp, rpd, cpd, z;
  331.     long x, y;
  332.  
  333.     z = zoomsize[zoom];
  334.     rpd = MINVERT+z; /* top-most plottable row */
  335.     cpd = MAXHORZ-z; /* right-most plottable column */
  336.     for (r = Xrow, rp = MAXVERT-1; r < Nrows && rp >= rpd; r++, rp -= z) {
  337.         for (c = Xcol, cp = MINHORZ+1; c < Ncols && cp <= cpd;
  338.                 c++, cp += z) {
  339.             x = GetCell( r, c, TOP );
  340.             y = GetCell( r, c, BOTTOM );
  341.             if (x || y) /* only map if something is there */
  342.                 map( rp, cp, x, y );
  343.             }
  344.         }
  345.     }
  346.  
  347. struct x { /* group the bit templates for an object */
  348.     long t;            /* the object type    */
  349.     char t0[ZOOM0][ZOOM0];    /* tiny zoom template    */
  350.     char t1[ZOOM1][ZOOM1];    /* small zoom template    */
  351.     char t2[ZOOM2][ZOOM2];    /* medium zoom template    */
  352.     char t3[ZOOM3][ZOOM3];    /* large zoom template    */
  353.     };
  354.  
  355. extern struct x y1[]; /* hole templates */
  356. extern struct x y2[]; /* hole-related templates */
  357. extern struct x y3[]; /* non-hole-related templates */
  358.  
  359. extern int z1; /* number of hole types */
  360. extern int z2; /* number of hole-related types */
  361. extern int z3; /* number of non-hole-related types */
  362.  
  363. #define domap1(v,c)    { for (i = 0; i < z1; i++) { \
  364.                 if (v & (y1[i].t)) { \
  365.                     if (zoom == 0) \
  366.                         plot0( rp, cp, y1[i].t0, c );\
  367.                     else if (zoom == 1) \
  368.                         plot1( rp, cp, y1[i].t1, c );\
  369.                     else if (zoom == 2) \
  370.                         plot2( rp, cp, y1[i].t2, c );\
  371.                     else if (zoom == 3) \
  372.                         plot3( rp, cp, y1[i].t3, c );\
  373.                     } \
  374.                 } } \
  375.  
  376. #define domap2(v,c)    { for (i = 0; i < z2; i++) { \
  377.                 if (v & (y2[i].t)) { \
  378.                     if (zoom == 0) \
  379.                         plot0( rp, cp, y2[i].t0, c );\
  380.                     else if (zoom == 1) \
  381.                         plot1( rp, cp, y2[i].t1, c );\
  382.                     else if (zoom == 2) \
  383.                         plot2( rp, cp, y2[i].t2, c );\
  384.                     else if (zoom == 3) \
  385.                         plot3( rp, cp, y2[i].t3, c );\
  386.                     } \
  387.                 } } \
  388.  
  389. #define domap3(v,c)    { for (i = 0; i < z3; i++) { \
  390.                 if (v & (y3[i].t)) { \
  391.                     if (zoom == 0) \
  392.                         plot0( rp, cp, y3[i].t0, c );\
  393.                     else if (zoom == 1) \
  394.                         plot1( rp, cp, y3[i].t1, c );\
  395.                     else if (zoom == 2) \
  396.                         plot2( rp, cp, y3[i].t2, c );\
  397.                     else if (zoom == 3) \
  398.                         plot3( rp, cp, y3[i].t3, c );\
  399.                     } \
  400.                 } } \
  401.  
  402. static void map ( rp, cp, v0, v1 ) /* map a cell */
  403.     int rp, cp;
  404.     long v0, v1;
  405.     {
  406.     int i;
  407.  
  408.     if (v0 & HOLE) {
  409.         domap1( v0, H ); /* plot the hole */
  410.         if (v1 && (sides & 2)) /* plot backside? */
  411.             domap2( v1, B );
  412.         if (v0 && (sides & 1)) /* plot frontside? */
  413.             domap2( v0, F );
  414.         }
  415.     else {
  416.         if (v1 && (sides & 2)) /* plot backside? */
  417.             domap3( v1, B );
  418.         if (v0 && (sides & 1)) /* plot frontside? */
  419.             domap3( v0, F );
  420.         }
  421.     }
  422.  
  423. static void plot0 ( rp, cp, obj, color ) /* plot a 3x3 template */
  424.     int rp, cp;
  425.     char obj[ZOOM0][ZOOM0];
  426.     int color;
  427.     {
  428.     int r, c;
  429.  
  430.     for (r = 0; r < ZOOM0; r++)
  431.         for (c = 0; c < ZOOM0; c++)
  432.             if (obj[r][c])
  433.                 Dot( color, rp-r, cp+c );
  434.     }
  435.  
  436. static void plot1 ( rp, cp, obj, color ) /* plot a 6x6 template */
  437.     int rp, cp;
  438.     char obj[ZOOM1][ZOOM1];
  439.     int color;
  440.     {
  441.     int r, c;
  442.  
  443.     for (r = 0; r < ZOOM1; r++)
  444.         for (c = 0; c < ZOOM1; c++)
  445.             if (obj[r][c])
  446.                 Dot( color, rp-r, cp+c );
  447.     }
  448.  
  449. static void plot2 ( rp, cp, obj, color ) /* plot a 10x10 template */
  450.     int rp, cp;
  451.     char obj[ZOOM2][ZOOM2];
  452.     int color;
  453.     {
  454.     int r, c;
  455.  
  456.     for (r = 0; r < ZOOM2; r++)
  457.         for (c = 0; c < ZOOM2; c++)
  458.             if (obj[r][c])
  459.                 Dot( color, rp-r, cp+c );
  460.     }
  461.  
  462. static void plot3 ( rp, cp, obj, color ) /* plot an 18x18 template */
  463.     int rp, cp;
  464.     char obj[ZOOM3][ZOOM3];
  465.     int color;
  466.     {
  467.     int r, c;
  468.  
  469.     for (r = 0; r < ZOOM3; r++)
  470.         for (c = 0; c < ZOOM3; c++)
  471.             if (obj[r][c])
  472.                 Dot( color, rp-r, cp+c );
  473.     }
  474.