|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 5572 (0x15c4)
Types: TextFile
Names: »ship.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/X/Roids/ship.c«
/* ship.c - handle movement, etc. of the ship. */
#include "roids.h"
#include "explode.bit"
#define MAXDIR 256
static int shipx[MAXDIR][NPOINTS];
static int shipy[MAXDIR][NPOINTS];
static double velx[MAXDIR];
static double vely[MAXDIR];
int px[NPOINTS], py[NPOINTS]; /* What points describe the ships outline */
/* now. */
static int orientation;
double sx, sy; /* The ship's current location (where the */
/* center of it is, in units of pixels. */
static double vx, vy; /* The ship's current velocity (in units */
/* of pixels per repaint.) */
static int ex, ey; /* Where we're painting an explosion. */
static Boolean showingexplosion = FALSE;
static int dturn;
static int goalx = -1, goaly;
static Boolean thrust;
void InitShip()
{
int i, d;
double angle;
shipdestroyed = TRUE;
showingexplosion = FALSE;
shiptimerid = NULL;
orientation = 0;
vx = vy = 0.0;
dturn = 0;
thrust = FALSE;
d = shipradius;
if (d > shipradius) d = shipradius;
for (i=0 ; i < numdir ; i++) {
angle = i * 2 * M_PI / (double) numdir;
shipx[i][0] = (int) rint(d * cos(angle + M_PI_2));
shipy[i][0] = (int) rint(-d * sin(angle + M_PI_2));
shipx[i][1] = (int) rint(d * cos(angle + M_PI + M_PI_4));
shipy[i][1] = (int) rint(-d * sin(angle + M_PI + M_PI_4));
shipx[i][2] = (int) rint(d * cos(angle - M_PI_4));
shipy[i][2] = (int) rint(-d * sin(angle - M_PI_4));
velx[i] = cos(angle + M_PI_2);
vely[i] = -sin(angle + M_PI_2);
}
}
void PaintShip(gc)
GC gc;
{
static double lx = -100.0, ly = -100.0;
static int lorient = -1;
int i, j, x, y;
BeginLines();
if (sx != lx || sy != ly || orientation != lorient) {
lx = sx;
ly = sy;
lorient = orientation;
for (i=0 ; i<NPOINTS ; i++) {
px[i] = sx + shipx[orientation][i];
py[i] = sy + shipy[orientation][i];
}
}
for (i=0 ; i<NPOINTS ; i++) {
j = (i + 1) % NPOINTS;
AddLine(px[i], py[i], px[j], py[j], gc);
}
EndLines();
}
void DestroyShip()
{
XImage ximage;
PaintShip(backgc);
shipdestroyed = TRUE;
ex = sx - explode_width/2;
ey = sy - explode_height/2;
ximage.height = explode_height;
ximage.width = explode_width;
ximage.xoffset = 0;
ximage.format = XYBitmap;
ximage.data = (char *)explode_bits;
ximage.byte_order = LSBFirst;
ximage.bitmap_unit = 16;
ximage.bitmap_bit_order = LSBFirst;
ximage.bitmap_pad = 16;
ximage.bytes_per_line = (ximage.width+15)/16 * 2;
ximage.depth = 1;
XPutImage(dpy, gamewindow, shipgc, &ximage,
0, 0, ex, ey, explode_width, explode_height);
showingexplosion = TRUE;
if (shiptimerid) XtRemoveTimeOut(shiptimerid);
shiptimerid = XtAddTimeOut(1000, MoveShip, (Opaque) MoveShip);
}
void MoveShip(closure, id)
Opaque closure;
XtIntervalId id;
{
int i, j, newx, newy;
if (closure != (Opaque) MoveShip) return;
if (shipdestroyed) {
if (showingexplosion) {
XClearArea(dpy, gamewindow, ex, ey, explode_width, explode_height,
FALSE);
showingexplosion = FALSE;
shiptimerid = XtAddTimeOut(2000, MoveShip, (Opaque) MoveShip);
return;
}
sx = gamewidth / 2.0;
sy = gameheight / 2.0;
if (!AreaForShipIsClear()) {
shiptimerid = XtAddTimeOut(100, MoveShip, (Opaque) MoveShip);
return;
}
if (shipsleft <= 0) Quit();
shipsleft--;
PaintScore();
shipdestroyed = FALSE;
vx = vy = 0.0;
}
shiptimerid = XtAddTimeOut(shipwait, MoveShip, (Opaque) MoveShip);
PaintShip(backgc);
if (goalx >= 0) dturn = FindGoalTurn();
if (dturn) {
orientation += dturn;
if (orientation < 0) orientation = numdir - 1;
else if (orientation >= numdir) orientation = 0;
}
if (thrust) {
vx += velx[orientation] * accper;
vy += vely[orientation] * accper;
vx = (vx > maxv) ? maxv : ((vx < -maxv) ? -maxv : vx);
vy = (vy > maxv) ? maxv : ((vy < -maxv) ? -maxv : vy);
}
sx += vx;
sy += vy;
sx = (sx < 0) ? sx + gamewidth : ((sx > gamewidth) ? sx - gamewidth : sx);
sy = (sy < 0) ? sy + gameheight: ((sy > gameheight)? sy - gameheight: sy);
PaintShip(shipgc);
if (CheckIfShipHitRocks())
DestroyShip();
}
void ThrustOn()
{
thrust = TRUE;
}
void ThrustOff()
{
thrust = FALSE;
}
void RotateLeft()
{
dturn = 1;
goalx = -1;
}
void RotateRight()
{
dturn = -1;
goaly = -1;
}
void RotateOff()
{
dturn = 0;
}
int FindGoalTurn()
{
double dx, dy;
double theta;
int dgoal;
dx = goalx - sx;
dy = goaly - sy;
if (rint(dy) == 0 && rint(dy) == 0)
return 0;
theta = atan2(-dy, dx);
theta += 3 * M_PI_2;
dgoal = (theta * numdir) / (2 * M_PI);
dgoal = dgoal % numdir;
if (dgoal == orientation) return 0;
else if (orientation < dgoal) {
if (dgoal - orientation <= numdir / 2)
return 1;
else return -1;
} else {
if (orientation - dgoal <= numdir / 2)
return -1;
else return 1;
}
}
void RotateToPoint(w, event, params, num_params)
Widget w;
XEvent *event;
char **params;
int *num_params;
{
goalx = event->xbutton.x;
goaly = event->xbutton.y;
}
void RotateMouseMoved(w, event, params, num_params)
Widget w;
XEvent *event;
char **params;
int *num_params;
{
goalx = event->xbutton.x;
goaly = event->xbutton.y;
}
void StopRotateToPoint()
{
goalx = -1;
dturn = 0;
}
void Fire()
{
double dx, dy;
if (!shipdestroyed) {
dx = vx + velx[orientation] * shotacc;
dy = vy + vely[orientation] * shotacc;
dx = dx * shotwait / shipwait;
dy = dy * shotwait / shipwait;
AddShot(sx, sy, dx, dy);
}
}