home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 373.lha / route_v1.0 / src / old / pcbview.c < prev   
Encoding:
C/C++ Source or Header  |  1990-04-25  |  16.3 KB  |  613 lines

  1. /*
  2. ** printed circuit board displayer, Copyright (C) Randy Nevin 1989.
  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 in good faith to help you,
  15. ** and i want to act as a central clearing house for future versions. you
  16. ** should contact me before undertaking a significant development effort, to
  17. ** avoid reinventing the wheel. if you come up with an enhancement you
  18. ** consider particularly useful, i would appreciate being informed so that it
  19. ** can be incorporated in future versions. my address is: Randy Nevin,
  20. ** 1731 211th PL NE, Redmond, WA 98053. this code is available directly from
  21. ** the author; just send a floppy and a self-addressed floppy mailer with
  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. */
  29.  
  30. #include <stdio.h>
  31.  
  32. /*
  33. #ifndef M_XENIX
  34. #include <stdlib.h>
  35. #include <io.h>
  36. #include <conio.h>
  37. #include <dos.h>
  38. #endif
  39. */
  40.  
  41. #include "pcbview.h"
  42.  
  43. struct Screen *screen;
  44. struct Window *window;
  45. struct RastPort *rastp;
  46. struct IntuitionBase *IntuitionBase;
  47. struct GfxBase *GfxBase;
  48. struct IntuiMessage *IM;
  49. ULONG class;
  50. USHORT code;
  51.  
  52. extern struct Screen *OpenScreen();
  53. extern struct Window *OpenWindow();
  54. extern struct Library *OpenLibrary();
  55. extern void CloseLibrary(),CloseScreen(),CloseWindow();
  56. extern struct Message *GetMsg();
  57.  
  58. #define MENUCODE(m,i,s) (SHIFTMENU(m)|SHIFTITEM(i)|SHIFTSUB(s))
  59.  
  60. /*
  61. #include <string.h>
  62. */
  63.  
  64. extern char *strrchr();
  65.  
  66. /* #include <signal.h> enable this to catch ^C */
  67. #include "cell.h"
  68.  
  69. /*
  70. ** ^C handling is disabled because on my system enabling it seems to interfere
  71. ** with int 10h processing, which is needed to plot pixels. you should enable
  72. ** it and see what happens on your system.
  73. */
  74.  
  75. /* WARNING: the code below assumes 640x350 16-color ega */
  76.  
  77. /* 0=black    1=blue        2=green        3=light blue        */
  78. /* 4=red    5=purple    6=brown        7=grey            */
  79. /* 8=black    9=bright blue    A=bright green    B=bright light blue    */
  80. /* C=scarlet    D=purple    E=yellow    F=white            */
  81.  
  82. /*
  83. ** the colors below work fine for me, but may not for your particular ega and
  84. ** monitor. if bright blue and light blue look the same to you, or some traces
  85. ** appear to be missing, you may want to change these constants.
  86. **
  87. ** on some egas, there appear to be gaps in the traces; i don't know why. on
  88. ** other egas, the traces look fine. this happened to me on the maximum zoom,
  89. ** but not on any other zoom level. apparently some problem with the int 10h
  90. ** interface.
  91. */
  92.  
  93. /* colors of objects */
  94. #define HOLC    0x2    /* hole color; scarlet            */
  95. #define FRSD    0x5    /* frontside trace color; bright blue    */
  96. #define BKSD    0x4    /* backside trace color; light blue    */
  97. #define EDGE    0x7    /* edge color; yellow            */
  98.  
  99. /* screen limits */
  100. #define MINHORZ    0    /* left-most pixel    */
  101. #define MAXHORZ    639    /* right-most pixel    */
  102. #define MINVERT    15    /* top-most pixel    */
  103. #define MAXVERT    511    /* bottom-most pixel    */
  104.  
  105. static int mode; /* for saving original screen mode */
  106. static int sides = 3; /* 0=holes only, 1=front only, 2=back only, 3=all */
  107.  
  108. #define MAXZOOM    3    /* maximum zoom number; minimum is 0 */
  109.  
  110. #define ZOOM0    3    /* 3x3 pixels per cell        */
  111. #define ZOOM1    6    /* 6x6 pixels per cell        */
  112. #define ZOOM2    10    /* 10x10 pixels per cell    */
  113. #define ZOOM3    18    /* 18x18 pixels per cell    */
  114.  
  115. static int zoom = 1; /* 0=3x3, 1=6x6, 2=10x10, 3=18x18 */
  116. static int zoomsize[MAXZOOM+1] = { ZOOM0, ZOOM1, ZOOM2, ZOOM3 };
  117.  
  118. /* current lower-left position */
  119. static int Xrow = 0;
  120. static int Xcol = 0;
  121.  
  122. int justboard = 1; /* only need the board data structure */
  123.  
  124. /* board dimensions */
  125. extern int Nrows;
  126. extern int Ncols;
  127.  
  128. extern void InitBoard();
  129. extern long GetCell();
  130. extern void SetCell();
  131. extern int GetMode();
  132. extern void SetMode();
  133. extern void Dot();
  134.  
  135. void main();
  136. /* static void control_C( void ); enable this to catch ^C */
  137. static void doedges();
  138. static void doboard();
  139. static void map();
  140. static void plot0();
  141. static void plot1();
  142. static void plot2();
  143. static void plot3();
  144.  
  145. void main ( argc, argv ) /* input routed board, display it on the screen */
  146. int argc;
  147. char *argv[];
  148. {
  149.     char *self, *p;
  150.     int r, c, rp, cp, i1, i2, i3, i4;
  151.     FILE *fp;
  152.     long x;
  153. /*
  154. #ifndef M_XENIX
  155.     union REGS regs;
  156. #else
  157.     int chh;
  158. #endif
  159. */
  160.  
  161.     printf( "Copyright (C) Randy Nevin, 1989. Version 1.00\n" );
  162.     printf( "See source code for rights granted.\n\n" );
  163.     printf( "Amiga Port by Udi Finkelstein\n" );
  164.     self = argv[0];
  165.     /* get rid of initial part of path */
  166.     if ((p = strrchr( self, '/' )) || (p = strrchr( self, ':' )))
  167.         self = ++p;
  168.     if (argc != 2) { /* need infile */
  169.         fprintf( stderr, "usage: %s infile\n", self );
  170.         exit( -1 );
  171.         }
  172.     if (!(fp = fopen( argv[1], "r" ))) {
  173.         fprintf( stderr, "can't open %s\n", argv[1] );
  174.         exit( -1 );
  175.         }
  176.     /* fetch the board dimensions */
  177.     if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
  178.         fprintf( stderr, "premature eof\n" );
  179.         exit( -1 );
  180.         }
  181.     Nrows = (rp & 0xFF) | ((cp << 8) & 0xFF00);
  182.     if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
  183.         fprintf( stderr, "premature eof\n" );
  184.         exit( -1 );
  185.         }
  186.     Ncols = (rp & 0xFF) | ((cp << 8) & 0xFF00);
  187.     InitBoard(); /* allocate memory for data structures */
  188.     for (r = 0; r < Nrows; r++) { /* read in the board, row by column */
  189.         for (c = 0; c < Ncols; c++) {
  190.             /* first, do frontside */
  191.             if ((i1 = getc( fp )) == EOF
  192.                 || (i2 = getc( fp )) == EOF
  193.                 || (i3 = getc( fp )) == EOF
  194.                 || (i4 = getc( fp )) == EOF) {
  195.                 fprintf( stderr, "premature eof\n" );
  196.                 exit( -1 );
  197.                 }
  198.             x = (long)i1 | (((long)i2) << 8)
  199.                 | (((long)i3) << 16) | (((long)i4) << 24);
  200.             SetCell( r, c, TOP, x );
  201.             /* then do backside */
  202.             if ((i1 = getc( fp )) == EOF
  203.                 || (i2 = getc( fp )) == EOF
  204.                 || (i3 = getc( fp )) == EOF
  205.                 || (i4 = getc( fp )) == EOF) {
  206.                 fprintf( stderr, "premature eof\n" );
  207.                 exit( -1 );
  208.                 }
  209.             x = (long)i1 | (((long)i2) << 8)
  210.                 | (((long)i3) << 16) | (((long)i4) << 24);
  211.             SetCell( r, c, BOTTOM, x );
  212.             }
  213.         }
  214.     /* tell user what commands are available */
  215. /*
  216.     printf( "\t0   = holes only\n" );
  217.     printf( "\t1   = holes and top traces\n" );
  218.     printf( "\t2   = holes and bottom traces\n" );
  219.     printf( "\t3   = holes and all traces\n" );
  220.     printf( "\tz/Z = zoom one level / maximum zoom\n" );
  221.     printf( "\ts/S = shrink one level / minimum shrink\n" );
  222.     printf( "\tl/L = move left by one / move left by ten\n" );
  223.     printf( "\tr/R = move right by one / move right by ten\n" );
  224.     printf( "\tu/U = move up by one / move up by ten\n" );
  225.     printf( "\td/D = move down by one / move down by ten\n" );
  226.     printf( "\tany other key exits the program\n" );
  227.     printf( "\nPress ENTER to continue, or ^C to exit " );
  228. */
  229.  
  230. #ifdef MSDOS_CODE
  231.  
  232. #ifndef M_XENIX
  233.     regs.h.ah = 0x8; /* character input without echo */
  234.     intdos( ®s, ®s ); /* call dos to get a keystroke */
  235. #else
  236.     (void)getchar();
  237. #endif
  238.     mode = GetMode(); /* save mode so can restore later */
  239.     /* signal( SIGINT, control_C ); enable this to catch ^C */
  240.     SetMode( 0x10 ); /* 640x350 16-color mode */
  241.  
  242. #endif
  243.  
  244.     if ((GfxBase = (struct GfxBase *)OpenLibrary(
  245.         "graphics.library",33L)) == NULL) {
  246.             printf("Can't open gfx!\n");
  247.             exit(10);
  248.     }
  249.  
  250.     if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary(
  251.         "intuition.library",33L)) == NULL) {
  252.             printf("Can't open intuition!\n");
  253.             CloseLibrary(GfxBase);
  254.             exit(10);
  255.     }
  256.  
  257.     if ((screen = OpenScreen(&NewScreenStructure)) == NULL) {
  258.             printf("Can't open screen!\n");
  259.             CloseLibrary(IntuitionBase);
  260.             CloseLibrary(GfxBase);
  261.             exit(10);
  262.     }
  263.  
  264.     NewWindowStructure1.Screen = screen;
  265.  
  266.     if ((window = OpenWindow(&NewWindowStructure1)) == NULL) {
  267.             printf("Can't open window!\n");
  268.             CloseScreen(screen);
  269.             CloseLibrary(IntuitionBase);
  270.             CloseLibrary(GfxBase);
  271.             exit(10);
  272.     }
  273.  
  274.     rastp = window->RPort;
  275.     SetMenuStrip(window,&MenuList1);
  276.     LoadRGB4(&screen->ViewPort,Palette,(long)PaletteColorCount);
  277.  
  278.     doedges(); /* display board edges */
  279.     doboard(); /* display the board */
  280.     for (;;) { /* process until unrecognized keystroke */
  281.  
  282. #ifdef MSDOS_CODE
  283.  
  284. #ifndef M_XENIX
  285.         regs.h.ah = 0x8; /* character input without echo */
  286.         intdos( ®s, ®s ); /* call dos to get a keystroke */
  287.         switch (regs.h.al) { /* determine what it is */
  288. #else
  289.         switch (chh = getchar()) { /* determine what it is */
  290. #endif
  291. #endif
  292.  
  293.         Wait (1L << (window->UserPort->mp_SigBit));
  294.         while((IM = (struct IntuiMessage *)
  295.                 GetMsg(window->UserPort)) != NULL) {
  296.             code = IM->Code;
  297.             class = IM->Class;
  298.             ReplyMsg(IM);
  299.             switch (class) {
  300.                 case CLOSEWINDOW:
  301.                     CloseWindow(window);
  302.                     CloseScreen(screen);
  303.                     CloseLibrary(IntuitionBase);
  304.                     CloseLibrary(GfxBase);
  305.                     exit(10);
  306.                 case MENUPICK:
  307.                     switch (code) {
  308.                         case MENUCODE(0,0,NOSUB): /* just show holes */
  309.                             if (sides == 0)
  310.                                 continue;
  311.                             sides = 0;
  312.                             break;
  313.                         case MENUCODE(0,1,NOSUB): /* show holes and top-side traces */
  314.                             if (sides == 1)
  315.                                 continue;
  316.                             sides = 1;
  317.                             break;
  318.                         case MENUCODE(0,2,NOSUB): /* show holes and bottom-side traces */
  319.                             if (sides == 2)
  320.                                 continue;
  321.                             sides = 2;
  322.                             break;
  323.                         case MENUCODE(0,3,NOSUB): /* show holes and all traces */
  324.                             if (sides == 3)
  325.                                 continue;
  326.                             sides = 3;
  327.                             break;
  328.                         case MENUCODE(2,1,NOSUB): /* zoom to the limit */
  329.                             if (zoom == MAXZOOM)
  330.                                 continue;
  331.                             zoom = MAXZOOM;
  332.                             break;
  333.                         case MENUCODE(2,0,NOSUB): /* zoom by one */
  334.                             if (zoom == MAXZOOM)
  335.                                 continue;
  336.                             zoom++;
  337.                             break;
  338.                         case MENUCODE(2,3,NOSUB): /* shrink to the limit */
  339.                             if (zoom == 0)
  340.                                 continue;
  341.                             zoom = 0;
  342.                             break;
  343.                         case MENUCODE(2,2,NOSUB): /* shrink by one */
  344.                             if (zoom == 0)
  345.                                 continue;
  346.                             zoom--;
  347.                             break;
  348.                         case MENUCODE(1,1,NOSUB): /* left by 10 */
  349.                             if (Xcol == 0)
  350.                                 continue;
  351.                             if (Xcol <= 10)
  352.                                 Xcol = 0;
  353.                             else
  354.                                 Xcol -= 10;
  355.                             break;
  356.                         case MENUCODE(1,0,NOSUB): /* left by one */
  357.                             if (Xcol == 0)
  358.                                 continue;
  359.                             Xcol--;
  360.                             break;
  361.                         case MENUCODE(1,3,NOSUB): /* right by 10 */
  362.                             if (Xcol == Ncols-1)
  363.                                 continue;
  364.                             if (Xcol >= Ncols-11)
  365.                                 Xcol = Ncols-1;
  366.                             else
  367.                                 Xcol += 10;
  368.                             break;
  369.                         case MENUCODE(1,2,NOSUB): /* right by one */
  370.                             if (Xcol == Ncols-1)
  371.                                 continue;
  372.                             Xcol++;
  373.                             break;
  374.                         case MENUCODE(1,5,NOSUB): /* up by 10 */
  375.                             if (Xrow == Nrows-1)
  376.                                 continue;
  377.                             if (Xrow >= Nrows-11)
  378.                                 Xrow = Nrows-1;
  379.                             else
  380.                                 Xrow += 10;
  381.                             break;
  382.                         case MENUCODE(1,4,NOSUB): /* up by one */
  383.                             if (Xrow == Nrows-1)
  384.                                 continue;
  385.                             Xrow++;
  386.                             break;
  387.                         case MENUCODE(1,7,NOSUB): /* down by 10 */
  388.                             if (Xrow == 0)
  389.                                 continue;
  390.                             if (Xrow <= 10)
  391.                                 Xrow = 0;
  392.                             else
  393.                                 Xrow -= 10;
  394.                             break;
  395.                         case MENUCODE(1,6,NOSUB): /* down by one */
  396.                             if (Xrow == 0)
  397.                                 continue;
  398.                             Xrow--;
  399.                             break;
  400.                     }
  401.             }
  402.         }
  403.         ClearPCB();
  404.         doedges(); /* display board edges */
  405.         doboard(); /* display the board */
  406.     }
  407. }
  408.  
  409. /*
  410. ** enable this to catch ^C
  411. **
  412. **static void control_C () { / * handle ^C * /
  413. **    SetMode( mode ); / * restore original screen mode * /
  414. **    exit( 0 );
  415. **    }
  416. */
  417.  
  418. /*
  419.  * display the board edges
  420.  */
  421. static void doedges ()
  422. {
  423.     int r1, c1, r2, c2, i, z;
  424.     long xr1, xc1, xr2, xc2;
  425.  
  426.     z = zoomsize[zoom];
  427.     /* first, calculate their virtual screen positions */
  428.     r1 = MAXVERT+(Xrow*z); /* bottom edge */
  429.     c1 = MINHORZ-(Xcol*z); /* left edge */
  430.     r2 = MAXVERT-1-((Nrows-Xrow)*z); /* top edge */
  431.     c2 = MINHORZ+1+((Ncols-Xcol)*z); /* right edge */
  432.  
  433.     SetAPen(rastp,(long)EDGE);
  434.  
  435.     xr1 = r1; xr2 = r2;
  436.     if (r1 < MINVERT) xr1 = MINVERT;
  437.     if (r1 > MAXVERT) xr1 = MAXVERT;
  438.     if (r2 < MINVERT) xr2 = MINVERT;
  439.     if (r2 > MAXVERT) xr2 = MAXVERT;
  440.  
  441.     xc1 = c1; xc2 = c2;
  442.     if (c1 < MINHORZ) xc1 = MINHORZ;
  443.     if (c1 > MAXHORZ) xc1 = MAXHORZ;
  444.     if (c2 < MINHORZ) xc2 = MINHORZ;
  445.     if (c2 > MAXHORZ) xc2 = MAXHORZ;
  446.  
  447.     if (r1 >= MINVERT && r1 <= MAXVERT) { /* draw bottom edge */
  448.         Move(rastp,xc1,(long)r1);
  449.         Draw(rastp,xc2,(long)r1);
  450.     }
  451.  
  452.     if (c1 >= MINHORZ && c1 <= MAXHORZ) { /* draw left edge */
  453.         Move(rastp,(long)c1,xr1);
  454.         Draw(rastp,(long)c1,xr2);
  455.     }
  456.  
  457.     if (r2 >= MINVERT && r2 <= MAXVERT) { /* draw top edge */
  458.         Move(rastp,xc1,(long)r2);
  459.         Draw(rastp,xc2,(long)r2);
  460.     }
  461.  
  462.     if (c2 >= MINHORZ && c2 <= MAXHORZ) { /* draw right edge */
  463.         Move(rastp,(long)c2,xr1);
  464.         Draw(rastp,(long)c2,xr2);
  465.     }
  466. }
  467.  
  468. static void doboard () { /* display the board on the screen, row by column */
  469.     int r, c, rp, cp, rpd, cpd, z;
  470.     long x, y;
  471.  
  472.     z = zoomsize[zoom];
  473.     rpd = MINVERT+z; /* top-most plottable row */
  474.     cpd = MAXHORZ-z; /* right-most plottable column */
  475.     for (r = Xrow, rp = MAXVERT-1; r < Nrows && rp >= rpd; r++, rp -= z) {
  476.         for (c = Xcol, cp = MINHORZ+1; c < Ncols && cp <= cpd;
  477.                 c++, cp += z) {
  478.             x = GetCell( r, c, TOP );
  479.             y = GetCell( r, c, BOTTOM );
  480.             if (x || y) /* only map if something is there */
  481.                 map( rp, cp, x, y );
  482.             }
  483.         }
  484.     }
  485.  
  486. struct x { /* group the bit templates for an object */
  487.     long t;            /* the object type    */
  488.     char t0[ZOOM0][ZOOM0];    /* tiny zoom template    */
  489.     char t1[ZOOM1][ZOOM1];    /* small zoom template    */
  490.     char t2[ZOOM2][ZOOM2];    /* medium zoom template    */
  491.     char t3[ZOOM3][ZOOM3];    /* large zoom template    */
  492.     };
  493.  
  494. extern struct x y1[];  /* hole templates        */
  495. extern struct x y2[];  /* hole-related templates    */
  496. extern struct x y3[];  /* non-hole-related templates    */
  497.  
  498. extern int z1;  /* number of hole types            */
  499. extern int z2;  /* number of hole-related types        */
  500. extern int z3;  /* number of non-hole-related types    */
  501.  
  502. #define domap1(v,c)    { for (i = 0; i < z1; i++) { \
  503.                 if (v & (y1[i].t)) { \
  504.                     if (zoom == 0) \
  505.                         plot0( rp, cp, y1[i].t0, c );\
  506.                     else if (zoom == 1) \
  507.                         plot1( rp, cp, y1[i].t1, c );\
  508.                     else if (zoom == 2) \
  509.                         plot2( rp, cp, y1[i].t2, c );\
  510.                     else if (zoom == 3) \
  511.                         plot3( rp, cp, y1[i].t3, c );\
  512.                     } \
  513.                 } } \
  514.  
  515. #define domap2(v,c)    { for (i = 0; i < z2; i++) { \
  516.                 if (v & (y2[i].t)) { \
  517.                     if (zoom == 0) \
  518.                         plot0( rp, cp, y2[i].t0, c );\
  519.                     else if (zoom == 1) \
  520.                         plot1( rp, cp, y2[i].t1, c );\
  521.                     else if (zoom == 2) \
  522.                         plot2( rp, cp, y2[i].t2, c );\
  523.                     else if (zoom == 3) \
  524.                         plot3( rp, cp, y2[i].t3, c );\
  525.                     } \
  526.                 } } \
  527.  
  528. #define domap3(v,c)    { for (i = 0; i < z3; i++) { \
  529.                 if (v & (y3[i].t)) { \
  530.                     if (zoom == 0) \
  531.                         plot0( rp, cp, y3[i].t0, c );\
  532.                     else if (zoom == 1) \
  533.                         plot1( rp, cp, y3[i].t1, c );\
  534.                     else if (zoom == 2) \
  535.                         plot2( rp, cp, y3[i].t2, c );\
  536.                     else if (zoom == 3) \
  537.                         plot3( rp, cp, y3[i].t3, c );\
  538.                     } \
  539.                 } } \
  540.  
  541. static void map ( rp, cp, v0, v1 ) /* map a cell */
  542.     int rp, cp;
  543.     long v0, v1;
  544.     {
  545.     int i;
  546.  
  547.     if (v0 & HOLE) {
  548.         domap1( v0, HOLC ); /* plot the hole */
  549.         if (v1 && (sides & 2)) /* plot backside? */
  550.             domap2( v1, BKSD );
  551.         if (v0 && (sides & 1)) /* plot frontside? */
  552.             domap2( v0, FRSD );
  553.         }
  554.     else {
  555.         if (v1 && (sides & 2)) /* plot backside? */
  556.             domap3( v1, BKSD );
  557.         if (v0 && (sides & 1)) /* plot frontside? */
  558.             domap3( v0, FRSD );
  559.         }
  560.     }
  561.  
  562. static void plot0 ( rp, cp, obj, color ) /* plot a 3x3 template */
  563.     int rp, cp;
  564.     char obj[ZOOM0][ZOOM0];
  565.     int color;
  566.     {
  567.     int r, c;
  568.  
  569.     for (r = 0; r < ZOOM0; r++)
  570.         for (c = 0; c < ZOOM0; c++)
  571.             if (obj[r][c])
  572.                 Dot( color, rp-r, cp+c );
  573.     }
  574.  
  575. static void plot1 ( rp, cp, obj, color ) /* plot a 6x6 template */
  576.     int rp, cp;
  577.     char obj[ZOOM1][ZOOM1];
  578.     int color;
  579.     {
  580.     int r, c;
  581.  
  582.     for (r = 0; r < ZOOM1; r++)
  583.         for (c = 0; c < ZOOM1; c++)
  584.             if (obj[r][c])
  585.                 Dot( color, rp-r, cp+c );
  586.     }
  587.  
  588. static void plot2 ( rp, cp, obj, color ) /* plot a 10x10 template */
  589.     int rp, cp;
  590.     char obj[ZOOM2][ZOOM2];
  591.     int color;
  592.     {
  593.     int r, c;
  594.  
  595.     for (r = 0; r < ZOOM2; r++)
  596.         for (c = 0; c < ZOOM2; c++)
  597.             if (obj[r][c])
  598.                 Dot( color, rp-r, cp+c );
  599.     }
  600.  
  601. static void plot3 ( rp, cp, obj, color ) /* plot an 18x18 template */
  602.     int rp, cp;
  603.     char obj[ZOOM3][ZOOM3];
  604.     int color;
  605.     {
  606.     int r, c;
  607.  
  608.     for (r = 0; r < ZOOM3; r++)
  609.         for (c = 0; c < ZOOM3; c++)
  610.             if (obj[r][c])
  611.                 Dot( color, rp-r, cp+c );
  612.     }
  613.