DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦80860fe6c⟧ TextFile

    Length: 7268 (0x1c64)
    Types: TextFile
    Names: »rocks.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/X/Roids/rocks.c« 

TextFile

/* rkocks.c - handle movement, etc. of the rocks. */

#include "roids.h"



#define NUMTYPES	3	/* How many types of rocks there are. */
#define MAXPOINTS	10	/* Maximum number of points in a rock. */

#define MAXROCKS	256	/* Maximum rocks we'll have at one time. */


static int numtocreate = 4;	/* How many rocks to create each round. */


#define DIAMONDDATA(size)	\
{0, size},			\
{size, 0},			\
{0, -size},			\
{-size, 0},





static int smallshape[][2] = {
    DIAMONDDATA(10)
    };
static int mediumshape[][2] = {
    DIAMONDDATA(15)
    };
static int largeshape[][2] = {
    DIAMONDDATA(20)
    };


static int ***shapes;


static int numpoints[NUMTYPES] = {XtNumber(largeshape), XtNumber(mediumshape),
				      XtNumber(smallshape)};

int radius[NUMTYPES];

extern double sx, sy;		/* Ship location. */

typedef struct _RockRec {
    double x, y;		/* Location. */
    double vx, vy;		/* Velocity. */
    int radius;			/* Radius of this rock. */
    int **shape;		/* Pointer to shape record. */
    int numpoints;		/* Number of points in shape record. */
} RockRec, *Rock;

RockRec rocks[MAXROCKS+2];

int numrocks = 0;		/* Number of rocks existing. */


#define RockNearBox(rock, minx, maxx, miny, maxy)	\
    (rint((rock)->x) - (rock)->radius <= (maxx) &&		\
     rint((rock)->y) - (rock)->radius <= (maxy) &&		\
     rint((rock)->x) + (rock)->radius >= (minx) &&		\
     rint((rock)->y) + (rock)->radius >= (miny))


#define RandomSpeed()	(maxrockspeed * (random() % 2000 - 1000) / 1000.0)

Boolean AreaForShipIsClear()
{
    int minx, maxx, miny, maxy, i;
    Rock rock;
    minx = sx - 5 * shipradius;
    maxx = sx + 5 * shipradius;
    miny = sy - 5 * shipradius;
    maxy = sy + 5 * shipradius;
    for (i=0, rock = rocks ; i<numrocks ; i++, rock++) {
	if (RockNearBox(rock, minx, maxx, miny, maxy))
	    return FALSE;
    }
    return TRUE;
}



static void ConfigureRock(rock, x, y, vx, vy, shape, numpoints, radius)
Rock rock;
double x, y, vx, vy;
int **shape;
int numpoints, radius;
{
    rock->x = x;
    rock->y = y;
    rock->vx = vx;
    rock->vy = vy;
    rock->shape = shape;
    rock->numpoints = numpoints;
    rock->radius = radius;
}



static void PaintRock(rock, gc)
Rock rock;
GC gc;
{
    register int x = rock->x;
    register int y = rock->y;
    register int i;
    for (i=0 ; i<rock->numpoints ; i++)
	AddLine(x + rock->shape[i][0], y + rock->shape[i][1],
		x + rock->shape[i+1][0], y + rock->shape[i+1][1],
		gc);
}



/*
 * Destroy rock #i.  Often, this means creating two rocks in its place.  The
 * point given is used to determine the direction of the destroying influence,
 * and thus which direction the two rocks should go.
 */

static void DestroyRock(i, x, y)
int i, x, y;
{
    int num, value;
    Rock rock = rocks + i;
    double oldx = rock->x;
    double oldy = rock->y;
    PaintRock(rock, backgc);
    value = 50;
    for (num = 0 ; num < NUMTYPES ; num++)
	if (rock->shape == shapes[num]) break;
	else value *= 2;
    if (num >= NUMTYPES)
	Punt("Couldn't find shape in DestroyRock!");
    score += value;
    PaintScore();
    numrocks--;
    rocks[i] = rocks[numrocks];
    num++;
    if (num < NUMTYPES) {
	for (i=numrocks ; i<MIN(MAXROCKS, numrocks+2) ; i++) {
	    ConfigureRock(rocks + i, oldx, oldy, RandomSpeed(), RandomSpeed(),
			  shapes[num], numpoints[num], radius[num]);
	}
	numrocks = MIN(MAXROCKS, numrocks + 2);
    }
}


	
Boolean LineHitsRock(ax, ay, bx, by)
int ax, ay, bx, by;
{
    register Rock rock;
    int i, j, x, y;
    register int minx, miny, maxx, maxy;
    int **shape;
    minx = MIN(ax, bx);
    maxx = MAX(ax, bx);
    miny = MIN(ay, by);
    maxy = MAX(ay, by);
    for (i=0, rock = rocks ; i<numrocks ; i++, rock++) {
	if (RockNearBox(rock, minx, maxx,  miny, maxy)) {
	    shape = rock->shape;
	    x = rock->x;
	    y = rock->y;
	    for (j=0 ; j<rock->numpoints ; j++) {
		if (CheckIntersects(ax, ay, bx, by,
				    shape[j][0] + x, shape[j][1] + y,
				    shape[j+1][0] + x, shape[j+1][1] + y)) {
		    DestroyRock(i, ax, ay);
		    return TRUE;
		}
	    }
	}
    }
    return FALSE;
}
	    
	

/* 
 * Carefully check if the given rock has hit the ship.  If so, destroy the
 * rock (creating new rocks as necessary), and return TRUE.  This does not
 * touch the ship; that is left to the calling routine.
 */

static Boolean CheckForCrash(rock)
Rock rock;
{
    extern int px[], py[];
    int i, j, ax, ay, bx, by;
    int **shape = rock->shape;
    int x = rock->x;
    int y = rock->y;
    if (shipdestroyed) return FALSE;
    for (i=0 ; i < NPOINTS ; i++) {
	ax = px[i];
	ay = py[i];
	bx = px[(i+1) % NPOINTS];
	by = py[(i+1) % NPOINTS];
	for (j=0 ; j<rock->numpoints ; j++) {
	    if (CheckIntersects(ax, ay, bx, by,
				shape[j][0] + x, shape[j][1] + y,
				shape[j+1][0] + x, shape[j+1][1] + y)) {
		DestroyRock(rock - rocks, rint(sx), rint(sy));
		return TRUE;
	    }
	}
    }
    return FALSE;
}


Boolean CheckIfShipHitRocks()
{
    int i, minx, miny, maxx, maxy;
    Rock rock;
    minx = sx - shipradius;
    miny = sy - shipradius;
    maxx = sx + shipradius;
    maxy = sy + shipradius;
    for (i=0, rock = rocks ; i < numrocks ; i++, rock++) {
	if (RockNearBox(rock, minx, maxx, miny, maxy)) {
	    if (CheckForCrash(rock))
		return TRUE;
	}
    }
    return FALSE;
}



void PaintAllRocks()
{
    int i;
    for (i=0 ; i<numrocks ; i++)
	PaintRock(rocks + i, rockgc);
}

void MoveRocks(closure, id)
Opaque closure;
XtIntervalId id;
{
    register Rock rock;
    register int i;
    int minx, miny, maxx, maxy;
    if (closure != (Opaque) MoveRocks) return;
    rocktimerid = XtAddTimeOut(rockwait, MoveRocks, (Opaque) MoveRocks);
    if (numrocks == 0) {
	numrocks = MIN(numtocreate, MAXROCKS);
	numtocreate += 2;
	for (i=0 ; i<numrocks ; i++) {
	    ConfigureRock(rocks + i, 0.0, 0.0,
			  RandomSpeed(), RandomSpeed(),
			  shapes[0], numpoints[0], radius[0]);
	}
    }
    minx = sx - shipradius;
    miny = sy - shipradius;
    maxx = sx + shipradius;
    maxy = sy + shipradius;
    for (i=0 ; i<numrocks ; i++) {
	rock = rocks + i;
	PaintRock(rock, backgc);
	rock->x += rock->vx;
	rock->y += rock->vy;
	rock->x = (rock->x < 0) ? rock->x + gamewidth :
	    ((rock->x > gamewidth) ? rock->x - gamewidth : rock->x);
	rock->y = (rock->y < 0) ? rock->y + gameheight :
	    ((rock->y > gameheight)? rock->y - gameheight: rock->y);
	PaintRock(rock, rockgc);
	if (RockNearBox(rock, minx, maxx, miny, maxy)) {
	    if (CheckForCrash(rock))
		DestroyShip();
	}
    }
}
	
	

static void SetIt(shape, init, num)
int **shape;
int init[][2];
int num;
{
    int i, j;
    for (i=0 ; i<num+1 ; i++) {
	shape[i] = (int *) XtMalloc(sizeof(int) * 2);
	for (j=0 ; j<2 ; j++)
	    shape[i][j] = init[i%num][j];
    }
}

void InitRocks()
{
    int i, j, m;
    rocktimerid = NULL;
    shapes = (int ***) XtMalloc(sizeof(int **) * NUMTYPES);
    for (i=0 ; i<NUMTYPES ; i++) {
	shapes[i] = (int **) XtMalloc(sizeof(int *) * (numpoints[i] + 1));
    }
    SetIt(shapes[0], largeshape, numpoints[0]);
    SetIt(shapes[1], mediumshape, numpoints[1]);
    SetIt(shapes[2], smallshape, numpoints[2]);
    for (i=0 ; i<NUMTYPES ; i++) {
	m = -1;
	for (j=0 ; j<numpoints[i] ; j++) {
	    m = MAX(m, shapes[i][j][0]);
	    m = MAX(m, shapes[i][j][1]);
	}
	radius[i] = m;
    }
}