home *** CD-ROM | disk | FTP | other *** search
- From: mcdonald@uxe.cso.uiuc.edu (J.D. McDonald )
- Newsgroups: comp.sources.misc
- Subject: v02i023: EGAFAST IBM-PC Graphics Package, Part 2/2
- Message-ID: <7134@ncoast.UUCP>
- Date: 26 Jan 88 04:30:40 GMT
- Approved: allbery@ncoast.UUCP
-
- Comp.sources.misc: Volume 2, Issue 23
- Submitted-By: J.D. McDonald <mcdonald@uxe.cso.uiuc.edu>
- Archive-Name: egafast/Part2
-
- due to the size, distribution is in two parts
- This is part 2.
-
- *********begin second copy of READ.ME*************
- This is a very simple graphics package for the EGA and VGA. It draws the
- basic primitives of lines, ellipses, filled rectangles, filled ellipses,
- and text (two sizes and user defined). It is written to get the ultimate
- in high speed possible while drawing in the set/reset mode. It can be
- called from Microsoft C and Fortran, or any language including assembler
- which follows their calling conventions.
- Here is a list of the included files:
-
- CLIPLINE C Source code for clipped line routine.
- EGAFORT H Header file for subroutine prototypes for Fortran.
- EGAGRA ASM The main graphics package source.
- EGAGRA DOC Documentation.
- EGATEST C A test program to verify correct compilation.
- ELLIPSE C Source code for ellipse drawers.
- GRAFEX1 C Example program that draws a star.
- GRAFEX2 C Example program that uses user-defined patterns.
- INTEST ASM Assembler subroutine for SLUGS.FOR
- MACROS AH Header file for EGAGRA.ASM which defines memory model.
- MOVERM C Example program for plane masking.
- MOVERS C Example program for page swapping and plane masking.
- SLUGS FOR Example program in Fortran whose results look nice.
-
- Some of the code in this package is patterned after that of U.E.Kruse of
- the U. of I. Physics department. The grafex1 demo program generates
- essentially the same pattern as the one of the same name in the package
- by Scott Snyder of caltech recently posted on the net. The macros.ah
- is also from his package.
-
- Your comments are welcome, especially if you see anything faster.
-
- Doug McDonald
- University of Illinois
- 505 S. Matthews
- Urbana Ill. 61801
- (mcdonald@uiucuxe or mcdonald@uxe.cso.uiuc.edu)
-
-
- ***********end second copy of READ.ME***********
- ***********begin file ELLIPSE.C*****************
- /* Draw an ellipse with width irx and height iry */
- /* from a routine by Tim Hogan in Dr. Dobb's Journal May '85 p.40 */
- /* Improved by calculating increments incrementally, thus removing all */
- /* multiplies from the loops. These multiplies were very bad since they */
- /* were (long)*(long). This code, when compiled by Microsoft C Version 4,*/
- /* can't be significantly improved by hand optimization. */
- /* Written Sept. 7, 1987 by J.D. McDonald (public domain) */
-
- static long alpha, beta, alpha2, alpha4, beta2, beta4, d;
- static long ddx, ddy, alphadx, betady;
- static int dy, dx;
-
- extern void e_start(); /* Starts off by writing right and left
- * points */
- extern void e_xd(); /* Moves one step to lower x (in all 4 quadrants)*/
- extern void e_xdyu(); /* Moves to lower x, higher y */
- extern void e_yu(); /* Moves to higher y */
-
- ellipse(x, y, irx, iry, c)
- int x, y, irx, iry;
- unsigned c;
- {
-
- beta = (long) irx *(long) irx;
- alpha = (long) iry *(long) iry;
-
- if (alpha == 0L)
- alpha = 1L;
- if (beta == 0L)
- beta = 1L;
-
- dy = 0;
- dx = irx;
- alpha2 = alpha << 1;
- alpha4 = alpha2 << 1;
- beta2 = beta << 1;
- beta4 = beta2 << 1;
- alphadx = alpha * dx;
- betady = 0;
- ddx = alpha4 * (1 - dx);
- ddy = beta2 * 3;
-
- d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha);
- e_start(x - dx, x + dx, y, c);
-
- do {
- if (d >= 0) {
- d += ddx;
- dx--;
- alphadx -= alpha;
- ddx += alpha4;
- e_xdyu();
- } else
- e_yu();
- d += ddy;
- dy++;
- betady += beta;
- ddy += beta4;
- } while (alphadx > betady);
-
- d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1)
- + beta * (1 - alpha2);
- ddx = alpha2 * (3 - (dx << 1));
- ddy = beta4 * (1 + dy);
-
- do {
- if (d <= 0) {
- d += ddy;
- ddy += beta4;
- dy++;
- e_xdyu();
- } else
- e_xd();
- d += ddx;
- ddx += alpha4;
- dx--;
- } while (dx > 0);
- }
-
- fillelip(x, y, irx, iry, c)
- int x, y, irx, iry;
- unsigned c;
- {
-
- beta = (long) irx *(long) irx;
- alpha = (long) iry *(long) iry;
-
- if (alpha == 0L)
- alpha = 1L;
- if (beta == 0L)
- beta = 1L;
-
- dy = 0;
- dx = irx;
- alpha2 = alpha << 1;
- alpha4 = alpha2 << 1;
- beta2 = beta << 1;
- beta4 = beta2 << 1;
- alphadx = alpha * dx;
- betady = 0;
- ddx = alpha4 * (1 - dx);
- ddy = beta2 * 3;
-
- d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha);
- rectfill(x - dx, y, x + dx, y, c);
-
- do {
- if (d >= 0) {
- d += ddx;
- dx--;
- alphadx -= alpha;
- ddx += alpha4;
- }
- d += ddy;
- dy++;
- betady += beta;
- ddy += beta4;
- rectfill(x - dx, y + dy, x + dx, y + dy, c);
- rectfill(x - dx, y - dy, x + dx, y - dy, c);
- } while (alphadx > betady);
-
- d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1)
- + beta * (1 - alpha2);
- ddx = alpha2 * (3 - (dx << 1));
- ddy = beta4 * (1 + dy);
-
- do {
- dx--;
- if (d <= 0) {
- d += ddy;
- ddy += beta4;
- dy++;
- rectfill(x - dx, y + dy, x + dx, y + dy, c);
- rectfill(x - dx, y - dy, x + dx, y - dy, c);
- }
- d += ddx;
- ddx += alpha4;
- } while (dx > 0);
- }
-
- ***********end file ELLIPSE.C*******************
- ***********begin file CLIPLINE.C****************
- /*routine to plot clipped line*/
- clipline(x1,y1,x2,y2,icol)
- int x1,y1,x2,y2,icol;
- {
- int x3, y3, x4, y4;
- if(clip_ln(x1,y1,&x3,&y3,x2,y2)){
- if(clip_ln(x2,y2,&x4,&y4,x3,y3))
- zline(x4,y4,x3,y3,icol);
- }
- }
-
- /* routine to clip one endpoint of a line */
- /* to clip to a rectangle instead of the screen, change MINX, MAXX, and MINY
- to input parameters instead of defines, and fix maxy also */
- #define MINY 0
- #define MINX 0
- #define MAXX 639
- extern int max_lin(void);
- int clip_ln(x1,y1,xc,yc,x2,y2)
- int x1,y1,x2,y2,*xc,*yc;
- {
- int delx,dely,maxy;
- long templ;
- maxy = max_lin() - 1;
- *xc=x1;
- *yc=y1;
- if ( y1 >= MINY && y1 <= maxy && x1 >= MINX && x1 <= MAXX)
- return(1);
- dely=y1-y2;
- delx=x1-x2;
- if (y1 > maxy || y1 < MINY) {
- if (y1 > maxy) {
- if (y2 > maxy) return (0);
- *yc=maxy;
- } else {
- if (y2 < MINY ) return(0);
- *yc=MINY;
- }
- templ = (long)(*yc-y2)*(long)delx;
- *xc=templ/dely+x2;
- if (*xc >= MINX && *xc <= MAXX) {
- return(1);
- }
- }
- dely=*yc-y2;
- delx=*xc-x2;
- if (*xc > MAXX || *xc < MINX) {
- if (*xc > MAXX) {
- if (x2 > MAXX ) return(0);
- *xc=MAXX;
- }
- else {
- if (x2 < MINX ) return(0);
- *xc=MINX;
- }
- templ = (long)(*xc-x2)*(long)dely;
- *yc=templ/delx+y2;
- if (*yc >= MINY && *yc <= maxy) {
- return(1);
- }
- }
- return(0);
- }
-
- *********************end file CLIPLINE.C*************
- *********************begin file GRAFEX1.C************
-
- #include <stdio.h>
- #include <math.h>
-
- #define pi 3.1415926
-
- main()
- {
- int n, i, j, d;
- unsigned color;
- struct {
- int x, y;
- } vert[32];
-
- do {
- printf("Enter number of vertices, 4 to 32: ");
- scanf("%d", &n);
- if ( n < 4 || n > 32 ) printf("Try again!\n");
- } while( n < 4 || n > 32);
-
- setmod(16); /*change ega to graphics mode*/
- zsetup(); /*initialize drawing package...bios drawing stops working */
-
- /* space n vertices equally on an ellipse that fits nicely on the screen */
-
- for (i=0; i<n; i++) {
- vert[i].x = 319.49 + 200.*sin(2*pi/n*i);
- vert[i].y = 174.49 - 160.*cos(2*pi/n*i);
- }
-
- /*
- * draw the figure. the colors are selected so that points that are the
- * same distance from each other on the ellipse have the same color.
- */
-
- for (i=0; i<n; i++)
- for (j=i+1; j<n; j++) {
- d = j-i;
- if (d > n/2) d = n - d;
- color = (float)d/(n/2+1)*15 + 1;
- zline(vert[i].x, vert[i].y, vert[j].x, vert[j].y, color);
- }
-
- /* wait... */
-
- curmod(); /*reset to allow bios to draw letters */
- printf("Press any key...");
- getch();
-
- /* and clean up. */
-
- setmod(3); /*back to text mode*/
- }
-
- *******************end file GRAFEX1.C***************
- *******************begin file GRAFEX2.C*************
- char bigsym[5] = {60,102,195,102,60};
- char littlesym[5] = {0,24,60,24,0};
-
- main()
- {
- char *cptr;
- int i, ix, iy, icount, icolor;
- setmod(16); /* set graphics mode*/
- zsetup(); /*initialize graphics package*/
- for (icount = 0 ; icount < 10000 ; icount++){
- ix = rand()/51;
- iy = rand()/93;
- icolor = rand() & 7;
-
- /* symbol(ix,iy,iheight,icolor,symbol) draws a rectangular pattern 8 bits
- wide and iheight bits high with upper left corner at ix,iy in color
- *symbol. The patterns in this program are
- bigsum littlesym
-
- ..****.. ........
- .**..**. ...**...
- **....** ..****..
- .**..**. ...**...
- ..****.. ........
- The result is a little spot with a bright center and a dim border. */
-
-
- symbol(ix,iy,5,icolor+8,littlesym);
- symbol(ix,iy,5,icolor,bigsym);
- }
- for(i = 0 ,cptr = "Hit any key to quit."; *cptr ;i++)
- llettr(i << 3,0,*cptr++,15);
-
- while(!kbhit());
- getch();
- setmod(3); /*go back to text mode*/
- }
-
-
- *******************end file GRAFEX2.c***************
- *******************begin file EGAGRA.DOC************
- EGAGRA - Fast Graphics Routines for the EGA or VGA
-
- Egagra is as set of high speed graphics routines for the IBM EGA
- and VGA graphics systems. It runs on these in the BIOS modes 15, 16, and 18,
- which are 350X640 monochrome, 350X640 16 color and 480 X 640 16 color
- modes respectively. It provides routines for lines, filled rectangles,
- and open and filled ellipses, as well as two sizes of text and a routine
- to display text-like patterns. The routines (including the text ones) all
- draw over any previous pattern in a given area; the text ones do not result
- in a black rectangle around the text. The text drawing routines also allow
- text to be places to any arbitrary pixel position. A mask function allows
- writing to one or more bit planes while leaving others uneffected.
- All of these routines are written in assembler in the calling sequence
- of Microsoft C, except for the ellipses and the clipped-line routine which
- are in C. A header file is provided so they can be used from Microsoft
- Fortran without changes. A set of demonstration programs in C and Fortran
- is included.
- The first subroutine called when using this package is setmod(n),
- where n is the desired graphics mode. This simply calls the ROM BIOS to
- set the desired mode; it still leaves the system in a text state so that
- the io routines of the language used are operational. The actual graphics
- calls (including text routines slettr, llettr and symbol) must be preceeded
- by a call to zsetup. After this call, language io to the console, such
- as printf or scanf in C or read and write to the console in Fortran, results
- in garbage. However, a call to curmod then re-enables language io. In
- other words, between calls to zsetup and curmod you use these graphics
- routines, while after curmod calls you use the facilities of the programming
- language. (Of course, there is no effect on io to disk files or COM ports.)
- At the end of you program there must be a call to reset the BIOS mode to
- the original value, usually 2, 3, or 7. If this isn't done, DOS will write
- garbage to the screen, a problem which can be fixed from DOS by using
- MODE CO80, MODE BW80 or MODE MONO as desired. When using an EGA with the
- minimum memory on an IBM monochrome display in mode 15, use colors 0,
- 3, 12 and 15 only.
- All the drawing routines except zpoint clip the drawing to the
- horizontal confines of the screen. The rectangle and filled ellipse ones
- clip vertically also. The rest simply draw on the portion of the screen
- buffer which is not mapped to the screen. A really long line or big ellipse
- will "wrap around". A routine called clipline draws a line clipped to the
- screen area.
- Since these routines use the set/reset register of the ega, and the
- BIOS doesn't, if you ctrl-break out of one of them into DOS, screen
- garbage results. You should therefore put the zsetup/curmod calls closely
- around the actual drawing routines, and to be sure, trap the MS-DOS
- break interrupt and call a setmod(orig_mode) in the inteppupt routine.
- The following description is for the C versions of the subroutines.
- The calling sequence for Fortran can be seen in the header file EGAFORT.H,
- which should be included in any Fortran routine using them. The routines
- will work in any memory model, but must be compiled separately for each.
- To make a library for a given model, perform the following steps:
- 1. Edit MACROS.AH to define the appropriate memory model.
- 2. Use MASM on egagra.asm.
- 3. Compile ELLIPSE.C with the appropriate memory model switch,
- either /AS /AM /AC or /AL for small, medium, compact, or large.
- ALSO use the /Fa switch. This will generate an ellipse.asm file.
- 4. Use MASM on ellipse.asm.
- 5. Repeat steps 4 & 5 on clipline.c.
- 6. Use LIB to combine the three .obj files into a library
- egagrafs.lib, egagrafm.lib, egagrafc.lib, or egagrafl.lib as
- appropriate.
- The contortions involved in making a .asm file out of ellipse and clipline
- and THEN assembling it are needed ONLY if you wish to use the library file
- with Fortran. This is done so that the C run-time library will not be
- automatically called, even if using Fortran. The ellipse routines don't
- need any run-time routines out of the C libraries, as all the necessary
- ones exist in Fortran. If you NEVER use Fortran, just compile ellipse.c
- directly with the correct memory-model switch. If you only have a Fortran
- compiler, you're out of luck with ellipses and clipped lines unless you
- translate ellipse.c and clipline.c into Fortran (which is perfectly easy.)
-
- Subroutine Descriptions
-
- Utility Routines
-
- setmod(i)
- int i;
- This routine calls the BIOS to put the graphics adapter
- into mode i.
-
-
- zsetup()
- This routine initializes graphics drawing mode (see
- text above). Zsetup is cancelled by curmod. The special
- graphics drawing mode used by this package is slightly
- different from the normal bios mode with the same resolution.
-
- curmod()
- This routine returns the adapter to normal bios drawing
- mode, allowing BIOS calls to produce text.
-
- setpal(ipal,icol)
- int ipal, icol;
- This routine changes the color produced by call a drawing
- routine with color ipal to the physical color icol.
- Ipal is a number from 0 to 15 whereas icol can vary from
- 0 to 63.
-
- setpals(palete)
- char *palete;
- The useage in a C program is
- char pal[17];
- setpals(pal);
- where pal[0] to pal[15] are preset to the value desired
- for the corresponding drawing color. pal[16] is the
- border color; for ega mode it must be set to 0; the
- other 16 values can range from 0 to 63. This call, unlike
- setpal, sets all the 16 colors in one call.
-
- setmask(mask)
- int mask;
- This routine sets the bit map write enable mask. Since this
- is rather cryptic, a bit of explanation is in order.
- Consider a given pixel. Let's say it is presently in color
- 1. If we set mask to 15, which is the default state, and
- write a point at that pixel with color 4, the pixel changes
- to color 4. Set it back to 1. But now set mask to 4. Then
- write color 4. The hardware then allows changes only to the
- 4's bit of the color; the 1's, 2's and 8's bits are write
- protected. Hence the color changes to 5. If we now set mask
- to 11 (1+2+8) and write a color 0, the color, now 5, changes
- to 4, since the 4's bit was protected. For an example
- of the use of this, see the program "movers.c" and "moverm.c",
- which generate exactly the same diaplay. The only difference
- is that "movers.c" also uses page swapping.
-
-
- setdraw(i)
- int i;
- This routine sends all following output to display page i.
- Note that i must be 0 or 1. See the example program
- "movers.c". A page need not be visible to be written to.
- Apparently the VGA mode 18 has only one page.
-
- setdisp(i)
- int i;
- This routine causes page i (0 or 1) to be visible on the
- screen. See the example program "movers.c".
-
-
-
- Text Routines
-
- slettr(ix, iy, ichr, col)
- int ix, iy, ichr, col;
-
- llettr(ix, iy, ichr, col)
- int ix, iy, ichr, col;
-
- These two routines write text. They differ only in that slettr
- draws using the 8 pixel high BIOS character set, while llettr
- uses the ega 14 pixel high set. Ix and iy are the pixel
- location of the upper left corner of the character box. They
- need not be at a normal text cursor position; any value
- -7 < ix < 647 and -14 < iy < (screen height + 13) is OK.
- Ichr is the character; any value in the drawing set will
- work including the values less than 32 and the ones between
- 128 and 255. Character 219 is good for filling a whole
- character box, such as simulating a background color. The
- VGA 8x16 character set could be added by adapting the
- initialization parts of slettr and llettr. I'm going to do
- so when I get a PS/2, and call it xlettr. Adding a 9th
- pixel row would be trickier.
-
-
- symbol(ix,iy,height,col,symb)
- int ix, iy, height, col;
- char *symb;
- This routine operates just like the text routines except
- that it draws a character of height height whose description
- is contained in the array symb. Thus with height = 8
- you can set an arbitrary patten of 256 pixels in an 8x8
- array. You can define your own character set, or use it
- for icons.
-
- Drawing Routines
-
- zline(ix0, iy0, ix1, iy1, col)
- int ix0, iy0, ix1, iy1, col;
-
- This routine draws a line from ix0, iy0 to ix1, iy1 in
- color col. The horizontal extent is restricted to the screen.
-
- clipline(ix0, iy0, ix1, iy1, col)
- int ix0, iy0, ix1, iy1, col;
-
- This routine draws a line from ix0, iy0 to ix1, iy1 in
- color col. It is restricted to the screen.
-
- rectfill(ix0, iy0, ix1, iy1, col)
- int ix0, iy0, ix1, iy1, col;
-
- This routine draws a solid rectangle between diagonally
- opposite corners ix0, iy0 and ix1, iy1 in color col.
- Both horizontal and vertical extents are clipped to the screen.
-
- ellipse(ix0, iy0, irx, iry, col)
- int ix0, iy0, irx, iry, col;
-
- fillelip(ix0, iy0, irx, iry, col)
- int ix0, iy0, irx, iry, col;
-
- These routines draw ellipses centered at ix0, iy0 with
- horizontal and vertical semi-axes irx and iry in color col.
- Ellipse is open, fillelip is solid. The horizontal extent
- is clipped to the screen. For a normal ega monitor,
- iry = .8*irx generates a circle.
-
- These routines were written by J. D. McDonald at the University of
- Illinois and are public domain.
-
- ****************end file EGAGRA.DOC***************
- ****************begin file EGATEST.C**************
- char palete1[] = { 56, 9, 18, 27, 36, 45, 54, 63,
- 0, 1, 2, 3, 4, 5, 6, 7, 0};
- char palete2[] = { 0, 1, 2, 3, 4, 5, 6, 7,
- 56, 9, 18, 27, 36, 45, 54, 63, 0};
- unsigned char pattern[] = {204, 102, 51, 102, 204, 153, 51, 102,
- 204, 102, 51, 102, 204, 153, 51, 102,
- 204, 102, 51, 102, 204, 153, 51, 102 };
-
- main()
- {
- char *cptr;
- int i, j, imode;
- int maxline = 350;
- do {
- printf("Enter mode number, 16 for EGA, 16 or 18 for VGA");
- scanf("%d",&imode);
- } while( imode != 16 && imode != 18);
- if(imode == 18) maxline = 480;
- setmod(imode);
- zsetup();
- for(i = 0 ,cptr = "This should be large brown letters."; *cptr ;i++)
- llettr(i << 3,0,*cptr++,6);
- for(i = 0 ,cptr = "At the upper left corner of the screen."; *cptr ;i++)
- llettr(i << 3,14,*cptr++,6);
- for(i = 0 ,cptr = "\003 \033There should be half a green heart (\003) at"; *cptr ;i++)
- llettr((i << 3)-3,maxline/2-7,*cptr++,2);
- for(i = 0 ,cptr = " the center of each edge of the screen."; *cptr ;i++)
- llettr((i << 3)-3,maxline/2+7,*cptr++,2);
- llettr(316,-7,3,2);
- llettr(316,maxline-7,3,2);
- llettr(636,maxline/2-7,3,2);
- for(i = 0 ,cptr = "This should be small bright blue letters."; *cptr ;i++)
- slettr(i << 3,30,*cptr++,9);
- ellipse(500,100,50,90,3);
- fillelip(500,100,20,20,4);
- for(i = 0 ,cptr = "Small filled red ellipse"; *cptr ;i++)
- llettr(400+(i << 3),196,*cptr++,4);
- for(i = 0 ,cptr = "Large open cyan ellipse"; *cptr ;i++)
- llettr(400+(i << 3),210,*cptr++,3);
- rectfill(100,250,539,300,7);
- zline(99,249,540,249,13);
- zline(99,249,99,301,13);
- zline(99,301,540,301,13);
- zline(540,249,540,301,13);
- zline(99,249,540,301,13);
- zline(99,301,540,249,13);
- for(i = 0 ,cptr = "Gray rectangle with violet border and cross."; *cptr ;i++)
- llettr(142+(i << 3),310,*cptr++,13);
- for(i = 0 ,cptr = "Hit any key."; *cptr ;i++)
- llettr(40+(i << 3),100,*cptr++,7);
- for(i = 0; i < 245; i += 8)symbol(i,50,24,6,pattern);
- for(i = 0 ,cptr = " Yellow text on brown pattern."; *cptr ;i++)
- llettr((i << 3),55,*cptr++,14);
- for(i = 0 ,cptr = "This will appear only in mode 18"; *cptr ;i++)
- llettr((i << 3),390,*cptr++,7);
- zline(0,412,256,412,7);
- while(!kbhit());
- setpals(palete1);
- getch();
- for(i = 0 ,cptr = "Dark and light colors should be reversed."; *cptr ;i++)
- llettr(40+(i << 3),196,*cptr++,7);
- while(!kbhit());
- getch();
- for(i = 0 ,cptr = "The red ellipse should now be green."; *cptr ;i++)
- llettr(40+(i << 3),210,*cptr++,7);
- rectfill(50,480,100,600,7);
- setdraw(1);
- for(i = 0 ,cptr = "This is the second video page."; *cptr ;i++)
- llettr(150+(i << 3),200,*cptr++,7);
- for(i = 0 ,cptr = "Three lines of text, and nothing else,should appear."
- ; *cptr ;i++)llettr(150+(i << 3),215,*cptr++,7);
- for(i = 0 ,cptr = "Hit any key."; *cptr ;i++)
- llettr(150+(i << 3),230,*cptr++,7);
- setpal(4,18);
- while(!kbhit());
- getch();
- setpals(palete2);
- setdisp(1);
- while(!kbhit());
- getch();
- setmod(3);
- }
-
- *****************end file EGATEST.C*****************
- *****************begin file MOVERS.C****************
- #include <math.h>
- #define PI128 3.141585/128.
- char quit_string[] = "Hit any key to quit.";
- char palete1[17] = { 0, 1, 58, 58, 62, 62, 62, 62, 4,
- 7, 4, 4, 4, 4, 4, 4, 0 } ;
- /*This program draws a moving ball with animation done using the page
- swapping method. It is speed limited by the necessity to swap only
- during vertical retrace. */
-
-
- double xs[256], ys[256];
- main()
- {
- int x1, y1, x2, y2, i, icol, j;
- double x, y;
-
- setmod(16);
- zsetup();
- setpals(palete1);
- setmask(15);
- setdraw(0);
- rectfill(0,0,639,349,0);
- for (i = 0; i < 8; i++) {
- rectfill(i*80, 0, i*80+19,349,1);
- rectfill(i*80+40, 0 , i*80+59, 349,8);
- }
- for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
- setdraw(1);
- rectfill(0,0,639,349,0);
- for (i = 0; i < 8; i++) {
- rectfill(i*80, 0, i*80+19,349,1);
- rectfill(i*80+40, 0 , i*80+59, 349,8);
- }
- for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
- setmask(6);
- x2=320;
- y2=175;
- for (i = 0; i < 256; i++) {
- xs[i] = 320.-300.*sin(PI128*i);
- ys[i] = 175.+100.*cos(PI128*i);
- }
- for (i = 0; !kbhit() ; i = (i+1) & 255 ) {
- if( i & 1) {
- setdisp(0);
- setdraw(1);
- } else {
- setdisp(1);
- setdraw(0);
- }
- while( !( inp(0x3da) & 8));
- x= xs[i];
- y= ys[i];
- rectfill(x2-10,y2-9,x2+10,y2+9,0);
- x2 = x1;
- y2 = y1;
- x1 = x;
- y1 = y;
- if(y1 > 175 && x1 >= 50 && x1 <= 130) icol = 2;
- else icol = 4;
- fillelip(x1,y1,10,8,icol);
- }
- setdisp(0);
- setmod(3);
- }
-
-
- **************end file MOVERS.C***************
- **************begin file MOVERM.C*************
- #include <math.h>
- #define PI128 3.141585/128.
- char quit_string[] = "Hit any key to quit.";
- char palete1[17] = { 0, 1, 0, 1, 62, 62, 62, 62, 4,
- 7, 4, 4, 4, 4, 4, 4, 0 } ;
- char palete2[17] = { 0, 1, 62, 62, 0, 1, 62, 62, 4,
- 7, 4, 4, 4, 4, 4, 4, 0 } ;
- char palete3[17] = { 0, 1, 0, 1, 58, 58, 58, 58, 4,
- 7, 4, 4, 4, 4, 4, 4, 0 } ;
- char palete4[17] = { 0, 1, 58, 58, 0, 1, 58, 58, 4,
- 7, 4, 4, 4, 4, 4, 4, 0 } ;
- /*This program draws a moving ball with animation done using the palete
- swapping method. It is speed limited by the necessity to swap only
- during vertical retrace. */
-
- double xs[256], ys[256];
-
- main()
- {
- int x1, y1, x2, y2, i;
- double x, y;
-
- setmod(16);
- zsetup();
- setpals(palete1);
- setmask(15);
- for (i = 0; i < 8; i++) {
- rectfill(i*80, 0, i*80+19,349,1);
- rectfill(i*80+40, 0 , i*80+59, 349,8);
- }
- for (i = 0; i < 256; i++ ) {
- xs[i] = 320.-300.*sin(PI128*i);
- ys[i] = 175.+100.*cos(PI128*i);
- }
- x2=320;
- y2=175;
- for (i = 0; i < 20; i++) llettr(i*9, 16, quit_string[i], 9);
- for (i = 0; !kbhit() ; i = (i+1) & 255 ) {
- x= xs[i];
- y= ys[i];
- if( i & 1) {
- setmask(4);
- rectfill(x2-10,y2-9,x2+10,y2+9,0);
- x2 = x1;
- y2 = y1;
- x1 = x;
- y1 = y;
- fillelip(x1,y1,10,8,4);
- if(y1 > 175 && x1 >= 50 && x1 <= 130) setpals(palete3);
- else setpals(palete1);
- } else {
- setmask(2);
- rectfill(x2-10,y2-9,x2+10,y2+9,0);
- x2 = x1;
- y2 = y1;
- x1 = x;
- y1 = y;
- fillelip(x1,y1,10,8,2);
- if(y1 > 175 && x1 >= 50 && x1 <= 130) setpals(palete4);
- else setpals(palete2);
- }
- }
- setmod(3);
- }
-
-
-
- ***************end file MOVERM.C**************
- ***************begin file INTEST.ASM**********
- _TEXT SEGMENT BYTE PUBLIC 'CODE'
- _TEXT ENDS
- _DATA SEGMENT WORD PUBLIC 'DATA'
- _DATA ENDS
- CONST SEGMENT WORD PUBLIC 'CONST'
-
- CONST ENDS
- _BSS SEGMENT WORD PUBLIC 'BSS'
-
- _BSS ENDS
- DGROUP GROUP CONST, _BSS, _DATA
- ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
- _TEXT SEGMENT
-
-
- ;intest.asm
- ;if there is no input returns 0
- ;if there is input it returns 255
-
- intest PROC FAR
- PUBLIC intest
- mov ah,0bh
- int 21h
- xor ah,ah
- ret
- intest endp
-
-
- _TEXT ENDS
- END
-
-
- **************end file INTEST.ASM***************
- **************begin file SLUGS.FOR**************
- $storage:2
- $include:'egafort.h'
- IMPLICIT INTEGER*2 (I-N)
- CHARACTER*10 IZC
- DIMENSION JCOL(11)
- WRITE(*,*)' Demo program for EGA.'
- WRITE(*,*)' To begin hit return'
- READ(*,1000)IZC
- 1000 FORMAT(A10)
- IDRAW=0
- CALL SETMOD(16)
- CALL ZSETUP
- 1 DO 2 I=1,11
- 2 JCOL(I)=0
- CALL RECTFILL(0,0,639,349,0)
- DO 5 I=1,11
- 3 ICOL=RAN()*25.+1.1
- DO 4 J=1,11
- 4 IF(ICOL.EQ.JCOL(J))GOTO 3
- JCOL(I)=ICOL
- IF(RAN().GT..6)THEN
- CALL BLOT(ICOL)
- ELSE
- CALL SLUG(ICOL)
- ENDIF
- 5 CONTINUE
- CALL SLEEP(4)
- GOTO 1
- END
- SUBROUTINE BLOT(ICOL)
- IMPLICIT INTEGER*2 (I-N)
- IXCEN=639.*RAN()
- IYCEN=349.*RAN()
- DO 1 I=1,25
- IRAD=4.+12.*RAN()
- RADIUS=70.*RAN()
- ANG=6.28*RAN()
- IX=RADIUS*SIN(ANG)
- IY=.8*RADIUS*COS(ANG)
- CALL FCIRC(IXCEN+IX,IYCEN+IY,IRAD,ICOL)
- 1 CONTINUE
- RETURN
- END
- SUBROUTINE SLUG(ICOL)
- IMPLICIT INTEGER*2 (I-N)
- DIMENSION WIDTH(12),SINTAB(0:32)
- DATA IFIRST/0/
- IF(IFIRST.EQ.0)THEN
- DO 1 I=0,32
- 1 SINTAB(I)=SIN(3.1415926*I/16.)
- IFIRST = 1
- ENDIF
- DO 2 I=1,12
- 2 WIDTH(I)=5.05*RAN()
- IX=320.+160.*RAN()
- IY=175.+90.*RAN()
- DTHET=6.28*RAN()
- DR=1.5+2.5*RAN()
- DX=DR*SIN(DTHET)
- DY=DR*COS(DTHET)
- DIST=0.
- DIST2=0.
- DO 5 I=1,60
- DTHET=1.6*RAN()
- IF(DTHET.LT..8)DTHET=DTHET-1.6
- CCOS=.05*COS(DTHET)
- SSIN=.05*SIN(DTHET)
- DDX=DX*CCOS+DY*SSIN-.05*DX
- DDY=DY*CCOS-DX*SSIN-.05*DY
- DO 4 J=1,20
- DX=DX+DDX
- DY=DY+DDY
- IX2=IX+DX
- IY2=IY+DY
- DIST2=DIST2+DX
- DIST=DIST+DR
- IF(DIST.GE.1.3)THEN
- DIST=0.
- WD=0.
- DO 3 LL=1,6
- MSIN = IAND(IFIX(DIST2*WIDTH(LL+6)),31)
- 3 WD=WD+WIDTH(LL)*SINTAB(MSIN)
- IWD=ABS(WD)+4.
- CALL FCIRC(IX,IY,IWD,ICOL)
- ENDIF
- IX=IX2
- IY=IY2
- IF(IX.GT.690)IX=IX-750
- IF(IY.GT.400)IY=IY-450
- IF(IX.LT.-50)IX=IX+750
- IF(IY.LT.-50)IY=IY+450
- 4 CONTINUE
- IF(INTEST().NE.0)THEN
- CALL SETMOD(3)
- STOP
- ENDIF
- 5 CONTINUE
- RETURN
- END
- FUNCTION RAN()
- IMPLICIT INTEGER*4 (L)
- IMPLICIT INTEGER*2 (M-N)
- DIMENSION M(2)
- EQUIVALENCE (M(1),L2)
- DATA IFIRST/0/
- IF(IFIRST.EQ.0)THEN
- CALL GETTIM(ID1,ID2,ITT2,ITT1)
- L1=ITT1+100*ITT2
- IF(MOD(L1,2).EQ.0)L1=L1+1
- IFIRST = 1
- ENDIF
- L2=L1
- M(2)=0
- L2=L2*259
- M(2)=0
- RAN=L2/65536.
- L1=L2
- RETURN
- END
- SUBROUTINE FCIRC(IX,IY,ISIZ,ICOL)
- IMPLICIT INTEGER*2 (I-N)
- DIMENSION ICOLSO(46),ICOLSI(46)
- DATA ICOLSO/1,1,1,1,1,1,1,1,
- 1 2,2,2,2,3,3,
- 2 4,4,4,4,4,4,4,
- 3 5,5,5,6,6,6,6,6,6,
- 4 7,8,8,8,8,
- 5 9,9,9,9,9,
- 6 12,12,12,12,12,13/
- DATA ICOLSI/2,6,7,9,10,12,13,14,
- 1 1,10,14,15,12,14,
- 2 2,7,9,10,12,13,14,
- 3 2,7,13,2,3,7,10,14,15,
- 4 14,9,11,12,13,
- 5 2,7,10,13,14,
- 6 2,7,9,10,15,15/
- ISIZ2 = (ISIZ*8)/10
- CALL FILLELIP(IX,IY,ISIZ,ISIZ2,ICOLSI(ICOL))
- CALL ELLIPSE(IX,IY,ISIZ,ISIZ2,ICOLSO(ICOL))
- RETURN
- END
- subroutine sleep(isleep)
- implicit integer*2 (a-z)
- call gettim(ihr,imin,isec,itic)
- isec = isec+isleep
- if(isec.gt.59)then
- isec = isec-60
- imin = imin+1
- endif
- if(imin.gt.59)then
- imin = imin-60
- ihr = ihr+1
- endif
- if(ihr.eq.23)then
- ihr = 0
- endif
- 1 call gettim(ihr1,imin1,isec1,itic)
- if(ihr1.ne.ihr.or.imin.ne.imin1.or.isec.ne.isec1)goto 1
- return
- end
-
- ****************end file SLUGS.FOR*****************
-