home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource Library: Graphics
/
graphics-16000.iso
/
msdos
/
animutil
/
anim13
/
animate1.c
< prev
next >
Wrap
Text File
|
1990-04-03
|
33KB
|
826 lines
/**************/
/* */
/* animate1.c */
/* */
/**************/
/*
Date of most recent change in main() or any of its functions: 3 April 1990.
This program emulates a Tektronix 4010 monochrome graphics display
and can replay files containing rasterized images.
The parameter file which is required by ANIMATE.EXE is ANIMATE.PAR.
A copy of ANIMATE.PAR for EGA/VGA graphics is supplied with the source code.
If you have Hercules monochrome graphics, you can get a Hercules
version of ANIMATE.PAR by renaming ANIMATE.PAR (the EGA version) to
ANIMATE.PAE and by renaming ANIMATE.PAH to ANIMATE.PAR.
Information for users of Turbo C (version 2 or newer) who wish to
modify ANIMATE:
The function "main" is in file ANIMATE1.C, and the functions it calls
are contained in file ANIMATE2.C.
The project file required by Turbo C's MAKE facility is ANIMATE.PRJ.
This program uses Borland's registerbgidriver() function to register
the Hercules and EGA/VGA graphics driver.
This means that you must use Borland's BGIOBJ utility to convert
the Hercules and EGA/VGA graphics drivers into object (.OBJ) files.
To do this, get into your Turbo C directory and type
BGIOBJ HERC and BGIOBJ EGAVGA
Then copy HERC.OBJ and EGAVGA.OBJ into the directory where you intend
to compile this animation program.
Then compile this program using the project file ANIMATE.PRJ.
Jon Ahlquist, 24 Sep 1988, 28 Feb 1989, 1 Jan 1990.
Copyright 1990 by Jon Ahlquist, Department of Meteorology B-161,
Florida State University, Tallahassee, Florida 32306-3034, USA.
Telephone: (904) 644-1558.
Telnet address: ahlquist@metsat.met.fsu.edu (ahlquist@128.186.5.2)
This software may be freely copied without charge.
Copyright is made to prevent anyone from trying to impose restrictions
on this software.
All software and documentation is provided "as is" without warranty
of any kind.
Development of this material was sponsored by NSF grant ATM-8714674.
*/
/***********************/
/* */
/* Include statements. */
/* */
/***********************/
/* Prototypes for: */
#include <conio.h> /* clrscr(). */
#include <ctype.h> /* toupper().*/
#include <dos.h> /* delay(). */
#include <errno.h> /* errno and error messages.*/
#include <fcntl.h> /* Macros for open() */
#include <graphics.h>/* All graphics routines. */
#include <io.h> /* open(), write() */
#include <process.h> /* exit() */
#include <stdio.h> /* fopen(), fwrite(), fread(), fclose(). */
#include <stdlib.h> /* itoa(), max(). */
#include <string.h> /* strnicomp() */
#include <sys\stat.h>/* Definition of S_IREAD and S_IWRITE. */
/**********************/
/* */
/* Define statements. */
/* */
/**********************/
#define MAX_FILES (10)
/* MAX_FILES is the maximum number of files to be opened by this program. */
#define ESC '\x1b'
/* ASCII 'Escape' character. */
#define Ctrl_C '\x03'
/* ASCII Control C */
/*****************************/
/* */
/* Start the main procedure. */
/* */
/*****************************/
void main(void)
{
int display_frame_num, /* 1 if frame numbers should be displayed,
0 if not. */
EOF_flag, /* 1 if an EOF was hit while trying to load
an image,
0 if the image was loaded ok. */
first_frame_save, /* Number of first frame to be saved in
rasterized form if rasterize==1. */
first_loop, /* 1 during the first loop through
the pictures,
0 on any subsequent loops. */
frame_num, /* Index for frame number. */
frame_num_color, /* Palette color to be used for frame
number counter. */
frame_num_color_default, /* Default frame_num_color. */
graph_driver, /* Either EGA or HERCMONO. */
graph_driver_default, /* Default graph_driver */
graph_error, /* Error code from graphresult(). */
graph_mode, /* Either EGAHI or HERCMONOHI. */
graph_mode_default,/* Default graph_mode. */
handle_background = 0,
/* Handle to read rasterized image
onto which each Tektronix graph is drawn.
"Handle" refers to the integer returned
by open() which is then used by read()
and/or write().
'handle_background' is initialized
here only to prevent a compilation
warning about possible use before
initialization. */
handle[MAX_FILES], /* Handles to rasterized image files. */
handle_out = 0, /* Handle for writing rasterized images.
'handle_out' is initialized here only to
prevent a compilation warning about
possible use before initialization. */
ifile, /* Loop index for counting files. */
last_frame_save, /* Number of last frame to be saved in
rasterized form if rasterize==1. */
last_page, /* 1 for double bufffereing of images,
0 for no double buffering. */
last_file = -1, /* No. of last input file. The input files
are numbered beginning with zero.
last_file is initialized to -1 so that
the MAIN_MENU section of the program will
respond correctly. */
num_bit_planes, /* No. of bit planes to load or save when
handling rasterized images.
EGA graphics have up to 4 bit planes.
This parameter is ignored for Hercules
graphics, which has only 1 bit plane. */
num_bit_planes_default=1, /* Default num_bit_planes. */
page, /* Counter for video pages: 0 or 1. */
pause, /* 0 for no pause at end of picture loop,
1 for a brief pause before going back
to restart the loop of rasterized
pictures. */
rast_background=0, /* 1 to read a rasterized background image,
such as a map, onto which is plotted
each Tektronix graph.
0 for no background image to be part of
each Tektronix graph. */
rasterize = 0, /* 1 to save images in rasterized form.
0 for no save of rasterized images. */
single_step, /* 1 if images should be shown one at a time
by hitting the 'n' or 'N' (next) key,
0 if pictures should be looped
automatically. */
xloc, yloc, /* Pixel coordinates at which the frame
number is displayed if
display_frame_num == 1. */
xloc_default, yloc_default, /* Default xloc and yloc. */
wait_increment=25, /* Number of milliseconds which is added
to or deducted from wait_time by
striking 's' or 'f' during image display.*/
wait_time; /* Time in milliseconds to wait after
finishing the display of one image
before going on to start loading
the next image. */
char frame_num_string[7],/* Frame number of displayed image
in ASCII form. */
purpose = 'T', /* Single character chosen from main menu.
'purpose' is initialized here only to
prevent a compilation warning about
possible use before initialization. */
response, /* Response to questions: 'Y' or 'N' . */
string_buffer[129],/* Buffer to hold string input from the
user. */
user_input; /* Single character instruction while
displaying pictures. */
FILE *fp[MAX_FILES]; /* File pointers to Tektronix files. */
struct palettetype palette, /* Structure for use by setallpalette(). */
palette_default; /* Default palette. */
/*
Prototypes for functions contained in ANIMATE2.C.
display_raster() and save_raster() are function pointers that are assigned
to either EGA or Hercules versions of display_raster and save_raster
by read_graphics_parms(). */
int display_EGA_raster (int handle, int page, int num_bit_planes);
int display_Herc_raster (int handle, int page, int num_bit_planes);
int (*display_raster) (int handle, int page, int num_bit_planes);
int (*display_raster_default)(int handle, int page, int num_bit_planes);
int Tek4010(FILE *fp);
void change_directory (void);
void create_parms_file(void);
void display_directory(void);
void open_status(int handle);
void save_EGA_raster (int handle, int page, int num_bit_planes);
void save_Herc_raster (int handle, int page, int num_bit_planes);
void (*save_raster) (int handle, int page, int num_bit_planes);
void (*save_raster_default) (int handle, int page, int num_bit_planes);
void setscaling(int x_res_Tek, int y_res_Tek);
FILE *read_graphics_parms
(char *file_name,
int *ptr_to_graph_driver, int *ptr_to_graph_mode,
int *ptr_to_num_bit_planes,
struct palettetype *ptr_to_palette,
int *ptr_to_frame_num_color,
int *ptr_to_xloc,
int *ptr_to_yloc,
int (**ptr_to_ptr_to_display_raster)(),
void (**ptr_to_ptr_to_save_raster)());
/*****************************/
/* */
/* Read graphics parameters. */
/* */
/*****************************/
{
FILE *fp_par; /* File pointer to parameter file. */
do {
fp_par = read_graphics_parms("ANIMATE.PAR",
& graph_driver_default, & graph_mode_default,
&num_bit_planes_default,
& palette_default, &frame_num_color_default,
& xloc_default, & yloc_default,
&display_raster_default, & save_raster_default);
if (fp_par == NULL) /* No parameter file found. */
{
printf("No parameter file found, so one will be created.\n");
create_parms_file();
}
}while (fp_par == NULL);
fclose(fp_par); /* Close the parameter file. */
if (registerbgidriver(EGAVGA_driver) < 0)
{
printf("Unable to register EGA/VGA graphics driver.");
exit(1);
}
if (registerbgidriver(Herc_driver) < 0)
{
printf("Unable to register Hercules graphics driver.");
exit(1);
}
} /* End of parameter file section. */
/****************************************************/
/* */
/* Main menu. */
/* */
/****************************************************/
MAIN_MENU:
/* Close files opened by a prior menu selection.
When this section is encountered for the first time, no files are closed
because last_file = -1, rast_background = 0, and rasterize = 0.
Thus, do not worry about compilation warnings stating that variables
in this 'close file' section might be used before they are defined. */
if (last_file >= 0)
for (ifile = 0; ifile <= last_file; ifile++)
{
if (purpose == 'T') fclose (fp [ifile]);/* Do not worry about */
else close (handle[ifile]);/* compilation warnings */
} /* about the possibility*/
if (rast_background) close (handle_background); /* of using these */
if (rasterize) close (handle_out); /* variables before they*/
/* are defined. */
/* (Re)set default values. */
closegraph();
graph_driver = graph_driver_default;
graph_mode = graph_mode_default;
num_bit_planes = num_bit_planes_default;
save_raster = save_raster_default;
display_raster = display_raster_default;
palette = palette_default;
frame_num_color = frame_num_color_default;
xloc = xloc_default;
yloc = yloc_default;
last_file =-1; /* No files chosen yet for display. */
first_loop = 1; /* First loop through the pictures. */
rast_background = 0; /* No rasterized background image for Tek plots. */
rasterize = 0; /* No rasterized saves of images. */
wait_time = 0; /* Millisecs to wait before showing next image. */
single_step = 0; /* No single step through the pictures. */
display_frame_num = 0; /* No display of frame numbers in each picture. */
pause = 0; /* No brief pause after the last rasterized
picture before going back to the first
picture to restart the loop. */
/* Display the menu. */
restorecrtmode();
clrscr();
printf(" >>> ANIMATE version 1.3 <<<\n"
" c. 1990 by Jon Ahlquist\n\n"
" Hit To invoke\n\n"
" C Change disc:\\directory\n"
" T Tektronix 4010 emulation\n"
" R Rasterized image replay\n"
" S Script replay of rasterized images\n"
" Esc Escape (exit) this program\n");
/* Display the directory of the logged disc drive. */
display_directory();
/****************************************************/
/* */
/* Get the menu choice. */
/* and enact it. */
/* */
/****************************************************/
/* Get the purpose of this run, and make sure that it is in upper case. */
purpose = toupper(getch());
switch (purpose) /* Each section of code below is a different 'case.' */
{
/*****************************/
/* */
/* Change working directory. */
/* */
/*****************************/
case 'C':
change_directory();
goto MAIN_MENU;
/************************/
/* */
/* Tektronix emulation. */
/* */
/************************/
case 'T':
printf("\nTektronix emulation selected.\n"
"As prompted, enter names of files holding Tektronix graphs.\n"
"Enter MENU to interrupt input and return to main menu.\n"
"Enter DONE after all files are entered.\n");
for (ifile = 0; ifile < MAX_FILES; ifile++)
{
do {
printf ("Name of file %d? \n", ifile+1);
scanf ("%s", string_buffer);
/* Return to the main menu and reset all counters if
the user enters "menu." */
if (strnicmp(string_buffer, "menu", 4) == 0)
{
last_file = ifile-1;
goto MAIN_MENU;
}
/* Break out of this "for" loop if the user enters "done." */
if (strnicmp(string_buffer, "done", 4) == 0)
{
last_file = ifile-1;
/* Jump down a few lines outside the "for" loop. */
goto ALL_FILES_ENTERED;
}
fp[ifile] = fopen (string_buffer, "rb");
if (fp[ifile] == NULL)
{
if (errno == EMFILE)
{
printf("\nToo many files open.\n");
printf("Add FILES=20 to CONFIG.SYS,\n");
printf("or reduce the number of files.\n");
exit(1);
}
else
{
printf("\nUnable to open %s.\n", string_buffer);
printf("Check for a typing error, and try again.\n");
}
}
} while (fp[ifile] == NULL);
} /* End of 'for' loop. */
last_file = MAX_FILES-1;
ALL_FILES_ENTERED:
printf("\nDo you want to READ a rasterized image onto which\n"
"each Tektronix graph will be plotted?\n");
do {
printf("Type 'y' or 'Y' for yes, 'n' or 'N' for no.\n");
response = toupper(getch());
if (response == ESC) goto MAIN_MENU;
if (response == Ctrl_C) exit(0);
} while (! ((response=='Y') || (response=='N')));
rast_background = (response == 'Y');
if (rast_background)
{
do {
printf ("\nSpecify disc:\\subdirectory\\file for "
"the rasterized background\n");
scanf ("%s", string_buffer);
handle_background = open (string_buffer, O_RDONLY | O_BINARY);
open_status(handle_background);
} while (handle_background < 0);
}
break; /* End of 'Tektronix emulation.'
The 'break' command jumps to the first statement
following the 'switch' section below. */
/*****************************/
/* */
/* Replay rasterized images. */
/* */
/*****************************/
case 'R':
printf("\nRasterized replay selected.\n"
"As prompted, enter names of files holding rasterized images.\n"
"Enter MENU to interrupt input and return to main menu.\n"
"Enter DONE after all files are entered.\n");
for (ifile = 0; ifile < MAX_FILES; ifile++)
{
do {
printf ("Name of file %d?\n", ifile+1);
scanf ("%s", string_buffer);
/* Return to the main menu and reset all counters if
the user enters "menu." */
if (strnicmp(string_buffer, "menu", 4) == 0)
{
last_file = ifile-1;
goto MAIN_MENU;
}
/* Break out of this "for" loop if the user enters "done." */
if (strnicmp(string_buffer, "done", 4) == 0)
{
last_file = ifile-1;
/* Jump down a few lines outside the "for" loop. */
goto all_files_entered;
}
handle[ifile] = open (string_buffer, O_RDONLY | O_BINARY);
open_status(handle[ifile]);
} while (handle[ifile] < 0);
} /* End of 'for' loop for entering file names. */
last_file = MAX_FILES-1;
all_files_entered:
break; /* End of 'Replay rasterized images.'
The 'break' command jumps to the first statement
following the 'switch' section below. */
/***************************************/
/* */
/* Script replay of rasterized images. */
/* */
/***************************************/
case 'S': /* Script replay of rasterized images. */
{
FILE *fp_script;
do {
printf("Enter the name of the file containing the script.\n"
"Enter MENU to interrupt input and return to main menu.\n");
scanf("%s", string_buffer);
/* Return to the main menu and reset all counters if
the user enters "menu." */
if (strnicmp(string_buffer, "menu", 4) == 0) goto MAIN_MENU;
fp_script = read_graphics_parms(string_buffer,
&graph_driver, &graph_mode, &num_bit_planes,
&palette, &frame_num_color, &xloc, &yloc,
&display_raster, &save_raster);
if (fp_script == NULL)
{
if (errno == EMFILE)
{
printf("\nToo many files open to open script file.\n"
"Add FILES=20 to CONFIG.SYS,\n"
"or reduce the number of files.\n");
exit(1);
}
else
printf("\nUnable to open %s.\n"
"Check for a typing error, and try again.\n",
string_buffer);
}
} while (fp_script == NULL);
/* Read the file(s) containing the images. */
for (ifile=0; ifile<MAX_FILES; ifile++)
{
/*Keep reading files until we hit an EOF or we read the
maximum number of files. */
if(fscanf(fp_script, "%s", string_buffer) == EOF)
{
last_file = ifile-1;
/* Jump down a few lines outside the "for" loop. */
goto ALL_files_entered;
}
/* Open the file whose name was just read. */
handle[ifile] = open (string_buffer, O_RDONLY | O_BINARY);
if (handle[ifile] == -1)
{
printf("Unable to open file %s listed in your script file.\n",
string_buffer);
exit(1);
}
}
last_file = MAX_FILES-1;
ALL_files_entered:
fclose(fp_script);
}
break; /* End of 'Script replay of rasterized images.'
The 'break' command jumps to the first statement
following the 'switch' section below. */
/*********************/
/* */
/* Exit the program. */
/* */
/*********************/
case ESC:
case Ctrl_C: exit(0);
default: goto MAIN_MENU; /* Choose again. An undefined key was hit. */
} /* End of 'switch' section. */
/**************************/
/* */
/* Ask about rasterizing. */
/* */
/**************************/
printf("\nDo you want to STORE rasterized versions of the images?\n");
do {
printf("Type 'y' or 'Y' for yes, 'n' or 'N' for no.\n");
response = toupper(getch());
if (response == ESC) goto MAIN_MENU;
if (response == Ctrl_C) exit(0);
} while (! ((response=='Y') || (response=='N')));
rasterize = (response=='Y'); /* Set flag for rasterizing. */
if (rasterize)
{
do {
printf("\nSpecify disc:\\subdir\\file to hold rasterized images.\n");
scanf("%s", string_buffer);
handle_out = open(string_buffer,
O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE);
if (handle_out < 0)
open_status(handle_out);
} while (handle_out < 0);
do {
printf("\nSpecify the first and last frame numbers to be saved.\n"
"The images are numbered beginning with 1.\n"
"To save ALL images, type 1 and a large integer < 32768.\n");
scanf("%s", string_buffer); first_frame_save = atoi(string_buffer);
scanf("%s", string_buffer); last_frame_save = atoi(string_buffer);
/* Repeat if an improper response was given, such as
a nonpositive integer,
a noninteger, in which case atoi() returned 0, or
the last frame is less than the first. */
} while ((first_frame_save < 1) || (last_frame_save < 1)
|| (last_frame_save < first_frame_save));
/* Create a script file describing the rasterized images. */
if (purpose == 'S')
{
int i;
char script_file[81];
FILE *fp_script;
printf("\nSpecify disc:\\subdir\\file to hold the SCRIPT for "
"the rasterized images.\n");
scanf("%s", script_file);
if ((fp_script = fopen(script_file, "wt+")) == NULL)
{
printf("Unable to open script file.\n");
exit(1);
}
if (graph_driver == EGA)
{
fprintf(fp_script, "EGA\n");
fprintf(fp_script, "%d\n", num_bit_planes);
for (i=0; i<16; i++) fprintf(fp_script, "%d ", palette.colors[i]);
fprintf(fp_script, "\n%d\n", frame_num_color);
}
else fprintf(fp_script, "Hercules\n");
/* The remaining information is the same for EGA or Hercules. */
fprintf(fp_script, "%d %d\n", xloc, yloc);
fprintf(fp_script, "%s", string_buffer);
fclose (fp_script);
} /* End of section for script file creation. */
} /* End of section for holding rasterized images. */
/************************/
/* */
/* Initialize graphics. */
/* */
/************************/
/* Check to see whether frame_num_color lies within range. */
{
int i, power_of_2;
if (graph_driver == EGA)
{
/* Compute 2 raised to the power num_bit_planes. */
for (power_of_2 = 1, i = 0; i < num_bit_planes; i++) power_of_2 *= 2;
if (frame_num_color >= power_of_2)
{
printf("\n\n"
"The frame number color in ");
if (purpose == 'S')printf("in your script file is out of range.\n");
else printf("ANIMATE.PAR is out of range.\n");
printf("It must lie between 1 and %d.\n"
"For now, the first palette color will be used.\n"
"Image display will begin in about 10 seconds.\n"
"In the meantime, make a note to correct this error.\n",
power_of_2 - 1);
frame_num_color = 1;
delay(10000);
}
}
} /* End of check on frame_num_color. */
initgraph(&graph_driver,&graph_mode, "");
graph_error = graphresult();
if (graph_error < 0)
{
printf("Error while trying to initialize graphics.\n");
printf("%s\n", grapherrormsg(graph_error));
exit(1);
}
if (graph_driver == EGA) /* Set colors for EGA mode. */
{
setallpalette(&palette);
setcolor(frame_num_color); /* Set drawing color for frame numbers. */
}
if (purpose == 'T')
/* Set scaling constants to transform from Tektronix 4010 coordinates
to graphics mode coordinates. */
setscaling(1024, 780);
/* We'll set up things not to use double buffering for Tektronix
emulation and double buffering for other modes. */
if (purpose == 'T') last_page = 0;
else last_page = 1;
page = last_page;
ifile = 0;
/*******************/
/* */
/* Display images. */
/* */
/*******************/
/* Each execution of this "while" block displays all the images
in the chosen files one time. */
while (1)
{
frame_num = 0;
while (1) /* This block is executed once per input file. */
{
/* Toggle the page between 0 and last_page. */
page = last_page - page;
setactivepage(page);
/* Display an image. */
if (purpose == 'T') /* Invoke the Tektronix emulator. */
{
if (rast_background) /* Plot the graph on a background image. */
{
do {
EOF_flag =
display_raster(handle_background, page, num_bit_planes);
if (EOF_flag) lseek(handle_background, 0L, SEEK_SET);
} while(EOF_flag);
}
else cleardevice(); /* Plot the graph on a blank screen. */
EOF_flag = Tek4010(fp[ifile]); /* Plot the graph. */
}
else /* Invoke rasterized image replay.
'display_raster' is a function pointer to either
'display_EGA_raster' or display_Herc_raster.'
*/
EOF_flag = display_raster(handle[ifile], page, num_bit_planes);
/*********************************************************/
/* */
/* See whether the user has given keyboard instructions. */
/* */
/*********************************************************/
while (kbhit())
{
user_input = toupper( getch() );
USER_INPUT:
switch(user_input)
{
case 'F': wait_time = (int) max(0, wait_time - wait_increment);
break;
case 'S': wait_time = (int) min(25000, wait_time + wait_increment);
break;
case '1': single_step = 1 - single_step; break;
case 'D': display_frame_num = 1 - display_frame_num; break;
case 'P': pause = 1 - pause; break;
case ESC:
case Ctrl_C: goto MAIN_MENU;
}
}
if (EOF_flag) /* An EOF was hit without getting an image.*/
{
/* Reset the page and go for the next image. */
page = last_page - page;
/* We read Tektronix files only once, so we do not need to rewind
them. Otherwise, we would have fseek(fp(++ifile), 0L, SEEK_SET);
instead of ifile++; and else{fseek(fp[ifile=0],0L,SEEK_SET);break;}
instead of else break; */
if (purpose == 'T')
{
if (ifile < last_file) ifile++;
else break;
}
/* Go to the next file and rewind it. */
else /* purpose == 'R' or 'S' */
{
if (ifile < last_file) lseek(handle[++ifile], 0L, SEEK_SET);
else /* ifile = last_file */
{
lseek(handle[ifile=0], 0L, SEEK_SET);
break; /* Jump outside the "while" block,
and start the next loop. */
}
}
}/* End of "EOF hit" section. */
else /* Image plotted. */
{
/* If single stepping, wait till user hits 'n' or 'N' before
showing the next frame.
If the user hits something else, take it as a user input
instruction.
*/
if (single_step)
{
user_input = toupper(getch());
if (user_input != 'N') goto USER_INPUT;
}
/* Display frame number if requested. */
frame_num++;
if (display_frame_num)
{
/* Convert the frame number to a base 10 ASCII string.
We call outtextxy twice because once is not always enough
to make it work correctly. I presume the problem arises
because Turbo C graphics were not designed with the idea
of users messing with the bit planes on their own. */
itoa(frame_num, frame_num_string, 10);
outtextxy(xloc, yloc, frame_num_string);
outtextxy(xloc, yloc, frame_num_string);
}
setvisualpage(page);
if (rasterize && first_loop)
{
if ((frame_num >= first_frame_save) &&
(frame_num <= last_frame_save))
save_raster(handle_out, page, num_bit_planes);
}
delay((unsigned)wait_time); /* Pause between pictures. */
}/* End of "Image plotted" section. */
} /* End of "while" block which is executed once per input file.
Reaching this point means that we have displayed each of the
desired images.
*/
/* Go back to the main menu if we are Tektronix mode. */
if (purpose == 'T') goto MAIN_MENU;
/* Reset the "first_loop" flag to indicate that the next loop
through the images is not the first. */
first_loop = 0;
/* Pause for a second on the last image if the user wants to pause
and if we are not in single step mode. */
if (pause && !single_step) delay(1000);
} /* End of block to loop images. */
} /* End of main. */