Source code for flying star field screen saver
/* -----------------------------------------------------------------------
Program starsvr.c: a screen saver written to use 640 x 480 16 color VGA
and display a starfield in which the viewer is moving through. Written
in ten days a few hours a day three months after my lay off.
Code represents some of the foundations for C++ in the use of structures.
--------------
programmer: T Wright
dated: August 1, 1993
dated: August 26, 1994 upgraded for Borland C/C++ compiler...
--------------------------------------------------------------*/
/* Standard Include files */
/* definitions */
#define starnumber 35 /* the number of stars to see */
#define xpixoffrt 380L /* boundry center blank-out stars */
#define ypixofftop 140L /* left and right top and bottom */
#define xpixofflft 250L
#define ypixoffbot 320L
#define xpixbrtrt 480L /* boundry where stars brighten for*/
#define ypixbrttop 95L /* them traveling closer */
#define xpixbrtlft 180L
#define ypixbrtbot 350L
#define centerx 320L /* initial center field of view */
/* structure definitions */
typedef struct starpos
{
double xpos;
double ypos;
int pixcolor;
double xyangle;
double zangle;
double sinanginc;
double cosanginc;
}locstar;
/* prototypes */
void backgrnd();
void foregrnd();
void kybexit( void );
void shading( int, locstar *, double startxypos[] );
void newstar( int, locstar *, double startxypos[], int );
void steering ( double * );
void trajectory( int, locstar *, double startxypos[] );
void edgeblnkout( int, locstar * );
void updpos( locstar *, double );
double degsin( double );
double degcos( double );
void main( void );
float ovrlcnst = 0.45L;
/* MAIN BODY */
void main( void )
{
// initialize the graphics system
int graphdriver = DETECT, graphmode;
initgraph(&graphdriver, &graphmode, "c:\\tc\\bgi");
setgraphmode( 2 ); /* set video mode to 16 color VGA */
backgrnd(); /* call starfield background first */
foregrnd(); /* move viewer through the field
routine will not exit.... */
return;
}
/* subroutines used by main */
/***************************************************************************/
void backgrnd()
{
int x, y; /* local x,y position of each star */
unsigned i,colorch = 12; /* color to star with in background*/
srand( 20 ); /* seed the random number generator*/
for( i = 0; i <= 100; ++i ) { /* begin loop to create background */
x = rand() / 51; /* no more than 100 stars random */
y = rand() / 68; /* value represent bound to VGA pix*/
putpixel( x, y, colorch++ ); /* put out the pixel */
if( colorch > 9 ) /* bounds check-stay bright colors */
{ colorch = 4; } /* go back to initial color */
else if ( colorch == 7 ) /* FILTER: want a different color */
{ colorch ++; }
} /* next two lines are for test only*/
return;
}
/***************************************************************************/
void foregrnd()
{
int initial = 1, i, x, y, colorreposit;
double cosval, sinval, random, startxypos[2] = { 320.0L, 240.0L };
double xstroff = 0.0L, ystroff = 0.0L;
locstar *star; /* set up star struct */
if ( NULL == ( star = ( starpos * ) calloc(starnumber,sizeof(locstar))) )
{
puts(" can not allocate the star memory " );
abort();
}
for (;;)
{
for (i = 0; i <= starnumber-1; i++) /* loop through starnumber stars */
{
newstar( i, star, startxypos, initial );
/* create new star now? */
star[i].pixcolor = 0; /* blank old position movement */
/* wink out star with black */
x = ( int )star[i].xpos; /* convert to integer and display */
y = ( int )star[i].ypos;
putpixel( x, y, star[i].pixcolor ); /* put out the pixel */
/* shading star depending on loc */
shading( i, star, startxypos );
/* update new position */
trajectory( i, star, startxypos );
edgeblnkout( i, star ); /* blink out star when @ scrn edge */
initial = 0; /* reset initial pass set up */
steering( &startxypos[2] ); /* steer heading left or right */
}
}
}
/***************************************************************************/
double degsin( double degreeinput)
{
double sinvalue;
double sininput;
sininput = ( 0.0174527L * degreeinput ); /* multiply by constant for deg*/
sinvalue = sin( sininput ); /* get the trig value */
return( sinvalue ); /* pass by value to caller */
}
/***************************************************************************/
double degcos( double degreeinput)
{
double cosvalue;
double cosinput;
cosinput = ( 0.0174527L * degreeinput ); /* multiply by constant for deg*/
cosvalue = cos( cosinput ); /* get the trig value */
return( cosvalue ); /* pass by value to caller */
}
/***************************************************************************/
void steering( double *startxypos )
{
int keyboard;
if( startxypos[0] < 320.0L )
{
startxypos[0] += 2.0L;
}else if( startxypos[0] > 320.0L )
{
startxypos[0] -= 2.0L;
}
if( kbhit() ) /* sensed keyboard touch quit */
{
keyboard = getch();
if( keyboard == 0x20 )
{
setgraphmode( 2 ); /* set video mode to 16 color VGA */
exit( 0 );
}
else
{
// keyboard = getch();
if( keyboard == 'K' )
{
// startxypos[0] -= 10.0L;
ovrlcnst -= 0.05L;
if ( ovrlcnst < 0.0L ) ovrlcnst = 0.05L;
}
if( keyboard == 'J' )
{
// startxypos[0] += 10.0L;
ovrlcnst += 0.05L;
}
}
}
return;
}
/***************************************************************************/
void shading( int i, locstar *star, double startxypos[] )
{
double xpixwnd;
xpixwnd = startxypos[0] - centerx;
if( star[i].xpos < ( xpixoffrt + xpixwnd ) &&
star[i].ypos < ypixoffbot &&
star[i].xpos > ( xpixofflft + xpixwnd ) &&
star[i].ypos > ypixofftop )
{
star[i].pixcolor = 0;
}else if( star[i].xpos > ( xpixbrtrt + xpixwnd ) ||
star[i].ypos > ypixbrtbot ||
star[i].xpos < ( xpixbrtlft + xpixwnd )||
star[i].ypos < ypixbrttop )
{
star[i].pixcolor = 15; /* restore it */
}else
{
star[i].pixcolor = 11;
}
return;
}
/***************************************************************************/
void newstar( int i, locstar *star, double startxypos[], int initial )
{
double xstroff = 0.0L, ystroff = 0.0L, random;
if( xstroff > 40.0L || ystroff < -25.0L )
{
xstroff = ystroff = 0.0L; /* limit excursion from center */
}
if( initial || star[i].xpos <= 0.0 || star[i].ypos <= 0.0
|| star[i].xpos >= 639.0 || star[i].ypos >= 479.0 )
{
random =( rand() / 91.0L ); /* get rand number norm 0-360 */
star[i].xyangle = random; /* remember the angle */
star[i].zangle = 0.2L; /* distance at infinity */
star[i].sinanginc = degsin( random ); /* obtain trig values */
star[i].cosanginc = degcos( random );
star[i].xpos = startxypos[0] + xstroff++; /* initial position */
star[i].ypos = startxypos[1] + ystroff--; /* but not all same place */
}
return;
}
/***************************************************************************/
void trajectory( int i, locstar *star, double startxypos[] )
{
double speed;
int x, y;
star[i].zangle = ( star[i].zangle * 1.25L );
// star[i].zangle *= 100.L;
if( star[i].zangle > 90.0 ) star[i].zangle = 90.0L; /*adj sense depth*/
if( !( i % 3 ) ) /* pick stars div by 3 */
{
speed = 1.5L * ovrlcnst;
updpos( star, speed );
}else if( !( i % 2 ) ) /* pick stars div by 2 */
{
speed = 6.5L * ovrlcnst;
updpos( star, speed );
}else
{
speed = 12.0L* ovrlcnst;
updpos( star, speed );
}
x = ( int )star[i].xpos; /* convert to integer and display */
y = ( int )star[i].ypos;
putpixel( x, y, star[i].pixcolor ); /* put out the pixel */
return;
}
/***************************************************************************/
void edgeblnkout( int i, locstar *star )
{
int x, y;
/* when the star reaches the border blank it out */
if( star[i].xpos <= 5.0 || star[i].ypos <= 5.0
|| star[i].xpos >= 630.0 || star[i].ypos >= 470.0 )
{
star[i].pixcolor = 0;
x = ( int )star[i].xpos; /* convert to integer and display */
y = ( int )star[i].ypos;
putpixel( x, y, star[i].pixcolor ); /* put out the pixel */
}
return;
}
/***************************************************************************/
void steereffct( locstar *star, double startxypos[] )
{
static double drift = 0;
static double prevdrift;
double warptraject;
static starcnt = 0;
int x, y, i;
if( drift ) /* actual drift noticed? */
{
if( ++starcnt > starnumber ) /* then we are in a turn */
{ /* by this code drift val*/
starcnt = drift = 0; /* will freeze for size */
} /* of stars */
star[i].sinanginc = degsin( star[i].xyangle );
star[i].cosanginc = degcos( star[i].xyangle );
}else
{
drift = startxypos[0] - prevdrift; /* moved center turning? */
prevdrift = startxypos[0];
}
return;
}
/***************************************************************************/
void updpos( locstar *star, double speed )
{
int i;
star[i].xpos += ( star[i].cosanginc *
( speed * degsin(star[i].zangle) ) );
star[i].ypos += star[i].sinanginc *
( speed * degsin(star[i].zangle) );
return;
}