home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / egafast / Part2 < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  31.0 KB

  1. From: mcdonald@uxe.cso.uiuc.edu (J.D. McDonald )
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i023: EGAFAST IBM-PC Graphics Package, Part 2/2
  4. Message-ID: <7134@ncoast.UUCP>
  5. Date: 26 Jan 88 04:30:40 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. Comp.sources.misc: Volume 2, Issue 23
  9. Submitted-By: J.D. McDonald <mcdonald@uxe.cso.uiuc.edu>
  10. Archive-Name: egafast/Part2
  11.  
  12. due to the size, distribution is in two parts 
  13. This is part 2.
  14.  
  15. *********begin second copy of READ.ME*************
  16. This is a very simple graphics package for the EGA and VGA. It draws the
  17. basic primitives of lines, ellipses, filled rectangles, filled ellipses,
  18. and text (two sizes and user defined). It is written to get the ultimate
  19. in high speed possible while drawing in the set/reset mode. It can be
  20. called from Microsoft C and Fortran, or any language including assembler
  21. which follows their calling conventions.
  22. Here is a list of the included files:
  23.  
  24. CLIPLINE C     Source code for clipped line routine.
  25. EGAFORT  H     Header file for subroutine prototypes for Fortran.
  26. EGAGRA   ASM   The main graphics package source.
  27. EGAGRA   DOC   Documentation.
  28. EGATEST  C     A test program to verify correct compilation.
  29. ELLIPSE  C     Source code for ellipse drawers.
  30. GRAFEX1  C     Example program that draws a star.
  31. GRAFEX2  C     Example program that uses user-defined patterns.
  32. INTEST   ASM   Assembler subroutine for SLUGS.FOR
  33. MACROS   AH    Header file for EGAGRA.ASM which defines memory model.
  34. MOVERM   C     Example program for plane masking.
  35. MOVERS   C     Example program for page swapping and plane masking.
  36. SLUGS    FOR   Example program in Fortran whose results look nice.
  37.  
  38. Some of the code in this package is patterned after that of U.E.Kruse of
  39. the U. of I. Physics department. The grafex1 demo program generates
  40. essentially the same pattern as the one of the same name in the package
  41. by Scott Snyder of caltech recently posted on the net. The macros.ah
  42. is also from his package.
  43.  
  44. Your comments are welcome, especially if you see anything faster.
  45.  
  46. Doug McDonald
  47. University of Illinois
  48. 505 S. Matthews 
  49. Urbana Ill. 61801
  50. (mcdonald@uiucuxe or mcdonald@uxe.cso.uiuc.edu)
  51.  
  52.  
  53. ***********end second copy of READ.ME***********
  54. ***********begin file ELLIPSE.C*****************
  55. /* Draw an ellipse with width irx and height iry                         */
  56. /* from a routine by Tim Hogan in Dr. Dobb's Journal May '85 p.40        */
  57. /* Improved by calculating increments incrementally, thus removing all   */
  58. /* multiplies from the loops. These multiplies were very bad since they  */
  59. /* were (long)*(long). This code, when compiled by Microsoft C Version 4,*/
  60. /* can't be significantly improved by hand optimization.                 */
  61. /* Written Sept. 7, 1987 by J.D. McDonald (public domain)                */
  62.  
  63. static long     alpha, beta, alpha2, alpha4, beta2, beta4, d;
  64. static long     ddx, ddy, alphadx, betady;
  65. static int      dy, dx;
  66.  
  67. extern void     e_start();    /* Starts off by writing right and left
  68.                  * points                                */
  69. extern void     e_xd();    /* Moves one step to lower x (in all 4 quadrants)*/
  70. extern void     e_xdyu();    /* Moves to lower x, higher y            */
  71. extern void     e_yu();       /* Moves to higher y                     */
  72.  
  73. ellipse(x, y, irx, iry, c)
  74.     int             x, y, irx, iry;
  75.     unsigned        c;
  76. {
  77.  
  78.     beta = (long) irx *(long) irx;
  79.     alpha = (long) iry *(long) iry;
  80.  
  81.     if (alpha == 0L)
  82.     alpha = 1L;
  83.     if (beta == 0L)
  84.     beta = 1L;
  85.  
  86.     dy = 0;
  87.     dx = irx;
  88.     alpha2 = alpha << 1;
  89.     alpha4 = alpha2 << 1;
  90.     beta2 = beta << 1;
  91.     beta4 = beta2 << 1;
  92.     alphadx = alpha * dx;
  93.     betady = 0;
  94.     ddx = alpha4 * (1 - dx);
  95.     ddy = beta2 * 3;
  96.  
  97.     d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha);
  98.     e_start(x - dx, x + dx, y, c);
  99.  
  100.     do {
  101.     if (d >= 0) {
  102.         d += ddx;
  103.         dx--;
  104.         alphadx -= alpha;
  105.         ddx += alpha4;
  106.         e_xdyu();
  107.     } else
  108.         e_yu();
  109.     d += ddy;
  110.     dy++;
  111.     betady += beta;
  112.     ddy += beta4;
  113.     } while (alphadx > betady);
  114.  
  115.     d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1) 
  116.     + beta * (1 - alpha2);
  117.     ddx = alpha2 * (3 - (dx << 1));
  118.     ddy = beta4 * (1 + dy);
  119.  
  120.     do {
  121.     if (d <= 0) {
  122.         d += ddy;
  123.         ddy += beta4;
  124.         dy++;
  125.         e_xdyu();
  126.     } else
  127.         e_xd();
  128.     d += ddx;
  129.     ddx += alpha4;
  130.     dx--;
  131.     } while (dx > 0);
  132. }
  133.  
  134. fillelip(x, y, irx, iry, c)
  135.     int             x, y, irx, iry;
  136.     unsigned        c;
  137. {
  138.  
  139.     beta = (long) irx *(long) irx;
  140.     alpha = (long) iry *(long) iry;
  141.  
  142.     if (alpha == 0L)
  143.     alpha = 1L;
  144.     if (beta == 0L)
  145.     beta = 1L;
  146.  
  147.     dy = 0;
  148.     dx = irx;
  149.     alpha2 = alpha << 1;
  150.     alpha4 = alpha2 << 1;
  151.     beta2 = beta << 1;
  152.     beta4 = beta2 << 1;
  153.     alphadx = alpha * dx;
  154.     betady = 0;
  155.     ddx = alpha4 * (1 - dx);
  156.     ddy = beta2 * 3;
  157.  
  158.     d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha);
  159.     rectfill(x - dx, y, x + dx, y, c);
  160.  
  161.     do {
  162.     if (d >= 0) {
  163.         d += ddx;
  164.         dx--;
  165.         alphadx -= alpha;
  166.         ddx += alpha4;
  167.     }
  168.     d += ddy;
  169.     dy++;
  170.     betady += beta;
  171.     ddy += beta4;
  172.     rectfill(x - dx, y + dy, x + dx, y + dy, c);
  173.     rectfill(x - dx, y - dy, x + dx, y - dy, c);
  174.     } while (alphadx > betady);
  175.  
  176.     d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1) 
  177.     + beta * (1 - alpha2);
  178.     ddx = alpha2 * (3 - (dx << 1));
  179.     ddy = beta4 * (1 + dy);
  180.  
  181.     do {
  182.     dx--;
  183.     if (d <= 0) {
  184.         d += ddy;
  185.         ddy += beta4;
  186.         dy++;
  187.         rectfill(x - dx, y + dy, x + dx, y + dy, c);
  188.         rectfill(x - dx, y - dy, x + dx, y - dy, c);
  189.     }
  190.     d += ddx;
  191.     ddx += alpha4;
  192.     } while (dx > 0);
  193. }
  194.  
  195. ***********end file ELLIPSE.C*******************
  196. ***********begin file CLIPLINE.C****************
  197. /*routine to plot clipped line*/
  198. clipline(x1,y1,x2,y2,icol)
  199. int x1,y1,x2,y2,icol;
  200. {
  201.     int x3, y3, x4, y4;
  202.     if(clip_ln(x1,y1,&x3,&y3,x2,y2)){
  203.       if(clip_ln(x2,y2,&x4,&y4,x3,y3))
  204.          zline(x4,y4,x3,y3,icol);
  205.     }
  206. }
  207.  
  208. /* routine to clip one endpoint of a line */
  209. /* to clip to a rectangle instead of the screen, change MINX, MAXX, and MINY
  210.    to input parameters instead of defines, and fix maxy also */
  211. #define MINY 0
  212. #define MINX 0
  213. #define MAXX 639
  214. extern int max_lin(void);
  215. int clip_ln(x1,y1,xc,yc,x2,y2)
  216. int x1,y1,x2,y2,*xc,*yc;
  217. {
  218.   int delx,dely,maxy;
  219.   long templ; 
  220.   maxy = max_lin() - 1;
  221.   *xc=x1; 
  222.   *yc=y1;
  223.   if ( y1 >= MINY && y1 <= maxy && x1 >= MINX && x1 <= MAXX) 
  224.      return(1);
  225.   dely=y1-y2;
  226.   delx=x1-x2;
  227.   if (y1 > maxy || y1 < MINY) {
  228.     if (y1 > maxy) {
  229.       if (y2 > maxy) return (0);
  230.       *yc=maxy;
  231.     } else {
  232.       if (y2 < MINY ) return(0);
  233.       *yc=MINY;
  234.     }
  235.     templ = (long)(*yc-y2)*(long)delx;
  236.     *xc=templ/dely+x2;
  237.     if (*xc >= MINX && *xc <= MAXX) {
  238.       return(1);
  239.     }
  240.   }
  241.   dely=*yc-y2;
  242.   delx=*xc-x2;
  243.   if (*xc > MAXX || *xc < MINX) {
  244.     if (*xc > MAXX) {
  245.       if (x2 > MAXX ) return(0);
  246.       *xc=MAXX;
  247.     }
  248.     else {
  249.       if (x2 < MINX ) return(0);
  250.       *xc=MINX;
  251.     }
  252.     templ = (long)(*xc-x2)*(long)dely;
  253.     *yc=templ/delx+y2;
  254.     if (*yc >= MINY && *yc <= maxy) {
  255.       return(1);
  256.     }
  257.   }
  258.   return(0);
  259. }
  260.  
  261. *********************end file CLIPLINE.C*************
  262. *********************begin file GRAFEX1.C************
  263.  
  264. #include <stdio.h>
  265. #include <math.h>
  266.  
  267. #define pi 3.1415926
  268.  
  269. main()
  270. {
  271.   int n, i, j, d;
  272.   unsigned color;
  273.   struct {
  274.     int x, y;
  275.   } vert[32];
  276.  
  277.   do {
  278.     printf("Enter number of vertices, 4 to 32: ");
  279.     scanf("%d", &n);
  280.     if ( n < 4 || n > 32 ) printf("Try again!\n");
  281.      } while( n < 4 || n > 32);
  282.  
  283.   setmod(16);     /*change ega to graphics mode*/
  284.   zsetup();       /*initialize drawing package...bios drawing stops working */
  285.  
  286. /* space n vertices equally on an ellipse that fits nicely on the screen */
  287.  
  288.   for (i=0; i<n; i++) {
  289.     vert[i].x = 319.49 + 200.*sin(2*pi/n*i);
  290.     vert[i].y = 174.49 - 160.*cos(2*pi/n*i);
  291.   }
  292.  
  293. /*
  294.  * draw the figure. the colors are selected so that points that are the
  295.  * same distance from each other on the ellipse have the same color.
  296.  */
  297.  
  298.   for (i=0; i<n; i++)
  299.     for (j=i+1; j<n; j++) {
  300.       d = j-i;
  301.       if (d > n/2) d = n - d;
  302.       color = (float)d/(n/2+1)*15 + 1;
  303.       zline(vert[i].x, vert[i].y, vert[j].x, vert[j].y, color);
  304.     }
  305.  
  306. /* wait... */
  307.  
  308.   curmod();    /*reset to allow bios to draw letters */
  309.   printf("Press any key...");
  310.   getch();
  311.  
  312. /* and clean up. */
  313.  
  314.   setmod(3);   /*back to text mode*/
  315. }
  316.  
  317. *******************end file GRAFEX1.C***************
  318. *******************begin file GRAFEX2.C*************
  319. char bigsym[5] = {60,102,195,102,60};
  320. char littlesym[5] = {0,24,60,24,0};
  321.  
  322. main()
  323. {
  324.       char *cptr;
  325.       int i, ix, iy, icount, icolor;
  326.       setmod(16);  /* set graphics mode*/
  327.       zsetup(); /*initialize graphics package*/
  328.       for (icount = 0 ; icount < 10000 ; icount++){
  329.             ix = rand()/51;
  330.             iy = rand()/93;
  331.             icolor = rand() & 7;
  332.  
  333. /*    symbol(ix,iy,iheight,icolor,symbol) draws a rectangular pattern 8 bits
  334.       wide and iheight bits high with upper left corner at ix,iy in color
  335.       *symbol. The patterns in this program are 
  336.                      bigsum               littlesym
  337.  
  338.                     ..****..              ........
  339.                     .**..**.              ...**...
  340.                     **....**              ..****..
  341.                     .**..**.              ...**...
  342.                     ..****..              ........
  343.      The result is a little spot with a bright center and a dim border.     */
  344.  
  345.                     
  346.             symbol(ix,iy,5,icolor+8,littlesym);
  347.             symbol(ix,iy,5,icolor,bigsym);
  348.          }
  349.       for(i = 0 ,cptr = "Hit any key to quit."; *cptr ;i++)
  350.           llettr(i << 3,0,*cptr++,15);
  351.  
  352.       while(!kbhit());
  353.       getch();
  354.       setmod(3);   /*go back to text mode*/
  355. }
  356.  
  357.  
  358. *******************end file GRAFEX2.c***************
  359. *******************begin file EGAGRA.DOC************
  360.              EGAGRA - Fast Graphics Routines for the EGA or VGA
  361.  
  362.       Egagra is as set of high speed graphics routines for the IBM EGA
  363. and VGA graphics systems. It runs on these in the BIOS modes 15, 16, and 18,
  364. which are 350X640 monochrome, 350X640 16 color and 480 X 640 16 color
  365. modes respectively. It provides routines for lines, filled rectangles,
  366. and open and filled ellipses, as well as two sizes of text and a routine
  367. to display text-like patterns. The routines (including the text ones) all
  368. draw over any previous pattern in a given area; the text ones do not result
  369. in a black rectangle around the text. The text drawing routines also allow
  370. text to be places to any arbitrary pixel position. A mask function allows
  371. writing to one or more bit planes while leaving others uneffected.
  372.       All of these routines are written in assembler in the calling sequence
  373. of Microsoft C, except for the ellipses and the clipped-line routine which
  374. are in C. A header file is provided so they can be used from Microsoft
  375. Fortran without changes. A set of demonstration programs in C and Fortran
  376. is included.
  377.       The first subroutine called when using this package is setmod(n),
  378. where n is the desired graphics mode. This simply calls the ROM BIOS to 
  379. set the desired mode; it still leaves the system in a text state so that
  380. the io routines of the language used are operational. The actual graphics
  381. calls (including text routines slettr, llettr and symbol) must be preceeded
  382. by a call to zsetup. After this call, language io to the console, such
  383. as printf or scanf in C or read and write to the console in Fortran, results
  384. in garbage. However, a call to curmod then re-enables language io. In 
  385. other words, between calls to zsetup and curmod you use these graphics
  386. routines, while after curmod calls you use the facilities of the programming
  387. language. (Of course, there is no effect on io to disk files or COM ports.)
  388. At the end of you program there must be a call to reset the BIOS mode to
  389. the original value, usually 2, 3, or 7. If this isn't done, DOS will write
  390. garbage to the screen, a problem which can be fixed from DOS by using
  391. MODE CO80, MODE BW80 or MODE MONO as desired. When using an EGA with the
  392. minimum memory on an IBM monochrome display in mode 15, use colors 0,
  393. 3, 12 and 15 only.   
  394.       All the drawing routines except zpoint clip the drawing to the
  395. horizontal confines of the screen. The rectangle and filled ellipse ones 
  396. clip vertically also. The rest simply draw on the portion of the screen
  397. buffer which is not mapped to the screen. A really long line or big ellipse
  398. will "wrap around". A routine called clipline draws a line clipped to the
  399. screen area.
  400.      Since these routines use the set/reset register of the ega, and the
  401. BIOS doesn't, if you ctrl-break out of one of them into DOS, screen
  402. garbage results. You should therefore put the zsetup/curmod calls closely
  403. around the actual drawing routines, and to be sure, trap the MS-DOS
  404. break interrupt and call a setmod(orig_mode) in the inteppupt routine.
  405.      The following description is for the C versions of the subroutines.
  406. The calling sequence for Fortran can be seen in the header file EGAFORT.H,
  407. which should be included in any Fortran routine using them. The routines
  408. will work in any memory model, but must be compiled separately for each.
  409. To make a library for a given model, perform the following steps:
  410.      1. Edit MACROS.AH to define the appropriate memory model. 
  411.      2. Use MASM on egagra.asm.
  412.      3. Compile ELLIPSE.C with the appropriate memory model switch, 
  413.         either /AS /AM /AC or /AL for small, medium, compact, or large.
  414.         ALSO use the /Fa switch. This will generate an ellipse.asm file.
  415.      4. Use MASM on ellipse.asm.
  416.      5. Repeat steps 4 & 5 on clipline.c.
  417.      6. Use LIB to combine the three .obj files into a library
  418.         egagrafs.lib, egagrafm.lib, egagrafc.lib, or egagrafl.lib as
  419.         appropriate.
  420. The contortions involved in making a .asm file out of ellipse and clipline
  421. and THEN assembling it are needed ONLY if you wish to use the library file
  422. with Fortran. This is done so that the C run-time library will not be
  423. automatically called, even if using Fortran. The ellipse routines don't
  424. need any run-time routines out of the C libraries, as all the necessary
  425. ones exist in Fortran. If you NEVER use Fortran, just compile ellipse.c
  426. directly with the correct memory-model switch. If you only have a Fortran
  427. compiler, you're out of luck with ellipses and clipped lines unless you 
  428. translate ellipse.c and clipline.c into Fortran (which is perfectly easy.)
  429.  
  430.                     Subroutine Descriptions
  431.  
  432.                     Utility Routines
  433.  
  434. setmod(i)
  435. int i;
  436.               This routine calls the BIOS to put the graphics adapter
  437.               into mode i.
  438.  
  439.  
  440. zsetup()
  441.               This routine initializes graphics drawing mode (see
  442.               text above). Zsetup is cancelled by curmod. The special
  443.               graphics drawing mode used by this package is slightly
  444.               different from the normal bios mode with the same resolution.
  445.  
  446. curmod()
  447.               This routine returns the adapter to normal bios drawing
  448.               mode, allowing BIOS calls to produce text.  
  449.  
  450. setpal(ipal,icol)
  451. int ipal, icol;
  452.               This routine changes the color produced by call a drawing
  453.               routine with color ipal to the physical color icol.
  454.               Ipal is a number from 0 to 15 whereas icol can vary from
  455.               0 to 63.
  456.  
  457. setpals(palete)
  458. char *palete;
  459.               The useage in a C program is
  460.                     char pal[17];
  461.                     setpals(pal);
  462.               where pal[0] to pal[15] are preset to the value desired
  463.               for the corresponding drawing color. pal[16] is the
  464.               border color; for ega mode it must be set to 0; the
  465.               other 16 values can range from 0 to 63. This call, unlike
  466.               setpal, sets all the 16 colors in one call.
  467.  
  468. setmask(mask)
  469. int mask;
  470.               This routine sets the bit map write enable mask. Since this
  471.               is rather cryptic, a bit of explanation is in order.
  472.               Consider a given pixel. Let's say it is presently in color
  473.               1. If we set mask to 15, which is the default state, and
  474.               write a point at that pixel with color 4, the pixel changes
  475.               to color 4. Set it back to 1. But now set mask to 4. Then
  476.               write color 4. The hardware then allows changes only to the
  477.               4's bit of the color; the 1's, 2's and 8's bits are write 
  478.               protected. Hence the color changes to 5. If we now set mask 
  479.               to 11 (1+2+8) and write a color 0, the color, now 5, changes 
  480.               to 4, since the 4's bit was protected. For an example
  481.               of the use of this, see the program "movers.c" and "moverm.c",
  482.               which generate exactly the same diaplay. The only difference
  483.               is that "movers.c" also uses page swapping.
  484.  
  485.  
  486. setdraw(i)
  487. int i;
  488.               This routine sends all following output to display page i.
  489.               Note that i must be 0 or 1. See the example program
  490.               "movers.c". A page need not be visible to be written to.
  491.               Apparently the VGA mode 18 has only one page.
  492.  
  493. setdisp(i)
  494. int i;
  495.               This routine causes page i (0 or 1) to be visible on the 
  496.               screen. See the example program "movers.c".
  497.  
  498.  
  499.  
  500.                     Text Routines
  501.  
  502. slettr(ix, iy, ichr, col)
  503. int ix, iy, ichr, col;
  504.  
  505. llettr(ix, iy, ichr, col)  
  506. int ix, iy, ichr, col;
  507.              
  508.              These two routines write text. They differ only in that slettr
  509.              draws using the 8 pixel high BIOS character set, while llettr
  510.              uses the ega 14 pixel high set. Ix and iy are the pixel
  511.              location of the upper left corner of the character box. They
  512.              need not be at a normal text cursor position; any value
  513.              -7 < ix < 647 and -14 < iy < (screen height + 13) is OK.
  514.              Ichr is the character; any value in the drawing set will 
  515.              work including the values less than 32 and the ones between
  516.              128 and 255. Character 219 is good for filling a whole
  517.              character box, such as simulating a background color. The
  518.              VGA 8x16 character set could be added by adapting the
  519.              initialization parts of slettr and llettr. I'm going to do
  520.              so when I get a PS/2, and call it xlettr. Adding a 9th
  521.              pixel row would be trickier.
  522.              
  523.  
  524. symbol(ix,iy,height,col,symb)
  525. int ix, iy, height, col;
  526. char *symb;
  527.              This routine operates just like the text routines except
  528.              that it draws a character of height height whose description
  529.              is contained in the array symb. Thus with height = 8
  530.              you can set an arbitrary patten of 256 pixels in an 8x8 
  531.              array. You can define your own character set, or use it
  532.              for icons.
  533.  
  534.                     Drawing Routines
  535.  
  536. zline(ix0, iy0, ix1, iy1, col)
  537. int ix0, iy0, ix1, iy1, col;
  538.              
  539.              This routine draws a line from ix0, iy0 to ix1, iy1 in
  540.              color col. The horizontal extent is restricted to the screen.
  541.  
  542. clipline(ix0, iy0, ix1, iy1, col)
  543. int ix0, iy0, ix1, iy1, col;
  544.              
  545.              This routine draws a line from ix0, iy0 to ix1, iy1 in
  546.              color col. It is restricted to the screen.
  547.  
  548. rectfill(ix0, iy0, ix1, iy1, col)
  549. int ix0, iy0, ix1, iy1, col;
  550.  
  551.              This routine draws a solid rectangle between diagonally
  552.              opposite corners ix0, iy0 and ix1, iy1 in color col.
  553.              Both horizontal and vertical extents are clipped to the screen.
  554.  
  555. ellipse(ix0, iy0, irx, iry, col)
  556. int ix0, iy0, irx, iry, col;
  557.  
  558. fillelip(ix0, iy0, irx, iry, col)
  559. int ix0, iy0, irx, iry, col;
  560.  
  561.              These routines draw ellipses centered at ix0, iy0 with
  562.              horizontal and vertical semi-axes irx and iry in color col.
  563.              Ellipse is open, fillelip is solid. The horizontal extent
  564.              is clipped to the screen. For a normal ega monitor,
  565.              iry = .8*irx generates a circle.
  566.  
  567. These routines were written by J. D. McDonald at the University of
  568. Illinois and are public domain.
  569.  
  570. ****************end file EGAGRA.DOC***************
  571. ****************begin file EGATEST.C**************
  572. char palete1[] = { 56, 9, 18, 27, 36, 45, 54, 63,
  573.              0, 1, 2, 3, 4, 5, 6, 7, 0};
  574. char palete2[] = { 0, 1, 2, 3, 4, 5, 6, 7,
  575.              56, 9, 18, 27, 36, 45, 54, 63, 0};
  576. unsigned char pattern[] = {204, 102, 51, 102, 204, 153, 51, 102,
  577.                            204, 102, 51, 102, 204, 153, 51, 102,
  578.                            204, 102, 51, 102, 204, 153, 51, 102 }; 
  579.  
  580. main()
  581. {
  582. char *cptr;
  583. int i, j, imode;
  584. int maxline = 350;
  585. do {
  586.     printf("Enter mode number, 16 for EGA, 16 or 18 for VGA");
  587.     scanf("%d",&imode); 
  588.  }  while( imode != 16 && imode != 18);
  589. if(imode == 18) maxline = 480;
  590. setmod(imode);
  591. zsetup();
  592. for(i = 0 ,cptr = "This should be large brown letters."; *cptr ;i++)
  593.        llettr(i << 3,0,*cptr++,6);
  594. for(i = 0 ,cptr = "At the upper left corner of the screen.";  *cptr ;i++)
  595.        llettr(i << 3,14,*cptr++,6);
  596. for(i = 0 ,cptr = "\003 \033There should be half a green heart (\003) at"; *cptr ;i++)
  597.        llettr((i << 3)-3,maxline/2-7,*cptr++,2);
  598. for(i = 0 ,cptr = "   the center of each edge of the screen."; *cptr ;i++)
  599.        llettr((i << 3)-3,maxline/2+7,*cptr++,2);
  600. llettr(316,-7,3,2);
  601. llettr(316,maxline-7,3,2);
  602. llettr(636,maxline/2-7,3,2);
  603. for(i = 0 ,cptr = "This should be small bright blue letters."; *cptr ;i++)
  604.        slettr(i << 3,30,*cptr++,9);
  605. ellipse(500,100,50,90,3);
  606. fillelip(500,100,20,20,4);
  607. for(i = 0 ,cptr = "Small filled red ellipse"; *cptr ;i++)
  608.        llettr(400+(i << 3),196,*cptr++,4);
  609. for(i = 0 ,cptr = "Large open cyan ellipse"; *cptr ;i++)
  610.        llettr(400+(i << 3),210,*cptr++,3);
  611. rectfill(100,250,539,300,7);
  612. zline(99,249,540,249,13);
  613. zline(99,249,99,301,13);
  614. zline(99,301,540,301,13);
  615. zline(540,249,540,301,13);
  616. zline(99,249,540,301,13);
  617. zline(99,301,540,249,13);
  618. for(i = 0 ,cptr = "Gray rectangle with violet border and cross."; *cptr ;i++)
  619.        llettr(142+(i << 3),310,*cptr++,13);
  620. for(i = 0 ,cptr = "Hit any key."; *cptr ;i++)
  621.        llettr(40+(i << 3),100,*cptr++,7);
  622. for(i = 0; i < 245; i += 8)symbol(i,50,24,6,pattern);
  623. for(i = 0 ,cptr = " Yellow text on brown pattern."; *cptr ;i++)
  624.        llettr((i << 3),55,*cptr++,14);
  625. for(i = 0 ,cptr = "This will appear only in mode 18"; *cptr ;i++)
  626.        llettr((i << 3),390,*cptr++,7);
  627. zline(0,412,256,412,7);
  628. while(!kbhit());
  629. setpals(palete1);
  630. getch();
  631. for(i = 0 ,cptr = "Dark and light colors should be reversed."; *cptr ;i++)
  632.        llettr(40+(i << 3),196,*cptr++,7);
  633. while(!kbhit());
  634. getch();
  635. for(i = 0 ,cptr = "The red ellipse should now be green."; *cptr ;i++)
  636.        llettr(40+(i << 3),210,*cptr++,7);
  637. rectfill(50,480,100,600,7);
  638. setdraw(1);
  639. for(i = 0 ,cptr = "This is the second video page."; *cptr ;i++)
  640.        llettr(150+(i << 3),200,*cptr++,7);
  641. for(i = 0 ,cptr = "Three lines of text, and nothing else,should appear."
  642.                 ; *cptr ;i++)llettr(150+(i << 3),215,*cptr++,7);
  643. for(i = 0 ,cptr = "Hit any key."; *cptr ;i++)
  644.        llettr(150+(i << 3),230,*cptr++,7);
  645. setpal(4,18);
  646. while(!kbhit());
  647. getch();
  648. setpals(palete2);
  649. setdisp(1);
  650. while(!kbhit());
  651. getch();
  652. setmod(3);
  653.  
  654. *****************end file EGATEST.C*****************
  655. *****************begin file MOVERS.C****************
  656. #include <math.h>
  657. #define PI128 3.141585/128.
  658.     char quit_string[] = "Hit any key to quit.";
  659.     char palete1[17] = { 0, 1, 58, 58, 62, 62, 62, 62, 4,
  660.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  661. /*This program draws a moving ball with animation done using the page
  662.   swapping method. It is speed limited by the necessity to swap only
  663.   during vertical retrace.                                            */
  664.  
  665.  
  666. double xs[256], ys[256];
  667. main()
  668. {
  669.     int  x1, y1, x2, y2, i, icol, j;
  670.     double x, y;
  671.  
  672.     setmod(16);
  673.     zsetup();
  674.     setpals(palete1);    
  675.     setmask(15);
  676.     setdraw(0);
  677.     rectfill(0,0,639,349,0);
  678.     for (i = 0; i < 8; i++) {
  679.       rectfill(i*80, 0, i*80+19,349,1);
  680.       rectfill(i*80+40, 0 , i*80+59, 349,8);
  681.     }
  682.     for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
  683.     setdraw(1);
  684.     rectfill(0,0,639,349,0);
  685.     for (i = 0; i < 8; i++) {
  686.       rectfill(i*80, 0, i*80+19,349,1);
  687.       rectfill(i*80+40, 0 , i*80+59, 349,8);
  688.     }
  689.     for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
  690.       setmask(6);
  691.     x2=320;
  692.     y2=175;
  693.     for (i = 0; i < 256; i++) {
  694.         xs[i] = 320.-300.*sin(PI128*i);
  695.         ys[i] = 175.+100.*cos(PI128*i);
  696.     }
  697.     for (i = 0; !kbhit() ; i = (i+1) & 255 ) {
  698.       if( i & 1) {
  699.           setdisp(0);
  700.           setdraw(1);
  701.       } else {
  702.           setdisp(1);
  703.           setdraw(0);
  704.       }    
  705.       while( !( inp(0x3da) & 8));      
  706.         x= xs[i];
  707.         y= ys[i];
  708.         rectfill(x2-10,y2-9,x2+10,y2+9,0);
  709.           x2 = x1;
  710.           y2 = y1;
  711.           x1 = x;
  712.           y1 = y;
  713.           if(y1 > 175 && x1 >= 50 && x1 <= 130) icol = 2;
  714.               else icol = 4;
  715.           fillelip(x1,y1,10,8,icol);
  716.     }
  717.     setdisp(0);
  718.     setmod(3);
  719.  }
  720.  
  721.  
  722. **************end file MOVERS.C***************
  723. **************begin file MOVERM.C*************
  724. #include <math.h>
  725. #define PI128 3.141585/128.
  726.     char quit_string[] = "Hit any key to quit.";
  727.     char palete1[17] = { 0, 1, 0, 1, 62, 62, 62, 62, 4,
  728.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  729.     char palete2[17] = { 0, 1, 62, 62, 0, 1, 62, 62, 4,
  730.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  731.     char palete3[17] = { 0, 1, 0, 1, 58, 58, 58, 58, 4,
  732.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  733.     char palete4[17] = { 0, 1, 58, 58, 0, 1, 58, 58, 4,
  734.                            7, 4, 4,  4,  4,  4,  4, 0 } ;
  735. /*This program draws a moving ball with animation done using the palete
  736.   swapping method. It is speed limited by the necessity to swap only
  737.   during vertical retrace.                                            */
  738.  
  739. double xs[256], ys[256];
  740.  
  741. main()
  742. {
  743.     int  x1, y1, x2, y2, i;
  744.     double x, y;
  745.  
  746.     setmod(16);
  747.     zsetup();
  748.     setpals(palete1);    
  749.     setmask(15);
  750.     for (i = 0; i < 8; i++) {
  751.       rectfill(i*80, 0, i*80+19,349,1);
  752.       rectfill(i*80+40, 0 , i*80+59, 349,8);
  753.     }
  754.     for (i = 0; i < 256; i++ ) {
  755.       xs[i] = 320.-300.*sin(PI128*i);
  756.       ys[i] = 175.+100.*cos(PI128*i);
  757.     }
  758.     x2=320;
  759.     y2=175;
  760.     for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
  761.     for (i = 0; !kbhit() ; i = (i+1) & 255 ) {
  762.       x= xs[i];
  763.       y= ys[i];
  764.       if( i & 1) {
  765.           setmask(4);
  766.           rectfill(x2-10,y2-9,x2+10,y2+9,0);
  767.           x2 = x1;
  768.           y2 = y1;
  769.           x1 = x;
  770.           y1 = y;
  771.           fillelip(x1,y1,10,8,4);
  772.           if(y1 > 175 && x1 >= 50 && x1 <= 130) setpals(palete3);
  773.               else setpals(palete1);
  774.       } else {
  775.           setmask(2);
  776.           rectfill(x2-10,y2-9,x2+10,y2+9,0);
  777.           x2 = x1;
  778.           y2 = y1;
  779.           x1 = x;
  780.           y1 = y;
  781.           fillelip(x1,y1,10,8,2);
  782.           if(y1 > 175 && x1 >= 50 && x1 <= 130) setpals(palete4);
  783.               else setpals(palete2);
  784.       }  
  785.     }
  786.     setmod(3);
  787.  }
  788.  
  789.  
  790.  
  791. ***************end file MOVERM.C**************
  792. ***************begin file INTEST.ASM**********
  793. _TEXT    SEGMENT  BYTE PUBLIC 'CODE'
  794. _TEXT    ENDS
  795. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  796. _DATA    ENDS
  797. CONST    SEGMENT  WORD PUBLIC 'CONST'
  798.  
  799. CONST    ENDS
  800. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  801.  
  802. _BSS    ENDS
  803. DGROUP    GROUP    CONST, _BSS, _DATA
  804.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES:  DGROUP
  805. _TEXT      SEGMENT
  806.  
  807.  
  808. ;intest.asm
  809. ;if there is no input returns 0
  810. ;if there is input it returns 255
  811.  
  812. intest          PROC      FAR
  813. PUBLIC           intest
  814.           mov       ah,0bh
  815.           int       21h
  816.           xor       ah,ah
  817.           ret
  818. intest   endp
  819.  
  820.  
  821. _TEXT    ENDS
  822. END
  823.  
  824.  
  825. **************end file INTEST.ASM***************
  826. **************begin file SLUGS.FOR**************
  827. $storage:2
  828. $include:'egafort.h'
  829.         IMPLICIT INTEGER*2 (I-N)
  830.         CHARACTER*10 IZC
  831.     DIMENSION JCOL(11)
  832.         WRITE(*,*)' Demo program for EGA.'
  833.         WRITE(*,*)' To begin hit return'
  834.         READ(*,1000)IZC
  835. 1000    FORMAT(A10)
  836.         IDRAW=0
  837.         CALL SETMOD(16)
  838.         CALL ZSETUP
  839. 1       DO 2 I=1,11
  840. 2           JCOL(I)=0
  841.         CALL RECTFILL(0,0,639,349,0)
  842.         DO 5  I=1,11
  843. 3        ICOL=RAN()*25.+1.1
  844.         DO 4 J=1,11
  845. 4            IF(ICOL.EQ.JCOL(J))GOTO 3
  846.         JCOL(I)=ICOL
  847.             IF(RAN().GT..6)THEN
  848.               CALL BLOT(ICOL)
  849.         ELSE
  850.                  CALL SLUG(ICOL)
  851.             ENDIF
  852. 5    CONTINUE
  853.         CALL SLEEP(4)
  854.         GOTO 1
  855.     END
  856.     SUBROUTINE BLOT(ICOL)
  857.     IMPLICIT INTEGER*2 (I-N)
  858.         IXCEN=639.*RAN()
  859.     IYCEN=349.*RAN()
  860.     DO 1 I=1,25
  861.           IRAD=4.+12.*RAN()
  862.         RADIUS=70.*RAN()
  863.         ANG=6.28*RAN()
  864.         IX=RADIUS*SIN(ANG)
  865.         IY=.8*RADIUS*COS(ANG)
  866.         CALL FCIRC(IXCEN+IX,IYCEN+IY,IRAD,ICOL)
  867. 1    CONTINUE
  868.     RETURN
  869.     END
  870.     SUBROUTINE SLUG(ICOL)
  871.         IMPLICIT INTEGER*2 (I-N)
  872.     DIMENSION WIDTH(12),SINTAB(0:32)
  873.         DATA IFIRST/0/
  874.         IF(IFIRST.EQ.0)THEN
  875.             DO 1 I=0,32
  876. 1           SINTAB(I)=SIN(3.1415926*I/16.)
  877.             IFIRST = 1
  878.         ENDIF
  879.     DO 2 I=1,12
  880. 2    WIDTH(I)=5.05*RAN()
  881.     IX=320.+160.*RAN()
  882.     IY=175.+90.*RAN()
  883.     DTHET=6.28*RAN()
  884.     DR=1.5+2.5*RAN()
  885.     DX=DR*SIN(DTHET)
  886.     DY=DR*COS(DTHET)
  887.     DIST=0.
  888.     DIST2=0.
  889.     DO 5 I=1,60
  890.     DTHET=1.6*RAN()
  891.     IF(DTHET.LT..8)DTHET=DTHET-1.6
  892.     CCOS=.05*COS(DTHET)
  893.     SSIN=.05*SIN(DTHET)
  894.     DDX=DX*CCOS+DY*SSIN-.05*DX
  895.     DDY=DY*CCOS-DX*SSIN-.05*DY
  896.     DO 4 J=1,20
  897.          DX=DX+DDX
  898.         DY=DY+DDY
  899.         IX2=IX+DX
  900.         IY2=IY+DY
  901.         DIST2=DIST2+DX
  902.         DIST=DIST+DR
  903.         IF(DIST.GE.1.3)THEN
  904.               DIST=0.
  905.             WD=0.
  906.             DO 3 LL=1,6
  907.                     MSIN = IAND(IFIX(DIST2*WIDTH(LL+6)),31)
  908. 3                WD=WD+WIDTH(LL)*SINTAB(MSIN)
  909.             IWD=ABS(WD)+4.
  910.             CALL FCIRC(IX,IY,IWD,ICOL)
  911.             ENDIF
  912.         IX=IX2
  913.         IY=IY2
  914.         IF(IX.GT.690)IX=IX-750
  915.         IF(IY.GT.400)IY=IY-450
  916.         IF(IX.LT.-50)IX=IX+750
  917.         IF(IY.LT.-50)IY=IY+450
  918. 4        CONTINUE
  919.         IF(INTEST().NE.0)THEN
  920.             CALL SETMOD(3)
  921.             STOP
  922.         ENDIF
  923. 5    CONTINUE
  924.     RETURN
  925.     END
  926.         FUNCTION RAN()
  927.         IMPLICIT INTEGER*4 (L)
  928.         IMPLICIT INTEGER*2 (M-N)
  929.         DIMENSION M(2)
  930.         EQUIVALENCE (M(1),L2)
  931.         DATA IFIRST/0/
  932.         IF(IFIRST.EQ.0)THEN
  933.             CALL GETTIM(ID1,ID2,ITT2,ITT1)
  934.             L1=ITT1+100*ITT2
  935.             IF(MOD(L1,2).EQ.0)L1=L1+1
  936.             IFIRST = 1
  937.         ENDIF
  938.         L2=L1
  939.         M(2)=0
  940.         L2=L2*259
  941.         M(2)=0
  942.         RAN=L2/65536.
  943.         L1=L2
  944.         RETURN
  945.         END
  946.         SUBROUTINE FCIRC(IX,IY,ISIZ,ICOL)
  947.         IMPLICIT INTEGER*2 (I-N)
  948.         DIMENSION ICOLSO(46),ICOLSI(46)
  949.         DATA ICOLSO/1,1,1,1,1,1,1,1,
  950.      1              2,2,2,2,3,3,
  951.      2              4,4,4,4,4,4,4,
  952.      3              5,5,5,6,6,6,6,6,6,
  953.      4              7,8,8,8,8,
  954.      5              9,9,9,9,9,
  955.      6              12,12,12,12,12,13/
  956.         DATA ICOLSI/2,6,7,9,10,12,13,14,
  957.      1              1,10,14,15,12,14,
  958.      2              2,7,9,10,12,13,14,
  959.      3              2,7,13,2,3,7,10,14,15,
  960.      4              14,9,11,12,13,
  961.      5              2,7,10,13,14,
  962.      6              2,7,9,10,15,15/
  963.         ISIZ2 = (ISIZ*8)/10
  964.         CALL FILLELIP(IX,IY,ISIZ,ISIZ2,ICOLSI(ICOL))
  965.         CALL ELLIPSE(IX,IY,ISIZ,ISIZ2,ICOLSO(ICOL))
  966.         RETURN
  967.         END
  968.         subroutine sleep(isleep)
  969.         implicit integer*2 (a-z)
  970.         call gettim(ihr,imin,isec,itic)
  971.         isec = isec+isleep
  972.         if(isec.gt.59)then
  973.             isec = isec-60
  974.             imin = imin+1
  975.         endif
  976.         if(imin.gt.59)then
  977.             imin = imin-60
  978.             ihr = ihr+1
  979.         endif
  980.         if(ihr.eq.23)then
  981.             ihr = 0
  982.         endif
  983. 1       call gettim(ihr1,imin1,isec1,itic)
  984.         if(ihr1.ne.ihr.or.imin.ne.imin1.or.isec.ne.isec1)goto 1
  985.         return
  986.         end
  987.  
  988. ****************end file SLUGS.FOR*****************
  989.