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 */


#include <stdio.h>
#include <conio.h>
#include <graphics.h>

#include <math.h>

#include <stdlib.h>

/* 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;

}