home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / animutil / anim13 / makemovy.c < prev    next >
Text File  |  1990-01-13  |  12KB  |  356 lines

  1. /* makemovy.c
  2.  
  3. This program demonstrates the use of Turbo C to make a short movie
  4. (containing only ten frames) which can be viewed using ANIMATE.EXE.
  5. It also demonstrates single versus double buffering of images.
  6. In this example, we show a simple traveling wave.
  7.  
  8. This program can be compiled and executed as is,
  9. but, before you do that:
  10. 1. You need to place header file grafsupp.h in your \TURBOC\INCLUDE
  11.    directory.   grafsupp.h provides definitions and prototypes related
  12.    to functions in grafsupp.c, which make possible device
  13.    independent plotting, i.e. you don't have to worry about pixels.
  14.    Routines in grafsupp.c are modeled after routines in graphics
  15.    written at the National Center for Atmospheric Research (NCAR).
  16. 2. You need to create files HERC.OBJ and EGAVGA.OBJ using Borland's
  17.    BGIOBJ utility before "making" an executable version of this
  18.    program.  Alternatively, you can delete the references to
  19.    registerbgidriver() in this program and references to EGAVGA.OBJ
  20.    and HERC.OBJ in MAKEMOVY.PRJ.  See the Turbo C manuals
  21.    for more information regarding BGIOBJ and registerbgidriver().
  22. 3. You need to select MAKEMOVY.PRJ as the project file.
  23.  
  24. You may find that the functions in grafsupp.c:
  25.  
  26. load_array(),
  27. scale(),
  28. draw_perimeter(),
  29. label_plot(),
  30. and plot_curve()
  31.  
  32. are useful for your own Turbo C graphics.
  33.  
  34. A useful function which I have not utilized in this program is
  35. gprintf(), which appears in Borland's bgidemo.c, which is part of the
  36. Turbo C package.  gprintf() is modeled after printf() but prints
  37. while the screen is in graphics mode, making it very useful to label plots.
  38. I did not include the source for gprintf() because it is copyrighted.
  39. You can use gprintf() in your own programs, but you cannot legally distribute
  40. it in source code form because of the copyright.
  41. If we are lucky, the next version of Turbo C might make gprintf()
  42. a built-in function.
  43.  
  44. Jon Ahlquist, 9 Feb 1989, 12 January 1990.
  45.  
  46. Copyright 1990 by Jon Ahlquist, Department of Meteorology B-161,
  47. Florida State University, Tallahassee, Florida 32306-3034, USA.
  48. Telephone: (904) 644-1558.
  49. Telnet address: ahlquist@metsat.met.fsu.edu (ahlquist@128.186.5.2)
  50.  
  51. This software may be freely copied without charge.
  52. Copyright is made to prevent anyone from trying to impose restrictions
  53. on this software.
  54. All software and documentation is provided "as is" without warranty
  55. of any kind.
  56.  
  57. Development of this material was sponsored by NSF grant ATM-8714674.
  58. */
  59.  
  60. /* Include statements.  Prototypes for:       */
  61. #include <io.h>      /* open(), write()       */
  62. #include <conio.h>   /* clrscr(), getch()     */
  63. #include <ctype.h>   /* toupper()             */
  64. #include <dos.h>     /* delay()               */
  65. #include <fcntl.h>   /* O_RDWR, O_CREAT, O_BINARY */
  66. #include <graphics.h>/* All Borland graphics routines.*/
  67. #include <math.h>    /* cos()                 */
  68. #include <stdio.h>   /* printf(), scanf()     */
  69. #include <stdlib.h>  /* exit()                */
  70. #include <sys\stat.h>/* S_IREAD, S_IWRITE     */
  71. #include <grafsupp.h>/* scale(), XX(x), YY(y) */
  72. /* All header files but grafsupp.h are supplied with Turbo C.
  73. grafsupp.h was written by Jon Ahlquist to accompany
  74. the functions in grafsupp.c.
  75. */
  76.  
  77. #define PI   3.14159265
  78. #define NPTS 200
  79.  
  80. void main(void)
  81. {
  82. int    graph_driver, graph_mode, graph_error,
  83.        num_frames = 10, /* No. of pictures to form the movie. */
  84.        page,            /* Index for page of video memory, either 0 or 1. */
  85.        handle,          /* Handle for file which will hold the movie. */
  86.        iframe, i,       /* Loop indices. */
  87.        num_bit_planes=1;
  88.  
  89. float  x[NPTS], xmin, xmax,
  90.        y[NPTS], ymin, ymax,
  91.        k, c, t,  dt;
  92.  
  93. char   plotfile[81], /* Name of file to hold movie. */
  94.        response;     /* 'y', 'Y', 'n', or 'N' for yes or no. */
  95.  
  96. /* We'll use a pointer, save_raster, to point to the version
  97. of save_raster that we want. */
  98. void   (*save_raster)  (int handle, int page, int num_bit_planes);
  99. void   save_Herc_raster(int handle, int page, int num_bit_planes);
  100. void   save_EGA_raster (int handle, int page, int num_bit_planes);
  101.  
  102. /* Clear the screen, and print an introduction. */
  103. clrscr();
  104. printf(
  105. "This program demonstrates two things:\n"
  106. "1. using Turbo C to make a rasterized movie\n"
  107. "   that can be viewed with ANIMATE, and\n"
  108. "2. single versus double buffering of video images.\n"
  109. "After the movie has been made, it can be viewed using ANIMATE.EXE.\n");
  110.  
  111. /* Get user input. */
  112.  
  113. printf("\nDo you want the movie to be made using EGA graphics?\n"
  114.        "(If not, we'll use Hercules graphics.)\n");
  115. do {
  116.    printf("Type 'y' or 'Y' for yes, 'n' or 'N' for no.\n"
  117.           "Hit the Escape key if you want to abort this program.\n");
  118.    response = toupper(getch());
  119.    if (response == 27) exit(0);
  120.    } while (! ((response=='Y') || (response=='N')));
  121.  
  122. printf("\nName the file you want to hold the rasterized images.\n"
  123.        "The file will occupy about 300 kilobytes.\n");
  124. scanf ("%s", plotfile);
  125.  
  126. handle = open (plotfile, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY,
  127.                S_IWRITE | S_IREAD);
  128. if (handle == -1)
  129.    {
  130.    printf("Unable to open the file.\n"
  131.           "Perhaps you typed an illegal file name or your disc is full.\n");
  132.    exit(1);
  133.    }
  134.  
  135. clrscr();
  136. printf(
  137. "The first half of the pictures will be drawn without double buffering,\n"
  138. "so you will see the drawing as it takes place.\n"
  139. "The second half of the movie will be created using double buffering.\n"
  140. "The motion will look smoother because\n"
  141. "you will not see an image until it is complete.\n\n"
  142. "Notes:\n"
  143. "1. The movie that is stored to disc is not affected by whether the images\n"
  144. "   are created by single or double buffering.\n"
  145. "   When you create a movie, you will probably prefer single buffering,\n"
  146. "   because then you see everything as it is drawn,\n"
  147. "   and that can help with debugging.\n"
  148. "   When you view a finished movie, though, you will certainly want\n"
  149. "   double buffering, such as is offered by ANIMATE.\n"
  150. "2. For Hercules graphics users only:\n"
  151. "   When double buffering starts, you will see that Borland\n"
  152. "   has a bug in its graphics screen clear command.\n"
  153. "   This does not affect the images that are stored to disc, though,\n"
  154. "   so your movie will look fine when viewed with ANIMATE.\n\n"
  155. "Hit any key to start making the movie.\n");
  156.  
  157. getch();
  158.  
  159.  
  160. /* Define limits in space and time. */
  161.     ymax =  1.0;
  162. xmin = 0.; xmax = 2.*PI;
  163.     ymin = -1.0;
  164. k = 3.; /* wavenumber  */
  165. c = 1.; /* phase speed */
  166.  
  167. /* Set dt so that the movie will be one wave period long. */
  168. dt = 2. * PI / (k * c * num_frames);
  169.  
  170.  
  171. /* Initialize graphics. */
  172.  
  173. if (response == 'Y')
  174.    {
  175.    graph_driver = EGA;
  176.    graph_mode   = EGAHI;
  177.    save_raster  = save_EGA_raster;
  178.    }
  179. else
  180.    {
  181.    graph_driver = HERCMONO;
  182.    graph_mode   = HERCMONOHI;
  183.    save_raster  = save_Herc_raster;
  184.    }
  185.  
  186. if (registerbgidriver(EGAVGA_driver) < 0)
  187.    {
  188.    printf("Unable to register EGA/VGA graphics driver.");
  189.    exit(1);
  190.    }
  191. if (registerbgidriver(Herc_driver) < 0)
  192.    {
  193.    printf("Unable to register Hercules graphics driver.");
  194.    exit(1);
  195.    }
  196.  
  197. initgraph (&graph_driver, &graph_mode, "\\turboc");
  198. if ((graph_error = graphresult())  <  0)
  199.    {
  200.    printf("Error while trying to initialize graphics.\n");
  201.    printf("%s\n", grapherrormsg(graph_error));
  202.    exit(1);
  203.    }
  204.  
  205. /* Set scaling factors to create device independent graphics,
  206. so that we do not have to count pixels.
  207. The eight arguments of scale() are explained in the comments
  208. at the beginning of scale().
  209. For users of NCAR graphics, the arguments for scale() are the same
  210. as the first eight arguments to Fortran subroutine SET
  211. of the NCAR graphics package. */
  212. scale( 0., 1., 0.25, 0.75,  xmin, xmax, ymin, ymax);
  213.  
  214.  
  215. /* Load the x array. */
  216. load_array(x, NPTS, xmin, xmax);
  217.  
  218.  
  219. /* Make the movie frame by frame. */
  220. page = 0;
  221. for (iframe = 0, t = 0.; iframe < num_frames; iframe++, t += dt)
  222.    {
  223.    /* Use single buffering for the first half of the movie,
  224.    then use double buffering. */
  225.    if (iframe < (num_frames/2))
  226.       page = 0; /* The first video page is page 0. */
  227.    else /* Toggle the page between 0 & 1 for double buffering. */
  228.       page = 1 - page;
  229.  
  230.    setactivepage(page);
  231.    cleardevice();
  232.  
  233.    /* Draw a box around the plotting domain, add tick marks,
  234.    and lable the plot. */
  235.    draw_perimeter(4, 2, 2, 2);
  236.    label_plot("Traveling wave", "x axis", "Wave amplitude");
  237.  
  238.    /* Load the y array. */
  239.    for (i=0; i< NPTS; i++)  y[i] = cos( k*(x[i]-c*t) );
  240.  
  241.    /* Plot the function. */
  242.    plot_curve(x, y, NPTS);
  243.  
  244.    /* Display and save the plot. */
  245.    setvisualpage(page);
  246.    save_raster(handle, page, num_bit_planes);
  247.    }
  248.  
  249. closegraph();
  250. close (handle);
  251.  
  252. printf(
  253. "To view the movie you have just made, type ANIMATE and hit the Enter key.\n"
  254. "Select 'r' for replay of rasterized images.\n"
  255. "Enter  %s  as the first file.\n"
  256. "Enter DONE as the second file.\n"
  257. "Answer no to the question about saving the movie.\n"
  258. "Then watch the movie.\n"
  259. "Note that the motion will look endless because the movie\n"
  260. "will be repeated until you hit the Escape key.\n\n"
  261. "Good luck!\n", plotfile);
  262. } /* End of main(). */
  263.  
  264. /**********************************************************************/
  265.  
  266. void save_Herc_raster(int handle_out, int page, int num_bit_planes)
  267.  
  268. /* This function stores a Hercules image to disc in rasterized form,
  269. i.e. pixel by pixel.
  270.  
  271.  
  272. Variable        Meaning
  273.  
  274. handle_out      Handle to the file to which the image will be written.
  275.  
  276. page            Video page to be saved, either 0 or 1.
  277.  
  278. num_bit_planes  Unused dummy variable included to provide consistency with
  279.                 save_EGA_raster().
  280.  
  281.  
  282. Jon Ahlquist, 22 July 1988, 1 Dec 1989.
  283. */
  284.  
  285. {
  286. #define  NBYTES_HERC 32768U /* Number of bytes in a Hercules image. */
  287.  
  288. unsigned  nbytes_written;
  289. void far  *fptr;
  290.  
  291. /* Define the address on the grahics board from which the image will
  292. be read. */
  293. fptr = page ? (void far *) 0xb8000000L : (void far *) 0xb0000000L;
  294.  
  295. nbytes_written = _write(handle_out, fptr, NBYTES_HERC);
  296. if (nbytes_written < NBYTES_HERC)
  297.    {
  298.    closegraph();
  299.    printf("Can't save image.  Disc is probably full.\n");
  300.    exit(1);
  301.    }
  302. } /* End of save_Herc_raster().
  303. Don't worry about a compilation warning saying that num_bit_planes is never
  304. used.  num_bit_planes is not needed by save_Herc_raster() and was included
  305. only so that the call to save_Herc_raster() would be like the call to
  306. save_EGA_raster, where num_bit_planes is required. */
  307.  
  308. /**************************************************************************/
  309.  
  310. void save_EGA_raster(int handle, int page, int num_bit_planes)
  311.  
  312. /* This function stores an EGA image to disc in rasterized form,
  313. i.e. pixel by pixel.
  314.  
  315. Variable:       Meaning:
  316. handle          Handle to the file to which the image will be written.
  317. page            Video page to be saved, either 0 or 1.
  318. num_bit_planes  Number of bit planes to store.
  319.                 Any value between 1 and 4, inclusive, is acceptable.
  320.  
  321. Jon Ahlquist, 22 July 1988, 1 Dec 1989.
  322. */
  323.  
  324. {
  325. #define  ONE          0x01
  326. #define  NBYTES_EGA 28000U /* Number of bytes in an EGA bit plane. */
  327.  
  328. int      bit_plane;
  329. unsigned nbytes_written;
  330. void far *fptr;
  331.  
  332.  
  333. /* Define the address on the grahics board from which the image will
  334. be read. */
  335. fptr = page ? (void far *) 0xa8000000L : (void far *) 0xa0000000L;
  336.  
  337. /* Tell the graphics board that one or more bit planes will be read. */
  338. outportb(0x3ce, 4);
  339.  
  340. /* Loop through the bit plane(s) and write the image to the output file. */
  341. for (bit_plane = 0; bit_plane < num_bit_planes; bit_plane++)
  342.    {
  343.    /* Toggle the bit plane from which the image will be taken. */
  344.    outportb(0x3cf, bit_plane);
  345.  
  346.    /* Write the image to the output file. */
  347.    nbytes_written = _write(handle, fptr, NBYTES_EGA);
  348.    if (nbytes_written < NBYTES_EGA)
  349.       {
  350.       closegraph();
  351.       printf("Can't save image.  Disc is probably full.\n");
  352.       exit(1);
  353.       }
  354.    }
  355. } /* End of save_EGA_raster(). */
  356.