home *** CD-ROM | disk | FTP | other *** search
- /**************/
- /* */
- /* animate2.c */
- /* */
- /**************/
-
- /*
- Second half of animate.c containing the functions called by
- the main function.
- 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.
- */
-
- /**************/
- /* */
- /* Prototypes */
- /* */
- /**************/
-
- #include <conio.h> /* getch(). */
- #include <ctype.h> /* toupper(). */
- #include <dos.h> /* outportb(). */
- #include <dir.h> /* chdir(), getcwd(), findfirst, findnext(), setdisk(). */
- #include <errno.h> /* errno, EMFILE. */
- #include <graphics.h>/* All graphics routines. */
- #include <io.h> /* _read(), _write(). */
- #include <process.h> /* exit(). */
- #include <stdio.h> /* printf(). */
- #include <stdlib.h> /* qsort(). */
- #include <string.h> /* strcat(). */
-
- /* Global variables. */
- float X_scale, X_offset, Y_scale, Y_offset;
-
- /******************************************************************/
-
- 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)())
-
- /*
- This function reads graphics parameters from file "file_name."
- Jon Ahlquist, 1 Jan 1990.
- */
- {
- int i; /* Loop index. */
- char video_mode[9]; /* Either "EGA" or "Hercules". */
- FILE *fp; /* File pointer to parameter file. */
-
- /* Function prototypes. */
- int display_EGA_raster (int handle, int page, int num_bit_planes);
- int display_Herc_raster(int handle, int page, int num_bit_planes);
- void save_EGA_raster (int handle, int page, int num_bit_planes);
- void save_Herc_raster (int handle, int page, int num_bit_planes);
-
-
- /* Open the file containing the graphics instructions. */
- fp = fopen(file_name, "rt");
- if (fp == NULL) return(NULL); /* No parameter file found. */
-
- /* Read the graphics mode to be used. */
- fscanf(fp, "%s", video_mode);
-
- if (strnicmp(video_mode, "EGA", 3) == 0)
- {
- *ptr_to_graph_driver = EGA;
- *ptr_to_graph_mode = EGAHI;
-
- /* Read the number of bit planes to be loaded
- and the colors to be assigned to the bit planes. */
- fscanf(fp, "%d", ptr_to_num_bit_planes);
-
- /* Define the colors to be used. */
- ptr_to_palette->size = 16; /* No. of colors. */
- for (i=0; i<16; i++) fscanf(fp, "%d", &ptr_to_palette->colors[i]);
-
- /* Select which of the palette colors will be used when writing
- the frame number. */
- fscanf(fp, "%d", ptr_to_frame_num_color);
-
- /*
- ptr_to_ptr_to_save_raster and ptr_to_ptr_to_display_raster
- are pointers to pointers.
- Here, we store the starting address of save_EGA_raster and
- display_EGA_raster in the address pointed to by ptr_to_ptr_to_save_raster
- and ptr_to_ptr_to_display_raster, respectively.
- */
- *ptr_to_ptr_to_save_raster = save_EGA_raster;
- *ptr_to_ptr_to_display_raster = display_EGA_raster;
- }
-
- else if (strnicmp(video_mode, "Her", 3) == 0)
- {
- *ptr_to_graph_driver = HERCMONO;
- *ptr_to_graph_mode = HERCMONOHI;
-
- *ptr_to_ptr_to_save_raster = save_Herc_raster;
- *ptr_to_ptr_to_display_raster = display_Herc_raster;
- /* See explanation of ptr_to_ptr_to_save_raster
- and ptr_to_ptr_to_display_raster above. */
- }
-
- else
- {
- printf("Invalid graphics mode listed at the beginning of file %s.\n"
- "Only EGA or Hercules are acceptable.\n", file_name);
- fclose(fp);
- exit(0);
- }
-
- /* Read the position at which the left edge of the frame number
- should be displayed when that option is selected. */
- fscanf(fp, "%d %d", ptr_to_xloc, ptr_to_yloc);
-
- return(fp);
- }
-
- /******************************************************************/
-
- void change_directory(void)
- {
-
- char drive[3], directory[81], filename[9], ext[5], string_buffer[81];
-
- TRY_AGAIN:
- printf("\nEnter disc:\\directory\n");
- scanf ("%s", string_buffer);
-
- /* Split the string into the drive name and directory using
- fnsplit(), which parses a string into a drive, directory, and filename.
- The directory and filename strings must be merged (concatenated)
- because actually they are both part of the directory name. */
- fnsplit(string_buffer, drive, directory, filename, ext);
- /* fnsplit is Borland function, not part of the ANSI standard. */
- strcat(directory,filename); /* ANSI concatenation function. */
-
- /* To change the disk drive, we convert the disk drive name
- to upper case ASCII. Then we call setdisk with 0 for drive A,
- 1 for drive B, etc. Since A is coded in ASCII as 65 (base 10),
- we convert from the ASCII letter to the integer we want
- by subtracting 65 (base 10). */
- if (drive[0] != '\0') setdisk(toupper(drive[0]) - 65);
- if (directory[0] != '\0')
- {
- if (chdir(directory))
- {
- printf("Path not found. Try again.\n");
- goto TRY_AGAIN;
- }
- }
- } /* End of change_directory(). */
-
- /******************************************************************/
-
- void create_parms_file(void)
- /* This function creates a file containing adjustable parameters.
- Jon Ahlquist, 23 July 1988, 27 Nov 1989, 1 Jan 1990.
- */
-
- {
- char response, /* Response to question about graphics type.*/
- num_bit_planes, /* No. of bit planes to be loaded (1 to 4). */
- graphics_type[9]; /* Graphics driver;
- either 'EGA' or 'Hercules'. */
-
- int i, /* 'For' loop index. */
- color, /* Color index, value of 0 to 63. */
- frame_num_color, /* Palette number (1-16) of the color
- in which the frame number will be
- written. */
- power_of_2, /* 2 to the power num_bit_planes. */
- xloc, yloc; /* Pixel coordinates at which the frame
- number is displayed if requested. */
-
- FILE *fp_par; /* FILE pointer to the parameter file. */
-
-
- /* Open the parameter file. */
- fp_par = fopen("animate.par", "wt+");
- if (fp_par == NULL)
- {
- printf("\nTrouble opening parameter file ANIMATE.PAR.\n");
- exit(1);
- }
-
- /* Get the default graphics type. */
- printf("\nDoes your computer have EGA graphics?\n"
- "(If not, we'll assume it has Hercules graphics.)\n");
- do {
- printf("Type 'y' or 'Y' for yes, 'n' or 'N' for no.\n");
- response = toupper(getch());
- if ((response == '\x1b'/* Escape key */ )|
- (response == '\x03'/* Control C */ )) exit(1);
- } while (! ((response=='Y') || (response=='N')));
-
-
- if (response == 'Y')
- strcpy(graphics_type, "EGA");
- else
- strcpy(graphics_type, "Hercules");
- fprintf(fp_par, "%s\n", graphics_type);
-
- /* There are extra questions if you have EGA graphics. */
- if (strcmp(graphics_type,"EGA") == 0)
- {
- /* Get the number of bit planes to be loaded. */
- do {
- printf("\nWhen reading or writing rasterized images,\n"
- "how many bit planes should be loaded "
- "under default conditions?\n"
- "Normally this is 1, but it could be as large as 4.\n");
- /* Get response and convert from an ASCII character to integer form. */
- num_bit_planes = getche() - 48; /* Character '1' is 49, '4' is 52. */
- } while (num_bit_planes<1 || num_bit_planes>4);
- fprintf(fp_par, "%d\n", num_bit_planes);
-
- /* Get the color assignments for the palette. */
- printf("\n\nSpecify the assignment of colors for the palette "
- "of 16 colors.\n"
- "These are 16 integers, each lying between 0 and 63.\n"
- "If you just stated that you will usually load "
- "more than 1 bit plane,\n"
- "you can get the default EGA colors by entering:\n"
- "0 1 2 3 4 5 7 20 56 57 58 59 60 61 62 63\n"
- "If you just stated that only 1 bit plane will usually be loaded,\n"
- "a reasonable choice is\n"
- "1 62 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
- "which will give yellow lines on a blue background.\n");
- for (i = 0; i < 16; i++)
- {
- scanf("%d", &color);
- fprintf(fp_par, "%d ", color);
- }
- fprintf(fp_par, "\n");
-
- /* Get the color for displaying frame numbers. */
- if (num_bit_planes == 1) /* No choice if num_bit_planes = 1. */
- fprintf(fp_par, "1\n");
- else
- {
- for (power_of_2=1, i=0; i<num_bit_planes; i++) power_of_2 *= 2;
- do {
- printf("\nIf and when you display frame numbers on your plots,\n"
- "in which palette color do you want the numbers written?\n"
- "Your answer should lie between 1 and %d."
- " (0 is the background color.)\n", power_of_2 - 1);
- scanf("%d", &frame_num_color);
- } while (frame_num_color<1 || frame_num_color>=power_of_2);
- fprintf(fp_par, "%d\n", frame_num_color);
- }
- } /* End of section for bit planes and colors for EGA. */
-
- /* Ask where to display frame numbers when that option is selected. */
- printf("\nSpecify the pixel column and row at which the left edge of the\n"
- "frame number will be displayed if that option is selected.\n"
- "EGA coordinates run from (0,0) in the upper left corner\n"
- "to (639,349) in the lower right corner.\n"
- "Hercules coordinates run from (0,0) in the upper left corner\n"
- "to (719,347) in the lower right corner.\n"
- "0 10 is often a good choice for either EGA or Hercules graphics.\n");
- scanf ("%d %d", &xloc, &yloc);
- fprintf(fp_par, "%d %d\n", xloc, yloc);
-
- fclose (fp_par); /* Close the parameter file. */
- } /* End of create_parms_file. */
-
- /******************************************************************/
-
- void display_directory(void)
- /*
- List all the files in the current directory.
- Jon Ahlquist, 1 Jan 1990.
- */
- {
-
- #define NCHARS 13
- /* Max. no. of characters in an MS/DOS file name, counting
- the final null terminator at the end of the character string. */
- #define MAX_FILES 100
- /* Max. no. of files to display. */
-
- int done, /* =0 if a file is found.
- =-1 if no file is found. */
- i, /* Loop counter. */
- nfiles; /* Number of files. */
-
- struct ffblk ffblk; /* See Borland's documentation for findfirst(). */
-
- char current_working_directory[81],
- file_name[MAX_FILES][NCHARS]; /* file_name will hold up to MAX_FILES
- files from the current directory. */
-
- getcwd(current_working_directory, 80);/* Get current working directory.*/
- printf("\nCurrent Working Directory: %s\n", current_working_directory);
-
- done = findfirst("*.*",&ffblk,0);
- i = 0;
- while (!done && i<MAX_FILES)
- {
- strcpy(file_name[i],ffblk.ff_name);
- done = findnext(&ffblk);
- i++;
- }
- nfiles=i;
-
- /* Alphabetize the list of files using the quicksort algorithm. */
- qsort(&file_name, nfiles, NCHARS, strcmp);
-
- for (i = 0; i<nfiles; i++)
- {
- printf(" %-12s",file_name[i]);
- if (i%5 == 4) printf("\n");
- }
- printf("\n");
- }
-
- /******************************************************************/
-
- void setscaling(int x_res_Tek, int y_res_Tek)
- /* x_res_Tek = No. of columns of pixels.
- y_res_Tek = No. of rows of pixels. */
-
- /* This function determines scaling parameters that are used to
- translate Tektronix graphics into graphics for the local
- graphics device.
-
- Jon Ahlquist, 23 June 1988, 1 Dec 1989.
- */
-
- /* define global variables that will be accessed
- during Tektronix emulation. */
-
- {
-
- int X_res, Y_res, x_asp, y_asp;
- float aspect_ratio, pixel_aspect_ratio, aspect_ratio_Tek, ratio;
-
- /* Determine the aspect ratio of the Tektronix graphics.
- Tektronix pixels are square.
- The origin for Tektronix coordinates is in the lower left corner
- of the screen. */
- aspect_ratio_Tek = (float)x_res_Tek / (float)y_res_Tek;
-
- /* Pixel addresses start with zero, so we subtract 1 from each of
- the Tektronix dimensions to get their maximum values.
- For example, for the Tektronix 4010, x runs from 0 through 1023
- and y runs from 0 through 779.*/
- x_res_Tek--;
- y_res_Tek--;
-
- /* Determine the resolution of the graphics mode. */
- X_res = getmaxx(); /* No. of columns of pixels, less 1. */
- Y_res = getmaxy(); /* No. of rows of pixels, less 1. */
-
- /* Determine the relative width and height of a pixel. */
- getaspectratio (&x_asp, &y_asp);
- pixel_aspect_ratio = (float) x_asp / (float) y_asp;
-
- /* Determine the ratio of width to height of a full screen
- in the local graphics mode. */
- aspect_ratio = pixel_aspect_ratio * (X_res + 1) / (Y_res + 1);
-
-
-
- /* Set the scaling and offset factors in order to
- convert from Tektronix graphics coordinates to the coordinates
- used by the graphics mode selected.
- (x,y) refers to Tektronix coordinates.
- (X,Y) refers to the user's local graphics mode coordinates.
- Y_scale is negative because (x,y) = (0,0) is in the lower left
- corner with Tektronix graphics, while (X,Y) = (0,0) is in the
- upper left corner with Borland graphics. */
-
- ratio = aspect_ratio_Tek / aspect_ratio;
-
- if (ratio >= 1)
- /* If ratio >= 1, then the Tektronix screen is relatively wider
- than the screen for the graphics mode selected.
- In that case, we need to adjust the scaling so that the
- width of the Tektronix plot will fill the width of the screen,
- and the height of the Tektronix plot will be vertically
- centered. That is, the middle value of y in
- Tektronix coordinates, i.e. 0.5 * y_res_Tek,
- should be mapped to the middle value of the user's
- Y coordinate, i.e. 0.5 * Y_res. */
- {
- X_scale = ((float) X_res) / ((float) x_res_Tek);
- Y_scale = -X_scale * pixel_aspect_ratio;
- X_offset = 0.5;
- Y_offset = 0.5 * (Y_res - Y_scale * y_res_Tek) + 0.5;
- }
-
-
- else
- /* If ratio < 1, then the Tektronix screen is relatively narrower
- than the screen for the graphics mode selected.
- In that case, we need to adjust the scaling so that the
- height of the Tektronix plot will fill the height of the screen,
- and the width of the Tektronix plot will be horizontally
- centered. That is, the middle value of x in
- Tektronix coordinates, i.e. 0.5 * x_res_Tek,
- should be mapped to the middle value of the user's
- X coordinate, i.e. 0.5 * X_res. */
- {
- Y_scale = -((float) Y_res) / ((float) y_res_Tek);
- X_scale = -Y_scale / pixel_aspect_ratio;
- X_offset = 0.5 * (X_res - X_scale * x_res_Tek) + 0.5;
- Y_offset = Y_res + 0.5;
- }
- } /*End of function setscaling(); */
-
- /******************************************************************/
-
- int Tek4010 (FILE *fp)
-
- /*
- Tek4010() emulates a Tektronix 4010 graphics terminal
- based on the description of Tek4010 operation given in chapter 5
- of the manual for Flexi-Tek communications software.
- Tek4010() ignores all alphanumeric input as well as
- any position/status enquiry.
- We assume that a graph is finished when either a screen clear command
- is received or when alphanumeric mode is entered after previously being
- in graphics mode.
-
- Return value: Tek4010() returns integer 1 if an EOF was encountered
- without meeting any graphics instructions.
- 0 is returned if a graph has been drawn.
-
- Tek4010() uses global variables X_scale, X_offset, Y_scale, and Y_offset
- computed by function setscaling().
-
- Jon Ahlquist, 1 July 1988, 15 Sep 1989, 8 Jan 1990, 3 April 1990.
- */
-
- {
- /* ASCII characters. */
- #define LF 0x0a /* Line feed */
- #define FF 0x0c /* Form feed */
- #define CR 0x0d /* Carriage return */
- #define ESC 0x1b /* Escape (Control [)*/
- #define GS 0x1d /* Control ] */
- #define US 0x1f /* Control _ (underscore) */
-
- /* Define masks 2 bytes long which will keep the rightmost 5 bits and
- the next 5 significant bits when used with the bitwise
- "and" operation (&). */
- #define keep_lo_5 0x001f
- #define keep_hi_5 0x03e0
-
- #define FALSE 0
- #define TRUE 1
-
- typedef int boolean; /* Boolean variables are either TRUE or FALSE. */
- boolean lo_y_set, /* FALSE if lowest 5 bits of Tektronix coordinate y
- are not yet defined. TRUE if defined. */
- start_line; /* FALSE if (x,y) does not begin a line,
- TRUE if (x,y) does begin a line. */
-
- char byte; /* byte from the Tektronix file. */
-
- int x, y, /* Tektronix 4010 coordinates. */
- X, Y; /* Pixel coordinates. */
-
- /* Skip all alphanumeric characters that may reside in the file
- before graphics mode is invoked.
- Return to the calling program if we hit an end of file. */
- do {
- byte = fgetc(fp);
- if (byte == EOF) return(1);
- } while (byte != GS);
- /* Reaching this point means that we have encountered ASCII character GS,
- which invokes graphics mode. */
-
-
- /* Initialize variables. */
- lo_y_set = FALSE;
- x = 0;
- y = 0;
-
- /* Decode the Tek 4010 graphics instructions and plot the graph. */
- while (1)
- {
- switch(byte=getc(fp))
- {
-
- /* First consider the cases that call for return to the calling function. */
- case EOF: /* End of file. */
- case US: /* Alphanumeric mode invoked. */
- return(0);
-
- case CR:
- /* Ignore a "carriage return, line feed" combination, but
- consider a graph to be complete if alphanumeric mode is entered
- after being in graphics mode. */
- if (getc(fp) != LF) return(0);
- else break;
-
- case ESC:
- /* ESC FF clears the screen.
- Thus, it is a signal that a graph is complete. */
- if (getc(fp) == FF) return(0);
- else break;
-
- case GS: /* Graphics mode re-invoked. */
- start_line = TRUE; /* The next point will start a line. */
- break;
-
- default:
- /* The only remaining case of interest to us is when the byte has a value
- that could be a graphics coordinate. Throw it away otherwise. */
- if ((byte < 32)|| (byte>127)) break;
-
- /* At this point we are guaranteed that the byte is an x or y coordinate.
- Check the leftmost 3 bits of the byte to see whether the rightmost
- 5 bits are the low or high 5 bits of an x or y coordinate. */
- switch(byte >> 5)
- {
-
- case 0x01: /* Set the high bits of x or y. */
- /* If the low 5 bits of y have been set,
- the bits are the high 5 bits of x. */
- if (lo_y_set) x = ( ((int)(keep_lo_5 & byte)) << 5) |
- (keep_lo_5 & x);
- /* Otherwise, the bits are the high 5 bits of y. */
- else y = ( ((int)(keep_lo_5 & byte)) << 5) |
- (keep_lo_5 & y);
- break;
-
-
- case 0x02: /* Set low 5 bits of x and plot. */
- x = (keep_hi_5 & x) | (keep_lo_5 & byte);
-
- /* Convert from Tektronix coordinates to pixel coordinates. */
- X = x * X_scale + X_offset;
- Y = y * Y_scale + Y_offset;
-
- /* Perform the requested graphics operation. */
- if (start_line) moveto (X, Y);
- else lineto (X, Y);
-
- /* Reset indicator to indicate that the next coordinate received
- will NOT be the start of a new line. */
- start_line = FALSE;
- /* Reset indicator to say that the low 5 bits of y have
- NOT been set since the last point was plotted. */
- lo_y_set = FALSE;
- break;
-
- case 0x03: /* Set the low 5 bits of y. */
- y = (keep_hi_5 & y) | (keep_lo_5 & byte);
- /* Set the flag that says that the low 5 bits
- of y have been set. */
- lo_y_set = TRUE;
- } /* End of "switch(byte>>5)" */
- } /* End of "switch (byte)" */
- } /* End of "while(1)" */
- /* The following return statement is unreachable, but its presence suppresses
- a compiler warning saying that the function should return a value.
- Tek4010() does return a value, but all the return statements are internal
- to the function. */
- return(1);
- } /* End of Tek4010(). */
-
- /**********************************************************************/
-
- void open_status(int handle)
-
- /* Function to check on the status of an open() statement.
- It always returns a value of 0.
- Jon Ahlquist, 8 July 1988.
- */
- {
- if (handle < 0)
- {
- if (errno == EMFILE)
- {
- printf("\nToo many files open.\n"
- "Add FILES=20 to CONFIG.SYS,\n"
- "or reduce the number of files.\n");
- exit(1);
- }
- else
- {
- printf("\nTrouble opening file.\n"
- "If you made a typing error, retype the file.\n"
- "Otherwise, hit control C to abort.\n");
- }
- }
- }
-
- /*********************************************************************/
-
- /* FROM HERE TO THE END, THERE ARE FUNCTIONS THAT DEPEND ON A PARTICULAR
- GRAPHICS DRIVER.*/
-
- /*********************************************************************/
- /*** HERCULES VERSIONS ***/
- /*********************************************************************/
-
- void save_Herc_raster(int handle_out, int page, int num_bit_planes)
-
- /* This function stores a Hercules image to disc in rasterized form,
- i.e. pixel by pixel.
-
-
- Variable Meaning
-
- handle_out Handle to the file to which the image will be written.
-
- page Video page to be saved, either 0 or 1.
-
- num_bit_planes Unused dummy variable included to provide consistency with
- save_EGA_raster().
-
-
- Jon Ahlquist, 22 July 1988, 1 Dec 1989.
- */
-
- {
- #define NBYTES_HERC 32768U /* Number of bytes in a Hercules image. */
-
- unsigned nbytes_written;
- void far *fptr;
-
- /* Define the address on the grahics board from which the image will
- be read. */
- fptr = page ? (void far *) 0xb8000000L : (void far *) 0xb0000000L;
-
- nbytes_written = _write(handle_out, fptr, NBYTES_HERC);
- if (nbytes_written < NBYTES_HERC)
- {
- closegraph();
- printf("Can't save image. Disc is probably full.\n");
- exit(1);
- }
- } /* End of save_Herc_raster().
- Don't worry about a compilation warning saying that num_bit_planes is never
- used. num_bit_planes is not needed by save_Herc_raster() and was included
- only so that the call to save_Herc_raster() would be like the call to
- save_EGA_raster, where num_bit_planes is required. */
-
- /*********************************************************************/
-
- int display_Herc_raster (int handle_in, int page, int num_bit_planes)
-
- /* This function reads and displays a rasterized Hercules image.
- It returns a value of 1 if an EOF was hit,
- a value of 0 if at least some bits were read to the video board.
-
- Variable Meaning
-
- handle_in Handle to the file from which the image will be read.
-
- page Video page to be saved, either 0 or 1.
-
- num_bit_planes Unused dummy variable included to provide consistency with
- display_EGA_raster().
-
- Jon Ahlquist, 22 July 1988, 8 Jan 1990.
- */
-
- {
- #define NBYTES_HERC 32768U /* Number of bytes in a Hercules image. */
- unsigned nbytes_read;
- void far *fptr;
-
- /* Define the address on the grahics board to which the image will
- be written. */
- fptr = page ? (void far *) 0xb8000000L : (void far *) 0xb0000000L;
-
- /* Read the image from disc. */
- nbytes_read = _read(handle_in, fptr, NBYTES_HERC);
- return(nbytes_read == 0);
- } /* End of display_Herc_raster().
- Don't worry about a compilation warning saying that num_bit_planes is never
- used. num_bit_planes is not needed by display_Herc_raster() and was included
- only so that the call to display_Herc_raster() would be like the call to
- display_EGA_raster, where num_bit_planes is required. */
-
-
- /**************************************************************************/
- /*** EGA VERSIONS ***/
- /**************************************************************************/
-
- void save_EGA_raster(int handle_out, int page, int num_bit_planes)
-
- /* This function stores an EGA image to disc in rasterized form,
- i.e. pixel by pixel.
-
- Variable Meaning
-
- handle_out Handle to the file to which the image will be written.
-
- page Video page to be saved, either 0 or 1.
-
- num_bit_planes Number of bit planes to store.
- Any value between 1 and 4, inclusive, is acceptable.
-
- Jon Ahlquist, 22 July 1988, 1 Dec 1989.
- */
-
- {
- #define ONE 0x01
- #define NBYTES_EGA 28000U /* Number of bytes in an EGA bit plane. */
-
- int bit_plane;
- unsigned nbytes_written;
- void far *fptr;
-
-
- /* Define the address on the grahics board from which the image will
- be read. */
- fptr = page ? (void far *) 0xa8000000L : (void far *) 0xa0000000L;
-
- /* Tell the graphics board that one or more bit planes will be read. */
- outportb(0x3ce, 4);
-
- /* Loop through the bit plane(s) and write the image to the output file. */
- for (bit_plane = 0; bit_plane < num_bit_planes; bit_plane++)
- {
- /* Toggle the bit plane from which the image will be taken. */
- outportb(0x3cf, bit_plane);
-
- /* Write the image to the output file. */
- nbytes_written = _write(handle_out, fptr, NBYTES_EGA);
- if (nbytes_written < NBYTES_EGA)
- {
- closegraph();
- printf("Can't save image. Disc is probably full.\n");
- exit(1);
- }
- }
- } /* End of save_EGA_raster(). */
-
- /*********************************************************************/
-
- int display_EGA_raster(int handle_in, int page, int num_bit_planes)
-
- /* This function reads and displays a rasterized EGA image.
- It returns a value of 1 if an EOF was hit,
- a value of 0 if at least some bits were read to the video board.
-
-
- Variable Meaning
-
- handle_in Handle to the file from which the image will be read.
-
- page Video page to be saved, either 0 or 1.
-
- num_bit_planes Number of bit planes to store.
- Any value between 1 and 4, inclusive, is acceptable.
-
- Jon Ahlquist, 22 July 1988, 8 Jan 1990.
- */
-
- {
- #define ONE 0x01
- #define NBYTES_EGA 28000U /* Number of bytes in an EGA bit plane. */
-
- int bit_plane;
- unsigned nbytes_read;
- void far *fptr;
-
-
- /* Define the address on the grahics board to which the image will
- be written. */
- fptr = page ? (void far *) 0xa8000000L : (void far *) 0xa0000000L;
-
- /* Tell the graphics board that bits will be written into the video board. */
- outportb(0x3c4, 0x02);
-
- /* Read the image from the input file,
- writing it to the requested bit planes. */
- for (bit_plane = 0; bit_plane < num_bit_planes; bit_plane++)
- {
- /* Select which bit plane will receive the next record from disc. */
- outportb(0x3c5, ONE << bit_plane);
-
- /* Read a record from disc into the bit plane. */
- nbytes_read = _read(handle_in, fptr, NBYTES_EGA);
- if (nbytes_read == 0) return(1); /* An EOF was hit. */
- }
- return(0);
- } /* End of display_EGA_raster(). */