home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
FGFX11.ZIP
/
EFFECTS.C
< prev
next >
Wrap
Text File
|
1994-04-11
|
22KB
|
654 lines
/****************************************************************************\
* *
* EFFECTS.C *
* *
* This program demonstrates several methods of fading in an image from an *
* off-screen video page using either Fastgraph or Fastgraph/Light. The set *
* of routines provided herein are written for 320 x 200 graphics video *
* modes, but they could easily be extended to work in other resolutions. *
* *
* The examples are by no means all inclusive. Rather, their purpose is to *
* illustrate a few methods of creating special effects with Fastgraph or *
* Fastgraph/Light. *
* *
* To compile this program and link it with Fastgraph: *
* *
* BCC -ms EFFECTS.C FGS.LIB (Borland C++) *
* *
* CL /AS EFFECTS.C /link FGS (Microsoft C) *
* *
* QCL /AS EFFECTS.C /link FGS (Microsoft QuickC) *
* *
* PC /ms EFFECTS (Power C) *
* PCL EFFECTS ;FGS *
* *
* TCC -ms EFFECTS.C FGS.LIB (Turbo C and C++) *
* *
* ZTC -ms EFFECTS.C FGS.LIB (Zortech C++) *
* *
* This program also can be linked with Fastgraph/Light if you replace the *
* FGS library references with FGLS. *
* *
* Fastgraph (tm) and Fastgraph/Light (tm) are graphics libraries published *
* by Ted Gruber Software. For more info, please call, write, or FAX. *
* *
* Ted Gruber Software orders/info (702) 735-1980 *
* PO Box 13408 FAX (702) 735-4603 *
* Las Vegas, NV 89112 BBS (702) 796-7134 *
* *
\****************************************************************************/
#include <fastgraf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* function prototypes */
void main(void);
void announce(char *);
int irandom(int,int);
void curtain(int);
void diagonal_fade(int);
void horizontal_random_fade(int);
void inward_tunnel_effect(int);
void outward_tunnel_effect(int);
void spiral_dual(int);
void spiral_layered(int);
void spiral_normal(int);
void split_screen(int);
void unveil(int);
void venetian_blind(int);
/* global variables */
int delay;
int scroll_delay;
/* main program */
void main()
{
int old_mode, new_mode;
unsigned int count;
unsigned long start_time;
/* make sure a 320 x 200 color graphics mode is available */
new_mode = fg_bestmode(320,200,2);
if (new_mode < 0 || new_mode == 12)
{
printf("This program requires a 320 x 200 color graphics mode.\n");
exit(1);
}
/* determine the number of delay units per half clock tick */
delay = fg_measure() / 2;
/* initialize Fastgraph for the selected video mode */
old_mode = fg_getmode();
fg_setmode(new_mode);
fg_allocate(1);
/* display a packed pixel run file on a hidden page */
fg_sethpage(1);
fg_setpage(1);
fg_move(0,199);
fg_dispfile("FG.PPR",320,1);
fg_setpage(0);
/* compute the number of delay units needed to make the text scroll */
/* down at the same rate, regardless of the CPU speed or video mode */
count = 0;
fg_waitfor(1);
start_time = fg_getclock();
do
{
fg_scroll(0,319,0,7,4,1);
count++;
}
while (fg_getclock() == start_time);
scroll_delay = (delay / 8) - (delay * 2) / count;
if (scroll_delay < 0) scroll_delay = 0;
/* demonstrate the inward tunnel effect */
announce("inward tunnel effect");
inward_tunnel_effect(0);
fg_waitfor(27);
announce("inward tunnel effect with delay");
inward_tunnel_effect(delay);
fg_waitfor(27);
/* demonstrate the outward tunnel effect */
announce("outward tunnel effect");
outward_tunnel_effect(0);
fg_waitfor(27);
announce("outward tunnel effect with delay");
outward_tunnel_effect(delay);
fg_waitfor(27);
/* demonstrate the diagonal fade */
announce("diagonal fade");
diagonal_fade(0);
fg_waitfor(27);
announce("diagonal fade with delay");
diagonal_fade(delay/2);
fg_waitfor(27);
/* demonstrate the horizontal random fade */
announce("horizontal random fade");
horizontal_random_fade(delay);
fg_waitfor(27);
/* demonstrate the curtain effect */
announce("curtain");
curtain(delay/8);
fg_waitfor(27);
/* demonstrate the spiral effect */
announce("spiral");
spiral_normal(delay*2);
fg_waitfor(27);
/* demonstrate the layered spiral effect */
announce("layered spiral");
spiral_layered(delay);
fg_waitfor(27);
/* demonstrate the dual spiral effect */
announce("dual spiral");
spiral_dual(delay/2);
fg_waitfor(27);
/* demonstrate the split screen effect */
announce("split screen");
split_screen(delay/2);
fg_waitfor(27);
/* demonstrate the unveil effect */
announce("unveil");
unveil(delay/4);
fg_waitfor(27);
/* demonstrate the "venetian blind" effect */
announce("venetian blind");
venetian_blind(delay);
fg_waitfor(27);
/* restore the original video mode and screen attributes */
fg_freepage(1);
fg_setmode(old_mode);
fg_reset();
}
/****************************************************************************\
* *
* announce *
* *
* Display the name of the special effect we're about to see. *
* *
\****************************************************************************/
void announce(message)
char *message;
{
register int y;
int length;
/* clear the screen */
fg_erase();
/* display the specified message at the top row */
fg_setcolor(15);
length = strlen(message);
fg_locate(0,20-length/2);
fg_text(message,length);
/* scroll the message to the center of the screen */
fg_setcolor(0);
for (y = 0; y < 96; y+=4)
{
fg_scroll(0,319,y,y+7,4,1);
fg_stall(scroll_delay);
}
/* wait 1.5 seconds */
fg_waitfor(27);
}
/****************************************************************************\
* *
* irandom *
* *
* Random number generator used in some of the effects. It returns an *
* integer between min and max inclusive. *
* *
\****************************************************************************/
int irandom(min,max)
int min, max;
{
return(rand() % (max-min+1) + min);
}
/****************************************************************************\
* *
* curtain *
* *
* Reveal each row, one at a time, starting from the bottom and proceeding *
* to the top. This gives the effect of a curtain rising, hence the name. *
* *
\****************************************************************************/
void curtain(delay)
int delay;
{
register int y;
for (y = 199; y >= 0; y--)
{
fg_restore(0,319,y,y);
fg_stall(delay);
}
}
/****************************************************************************\
* *
* diagonal_fade *
* *
* This reveals the hidden page in two diagonal segments, separated by an *
* imaginary line extending from the lower left corner to the upper right *
* corner of the screen. We start with the top line of the left segment and *
* the bottom line of the right segment, and continue until the entire *
* screen is revealed. *
* *
\****************************************************************************/
void diagonal_fade(delay)
int delay;
{
int xmin, xmax;
int ymin, ymax;
xmin = 0;
xmax = 319;
ymin = 0;
ymax = 199;
while (xmax > 0)
{
fg_restore(0,xmax,ymin,ymin+4);
fg_restore(xmin,319,ymax-4,ymax);
fg_stall(delay);
xmin += 8;
xmax -= 8;
ymin += 5;
ymax -= 5;
}
}
/****************************************************************************\
* *
* horizontal_random_fade *
* *
* In this effect, the screen is divided into a series of two-pixel high *
* rows. Each row is revealed in random parts from left to right. This *
* process repeats 20 times, once for each row. At the end, a call to the *
* fg_restore routine guarantees that all rows are transferred. *
* *
\****************************************************************************/
void horizontal_random_fade(delay)
int delay;
{
register int i, j;
int xwidth;
int xmin, xmax;
int y;
int xpos[100];
for (j = 0; j < 100; j++)
xpos[j] = 0;
for (i = 0; i < 20; i++)
{
for (j = 0; j < 100; j++)
{
xmin = xpos[j];
if (xmin < 320)
{
xmax = xmin + irandom(1,10) * 8;
if (xmax > 320) xmax = 320;
y = j * 2;
fg_restore(xmin,xmax-1,y,y+1);
xpos[j] = xmax;
}
}
fg_stall(delay);
}
/* make sure we got them all */
fg_restore(0,319,0,199);
}
/****************************************************************************\
* *
* inward_tunnel_effect *
* *
* Starting at the screen edges, reveal the screen through a series of *
* concentric hollow rectangles. *
* *
\****************************************************************************/
void inward_tunnel_effect(delay)
int delay;
{
int xmin, xmax;
int ymin, ymax;
xmin = 0;
xmax = 319;
ymin = 0;
ymax = 199;
while (xmin < xmax)
{
fg_restore(0,319,ymin,ymin+4);
fg_restore(xmax-7,xmax,0,199);
fg_restore(0,319,ymax-4,ymax);
fg_restore(xmin,xmin+7,0,199);
fg_stall(delay);
xmin += 8;
xmax -= 8;
ymin += 5;
ymax -= 5;
}
}
/****************************************************************************\
* *
* outward_tunnel_effect *
* *
* Starting at the screen center, reveal the screen through a series of *
* concentric hollow rectangles. *
* *
\****************************************************************************/
void outward_tunnel_effect(delay)
int delay;
{
int xmin, xmax;
int ymin, ymax;
xmin = 152;
xmax = 167;
ymin = 95;
ymax = 104;
while (xmin >= 0)
{
fg_restore(xmin,xmax,ymin,ymin+5);
fg_restore(xmax-7,xmax,ymin,ymax);
fg_restore(xmin,xmax,ymax-4,ymax);
fg_restore(xmin,xmin+7,ymin,ymax);
fg_stall(delay);
xmin -= 8;
xmax += 8;
ymin -= 5;
ymax += 5;
}
}
/****************************************************************************\
* *
* spiral_dual *
* *
* In this effect, we reveal the screen through two spirals. One spiral *
* emanates clockwise from the screen edges to the screen center, while the *
* other emanates counterclockwise from the center to the screen edges. *
* *
\****************************************************************************/
void spiral_dual(delay)
int delay;
{
int xmin_outer, xmax_outer;
int ymin_outer, ymax_outer;
int xmin_inner, xmax_inner;
int ymin_inner, ymax_inner;
xmin_outer = 0;
xmax_outer = 319;
ymin_outer = 0;
ymax_outer = 199;
xmin_inner = 152;
xmax_inner = 167;
ymin_inner = 95;
ymax_inner = 104;
while (xmin_outer < xmin_inner)
{
fg_restore(xmin_outer,xmax_outer,ymin_outer,ymin_outer+4);
fg_stall(delay);
fg_restore(xmin_inner,xmax_inner,ymax_inner-4,ymax_inner);
fg_stall(delay);
fg_restore(xmax_outer-7,xmax_outer,ymin_outer,ymax_outer);
fg_stall(delay);
fg_restore(xmax_inner+1,xmax_inner+8,ymin_inner,ymax_inner);
fg_stall(delay);
fg_restore(xmin_outer,xmax_outer,ymax_outer-4,ymax_outer);
fg_stall(delay);
fg_restore(xmin_inner-8,xmax_inner,ymin_inner,ymin_inner+4);
fg_stall(delay);
fg_restore(xmin_outer,xmin_outer+7,ymin_outer,ymax_outer);
fg_stall(delay);
fg_restore(xmin_inner-8,xmin_inner-1,ymin_inner,ymax_inner+5);
fg_stall(delay);
xmin_outer += 8;
xmax_outer -= 8;
ymin_outer += 5;
ymax_outer -= 5;
xmin_inner -= 8;
xmax_inner += 8;
ymin_inner -= 5;
ymax_inner += 5;
}
}
/****************************************************************************\
* *
* spiral_layered *
* *
* This effect is similar to the normal spiral. Instead of revealing the *
* screen in one iteration, this effect does so in four iterations (layers), *
* each moving more toward the screen center. *
* *
\****************************************************************************/
void spiral_layered(delay)
int delay;
{
register int i;
int xmin, xmax;
int ymin, ymax;
for (i = 0; i < 4; i++)
{
xmin = i * 8;
xmax = 319 - xmin;
ymin = i * 5;
ymax = 199 - ymin;
while (xmin < xmax)
{
fg_restore(xmin,xmax,ymin,ymin+4);
fg_stall(delay);
fg_restore(xmax-7,xmax,ymin,ymax);
fg_stall(delay);
fg_restore(xmin,xmax,ymax-4,ymax);
fg_stall(delay);
fg_restore(xmin,xmin+7,ymin,ymax);
fg_stall(delay);
xmin += 32;
xmax -= 32;
ymin += 20;
ymax -= 20;
}
}
}
/****************************************************************************\
* *
* spiral_normal *
* *
* This is a spiral effect in which we reveal the screen as a series of *
* rectangles, emanating from the screen edges and proceeding clockwise to *
* the center of the screen. *
* *
\****************************************************************************/
void spiral_normal(delay)
int delay;
{
int xmin, xmax;
int ymin, ymax;
xmin = 0;
xmax = 319;
ymin = 0;
ymax = 199;
while (xmin < xmax)
{
fg_restore(xmin,xmax,ymin,ymin+19);
fg_stall(delay);
fg_restore(xmax-31,xmax,ymin,ymax);
fg_stall(delay);
fg_restore(xmin,xmax,ymax-19,ymax);
fg_stall(delay);
fg_restore(xmin,xmin+31,ymin,ymax);
fg_stall(delay);
xmin += 32;
xmax -= 32;
ymin += 20;
ymax -= 20;
}
}
/****************************************************************************\
* *
* split_screen *
* *
* Reveal the top half of from left to right while revealing the bottom half *
* from right to left. *
* *
\****************************************************************************/
void split_screen(delay)
int delay;
{
register int xmin, xmax;
xmin = 0;
xmax = 319;
while (xmax > 0)
{
fg_restore(xmin,xmin+7,0,99);
fg_restore(xmax-7,xmax,100,199);
fg_stall(delay);
xmin += 8;
xmax -= 8;
}
}
/****************************************************************************\
* *
* unveil *
* *
* Starting at the center, reveal the screen in small horizontal increments *
* until we reach the left and right edges. *
* *
\****************************************************************************/
void unveil(delay)
int delay;
{
register int xmin, xmax;
xmin = 152;
xmax = 167;
while (xmin >= 0)
{
fg_restore(xmin,xmin+7,0,199);
fg_restore(xmax-7,xmax,0,199);
fg_stall(delay);
xmin -= 8;
xmax += 8;
}
}
/****************************************************************************\
* *
* venetian_blind *
* *
* Reveal the screen in four iterations, each revealing every fourth row. *
* The effect produced resembles opening a Venetian blind. *
* *
\****************************************************************************/
void venetian_blind(delay)
int delay;
{
register int y;
for (y = 0; y < 200; y += 4)
fg_restore(0,319,y,y);
fg_stall(delay);
for (y = 1; y < 200; y += 4)
fg_restore(0,319,y,y);
fg_stall(delay);
for (y = 2; y < 200; y += 4)
fg_restore(0,319,y,y);
fg_stall(delay);
for (y = 3; y < 200; y += 4)
fg_restore(0,319,y,y);
}