int main(void) { /* init ncurses */ WINDOW * mainwin; if (( mainwin = initscr()) == NULL) { fprintf(stderr,"ERROR initializing ncurses.\n"); exit(1); } /* Define all internally used variables */ int loopy,loopx; int keyin=0; /* Initialize BigMap array to all blanks */ for(loopy=1; loopy<=84; loopy++) for(loopx=1; loopx<=84; loopx++) bigmap[loopy][loopx]=' '; for(loopy=1; loopy<=2; loopy++) for(loopx=1; loopx<=84; loopx++) { bigmap[loopy][loopx]='#'; bigmap[loopy+82][loopx]='#'; } for(loopx=1; loopx<=2; loopx++) for(loopy=1; loopy<=84; loopy++) { bigmap[loopy][loopx]='#'; bigmap[loopy][loopx+82]='#'; } for(loopx=1; loopx<=8; loopx++) { shields[loopx]=100; twas[loopx]='B'; } /*********** Main programming starts here ***********/ curs_set(0); drawscr(); initgame(); views(); while(keyin != 27) { keyin = check_keybrd(); switch(keyin) { case 172:movetank(UP);break; case 180:movetank(DOWN);break; case 175:movetank(LEFT);break; case 177:movetank(RIGHT);break; case 182:clrtext();break; case 49:tank=1;views();break; case 50:tank=2;views();break; case 51:tank=3;views();break; case 52:tank=4;views();break; case 53:tank=5;views();break; case 54:tank=6;views();break; case 55:tank=7;views();break; case 56:tank=8;views();break; case 33:decoy=1;views();break; case 64:decoy=2;views();break; case 35:decoy=3;views();break; } remote(); refresh(); } curs_set(1); /* Show Cursor */ return(0); }
void cbzone_while(void) { #ifdef WIN32 if (GetAsyncKeyState( VK_F1 ) < 0) { free(o); return; // myexit(scores(score)); //HACK OUT by Eric Fogelin } #endif gettimeofday(&tstart, 0); gprinqcursor((Position_t *)position); event = gprcondeventwait(&key, (Position_t *)position); if (event && key == 'Q') { free(o); return; // myexit(scores(score)); //HACK OUT by Eric Fogelin } if (event && key == 'R') { clearentirescreen(); staticscreen(); updatedisplay(False, False, -1, 0, False, True); updatedisplay(missilerun, lander, score, opt->numleft, sens, False); if (sight_flag) message(1, False); if (pl->attr & IS_BLOCKED) message(2, False); if (salvo_flag) message(3, False); scanner(o); xhairs(aligned); drawhorizon(pl->azm); } joystick(position, sens, pl); if (!paused) { for (i=0; i<opt->msalvos; i++) { /* now find a shot we can use */ s = pl->salvo+i; if (!(s->attr & STILL_THERE)) break; s = NULL; } if (event && pl->attr & IS_ALIVE) if (keylast) { for (i=0; i<opt->msalvos; i++) { /* now find a shot we can use */ s = pl->salvo+i; if (!(s->attr & STILL_THERE)) break; s = NULL; } if (key == 'a' && s!=NULL) { /* fire up one shot */ playsound(opt->loud?sfire:suser_shoots); s->attr = START_LIVING; s->ecount = 0; s->x = pl->x; s->y = pl->y; s->z = 0.0; s->prox = 0; s->proy = 0; s->azm = pl->azm; s->speed = 40.0; keylast = False; } else if (key == 'b') { /* center our joystick */ position[0] = 500; position[1] = 355; gprsetcursorposition((Position_t *)position); joystick(position, sens, pl); keylast = False; } else if (key == 'c') { /* toggle sensitivity */ sens = !sens; joystick(position, sens, pl); keylast = False; } } else if (key == 'A' || key == 'B' || key == 'C') keylast = True; /* button released */ /* if we can move, update our rotation, bearing (azimuth), and */ /* position. */ if (pl->attr & IS_ALIVE && !(pl->attr & IS_BLOCKED)) { pl->azm += pl->rotate; if (pl->azm > PI2) pl->azm -= PI2; if (pl->azm <= 0.0) pl->azm += PI2; pl->ca = cos(pl->azm); pl->sa = sin(pl->azm); } if (pl->attr & IS_ALIVE) { pl->x -= pl->sa * pl->speed; pl->y += pl->ca * pl->speed; } else pl->speed = 0.0; /* now call the move generation routines for the objects */ /* which require thought, speed and/or rotation may be */ /* affected. */ for (g=o+opt->estart; g<o+opt->sstart; g++) if (g->attr & IS_ALIVE) switch (g->type) { case IS_TANK: movetank(g, pl); break; case IS_SUPER: movesuper(g, pl); break; case IS_MISSILE: movemissile(g, pl, first); break; case IS_COPTER: movecopter(g, pl); break; case IS_LANDER: movelander(g, pl); break; default: printf("Help! Something's alive and I don't know what...\n"); #ifdef WIN32 return; #else //X11 myexit(1); #endif } /* now update their bearing and position */ for (g=o+opt->estart; g<o+opt->lstart; g++) { if (g->attr & IS_ALIVE && !(g->attr & IS_BLOCKED)) g->azm += g->rotate; g->ca = cos(g->azm); g->sa = sin(g->azm); g->x -= g->sa * g->speed; g->y += g->ca * g->speed; } for (g=o+opt->lstart; g<o+opt->bstart; g++) if (g->attr & IS_ALIVE) { g->ca = cos(g->azm); g->sa = sin(g->azm); g->x -= g->sa * g->speed; g->y += g->ca * g->speed; } /* now compute ranges from objects to the player */ for (g=o+opt->estart; g<o+opt->mobjects; g++) if (g->attr & STILL_THERE) g->range = sqrt(DIST(g, pl)); for (g=o; g<o+opt->lstart; g++) /* assume all objects are */ g->attr &= ~IS_BLOCKED; /* unblocked */ /* now check to see if they really were unblocked. If not, then */ /* project them back along their path until they are. This */ /* section just checks for being blocked by blocks. */ for (g=o+opt->bstart; g<o+opt->mobjects; g++) { if (g->range < blocksize) { pl->attr |= BLOCKED_BY_BLOCK; dx = pl->x - g->x; dy = pl->y - g->y; diff = dy * pl->ca - dx * pl->sa; if (pl->speed > 0.0) v = diff + sqrt(diff*diff + blocksizesqrd - g->range*g->range); else if (pl->speed < 0.0) v = diff - sqrt(diff*diff + blocksizesqrd - g->range*g->range); pl->x += pl->sa * v; pl->y -= pl->ca * v; } for (g2=o+opt->estart; g2<o+opt->lstart; g2++) if (g2->attr & IS_ALIVE && (dist = DIST(g, g2)) < blocksizesqrd) { g2->attr |= BLOCKED_BY_BLOCK; if (!(g2->type & (IS_MISSILE | IS_COPTER))) { dx = g2->x - g->x; dy = g2->y - g->y; diff = dy * g2->ca - dx * g2->sa; if (g2->speed > 0.0) v = diff + sqrt(diff*diff + blocksizesqrd - dist); else if (g2->speed < 0.0) v = diff - sqrt(diff*diff + blocksizesqrd - dist); g2->x += g2->sa * v; g2->y -= g2->ca * v; } } } /* if the player moved, or if an enemy did, we need to recompute */ /* the range to that enemy. */ for (g=o+opt->estart; g<o+opt->lstart; g++) if (g->attr & IS_ALIVE && (g->attr & IS_BLOCKED || pl->attr & IS_BLOCKED)) g->range = sqrt(DIST(g, pl)); /* now check to see if the player is blocked by any enemy. */ /* if so, project them back. */ for (g=o+opt->estart; g<o+opt->lstart; g++) if (g->attr & IS_ALIVE && g->range < blocksize) if (!(g->type & (IS_MISSILE | IS_COPTER))) { if (g->attr & IS_BLOCKED) { pl->speed = 0.0; if (fabs(g->speed) < 0.001) g->speed = sign(0.001, g->speed); } pl->attr |= BLOCKED_BY_ENEMY; g->attr |= BLOCKED_BY_ENEMY; ddx = pl->speed * pl->sa - g->speed * g->sa; ddy = pl->speed * pl->ca - g->speed * g->ca; ddx2 = ddx*ddx; ddy2 = ddy*ddy; dx = pl->x - g->x; dy = pl->y - g->y; dif = ddy * dy - ddx * dx; alpha = (dif + sqrt(dif*dif + (blocksizesqrd - g->range*g->range) * (ddx2 + ddy2))) / (ddx2 + ddy2); pl->x += alpha * pl->speed * pl->sa; pl->y -= alpha * pl->speed * pl->ca; g->x += alpha * g->speed * g->sa; g->y -= alpha * g->speed * g->ca; } /* if we've moved, recompute distance to all the salvos */ if (pl->attr & IS_BLOCKED) for (g=o+opt->sstart; g<o+opt->bstart; g++) if (g->attr & IS_ALIVE) g->range = sqrt(DIST(g, pl)); /* enemies disappear if their range is greater than 2200. */ /* We check last[0] to see if they need to be erased. In */ /* most cases probably not, unless we really screw with */ /* their speed. */ tank_stranded = False; for (g=o+opt->estart; g<o+opt->lstart; g++) { g->ecount++; if (g->attr & IS_ALIVE) if (g->range > 2200.0) if (g->dc[0].last) g->attr = ERASE; else g->attr = 0; else if (g->type & (IS_SUPER | IS_TANK) && g->ecount > TANK_STRAND_COUNT) tank_stranded = True; } /* landers are out of range at 2750 */ for (g=o+opt->lstart; g<o+opt->sstart; g++) { g->ecount++; if (g->attr & IS_ALIVE && g->range > 2750.0) if (g->dc[0].last) g->attr = ERASE; else g->attr = 0; } /* blocks also at 2200 */ for (g=o+opt->bstart; g<o+opt->mobjects; g++) if (g->range > 2200.0) if (g->dc[0].last) g->attr = ERASE; else g->attr = 0; /* salvos are never out of range, but their lifetime is limited */ for (g=o+opt->sstart; g<o+opt->bstart; g++) { g->ecount++; if (g->attr & IS_ALIVE && g->ecount > 50) if (g->dc[0].last) g->attr = ERASE; else g->attr = 0; } /* we never set the 'salvo fired' message in this routine. */ /* however, we do have to turn it off. if salvos are alive */ /* we assume the message is on, once no enemy salvos are */ /* alive we turn it off. */ new_salvo_flag = False; for (g=o+opt->sstart; g<o+opt->bstart; g++) if (g->attr & IS_ALIVE) { /* if salvo exist and */ if (g->salvo != pl) /* not owned by player */ new_salvo_flag = True; /* then the flag is set */ /* check to see if a salvo hits a block */ for (g2=o+opt->bstart; g2<o+opt->mobjects; g2++) if (fabs(g2->x - g->x) < g2->criticalx && fabs(g2->y - g->y) < g2->criticaly) { g->attr = START_EXPLODING; g->ecount = 0; } /* now check to see if the salvo kills a lander. */ /* If so, and the player fired the salvo, update */ /* the score. */ for (g2=o+opt->lstart; g2<o+opt->sstart; g2++) if (g2->attr & IS_ALIVE) if (DIST(g, g2) < g2->criticalx) { g->attr = START_EXPLODING; g2->attr = START_EXPLODING; g->ecount = 0; g2->ecount = 0; if (g->salvo == pl) { score += 10000; icheck = score / 100000; if (icheck > scorebase) { opt->numleft++; if (opt->numleft > 4) opt->numleft = 4; scorebase = icheck; } } } /* now check to see if the salvo hit any enemy. The salvo */ /* cannot hit the one who fired it. This prevents range */ /* checking problems when first fired. */ for (g2=o+opt->estart; g2<o+opt->lstart; g2++) if (g2->attr & IS_ALIVE && g->salvo != g2) { dx = g->x - g2->x; dy = g->y - g2->y; testx = fabs( dx * g2->ca + dy * g2->sa); testy = fabs(-dx * g2->sa + dy * g2->ca); if (testx < g2->criticalx && testy < g2->criticaly && (!(g2->type & (IS_MISSILE | IS_COPTER)) || g2->z < 80.0)) { g->attr = START_EXPLODING; g2->attr = START_EXPLODING; g->ecount = 0; g2->ecount = 0; /* if the player fired, give him credit */ if (g->salvo == pl) { if (g2->type & IS_SUPER) score += 5000; else if (g2->type & (IS_MISSILE | IS_COPTER)) { score += 5000; nummissile--; } else score += 3000; icheck = score / 100000; if (icheck > scorebase) { opt->numleft++; if (opt->numleft > 4) opt->numleft = 4; scorebase = icheck; } } } } } /* check to see if a missile or copter rams a lander */ for (g=o+opt->estart; g<o+opt->lstart; g++) if (g->type & (IS_MISSILE | IS_COPTER) && g->attr & IS_ALIVE) for (g2=o+opt->lstart; g2<o+opt->sstart; g2++) if (g2->attr & IS_ALIVE && DIST(g, g2) < g2->criticalx && g->z < 80) { nummissile--; g->attr = START_EXPLODING; g2->attr = START_EXPLODING; g->ecount = 0; g2->ecount = 0; } /* now check if we need to draw the object. */ /* convert into player-centric coordinates */ /* and project a cone forward to see if the */ /* enemy is within it. Also align the gun */ /* gun sights if necessary. */ new_sight_flag = False; aligned = False; lander = False; for (g=o+opt->estart; g<o+opt->mobjects; g++) if (g->attr & (IS_ALIVE|IS_EXPLODING)) { g->dc[0].seen = False; if (g->range < 2000.0) { dx = g->x - pl->x; dy = g->y - pl->y; g->proy = -dx * pl->sa + dy * pl->ca; g->prox = dx * pl->ca + dy * pl->sa; check = g->proy / (fabs(g->prox) + 1.0); if (check > threshold) { g->dc[0].seen = True; if (g->type & IS_ENEMY && g->attr & IS_ALIVE) new_sight_flag = True; if (fabs(g->prox) < 50 && g->attr & IS_ALIVE && !(g->type & (IS_ABLOCK | IS_SALVO))) aligned = True; } if (g->type & IS_LANDER && g->attr & IS_ALIVE && check > landerthreshold) { lander = True; if (fabs(g->prox) < 60) aligned = True; } } } /* change the various messages, if necessary. Never use */ /* the bell, unless opt->loud is True. */ if (sight_flag && !new_sight_flag) { message(-1, False); sight_flag = False; } else if (!sight_flag && new_sight_flag) { message(1, False); sight_flag = True; playsound(senemy_seen); } if (pl->attr & IS_BLOCKED && !blocked_flag) { message(2, True); blocked_flag = True; playsound(smove_blocked); } else if (!(pl->attr & IS_BLOCKED) && blocked_flag) { message(-2, False); blocked_flag = False; } if (salvo_flag && !new_salvo_flag) { message(-3, False); salvo_flag = False; } else if (!salvo_flag && new_salvo_flag) { salvo_flag = True; playsound(ssalvo_fired); } scanner(o); updatedisplay(missilerun, lander, score, opt->numleft, sens, False); xhairs(aligned); drawhorizon(pl->azm); /* now draw all the objects */ for (g=o+opt->estart; g<o+opt->mobjects; g++) { if (g->attr & (IS_ALIVE | ERASE)) drawobject(g, pl); else if (g->attr & (IS_EXPLODING | EXERASE)) switch (g->type) { case IS_SALVO: explodesalvo(g, pl); break; case IS_COPTER: case IS_MISSILE: case IS_LANDER: case IS_TANK: case IS_SUPER: if (g->ecount == 1) playsound(opt->loud?skill:sobject_explodes); explodeobject(g, pl); break; default: printf("Help! Cannot explode what doesn't exist.\n"); #ifdef WIN32 return; #else //X11 myexit(1); #endif } g->attr &= ~(ERASE | EXERASE); } /* now start checking for player death. if there is a missile, */ /* check to see if it rammed the player. */ if (missilerun) for (g=o+opt->estart; g<o+opt->lstart; g++) if (g->attr & IS_ALIVE && g->type & (IS_MISSILE | IS_COPTER) && g->range < blocksize && g->z < 80) { g->attr = START_EXPLODING; drawcracks(); pl->attr &= ~IS_ALIVE; dead = True; deadcount = 0; } /* check to see if any salvos hit. */ for (g=o+opt->sstart; g<o+opt->bstart; g++) if (g->attr & IS_ALIVE && g->salvo != pl && g->range < 100.0 && fabs(g->prox) < pl->criticalx && fabs(g->proy) < pl->criticaly) { drawobject(g, pl); g->attr = 0; drawcracks(); pl->attr &= ~IS_ALIVE; dead = True; deadcount = 0; } /* if we are dead, redraw the cracks every five turns. after 50 */ /* turns, we can start playing again if we have any lives left. */ if (dead) { if (deadcount == 0) playsound(opt->loud?suser_died:sobject_explodes); if (deadcount%5 == 0) drawcracks(); if (deadcount > 50) { dead = False; if (!opt->training && (--opt->numleft < 0)) { #ifdef DEVELOPER gettimeofday(&game_end, 0); if (opt->output) printf("The game took an average %10.8f secs.\n", (game_end.tv_sec-game_start.tv_sec + (game_end.tv_usec-game_start.tv_usec)*1.0e-6)/passes); #endif //DEVELOPER free(o); #ifdef WIN32 return; #else //X11 myexit(scores(score)); #endif } if (missilerun) { nummissile -= 2; if (nummissile <= 0 && opt->mtanks) { missilerun = False; nextmissile = 750 * frand() + 750; } } clearscreen(); pl->x = 0.0; /* reset all our attributes */ pl->y = 0.0; pl->speed = 0.0; pl->azm = 0.0; pl->ca = 1.0; pl->sa = 0.0; pl->attr = START_LIVING; message(-1, False); /* turn off all the messages */ sight_flag = False; message(-2, False); // blocked_flag = False; message(-3, False); salvo_flag = False; for (g=o+opt->estart; g<o+opt->mobjects; g++) g->attr = 0; /* remove all objects */ } } /* Now schedule the missile runs. There will be a missile run if */ /* mtanks==0 or we are in copter practice or if a tank has been */ /* around too long or we haven't had a missile in a while. */ if (pl->attr & IS_ALIVE && opt->mmissiles && (!opt->mtanks || opt->copters || tank_stranded || missilecount > nextmissile)) if (!missilerun) { missilecount = 0; for (g=o+opt->estart; g<o+opt->bstart; g++) if (!(g->type & (IS_LANDER | IS_MISSILE | IS_COPTER))) if (g->attr & IS_ALIVE) g->attr = ERASE; else if (g->attr & IS_EXPLODING) g->attr = EXERASE; nummissile = frand() * 3 * opt->mmissiles + 1; if (firstmissile) nummissile = 1; first = firstmissile; firstmissile = False; missilerun = True; } /* once this run is over, schedule another one for a later date */ if (missilerun && opt->mtanks && nummissile <= 0) { missilerun = False; nextmissile = 750 * frand() + 750; } /* now place whatever objects need to be placed. */ if (!dead) placeobjects(o, missilerun, score); pl->attr &= ~IS_NEW; /* in case the player was new */ deadcount++; if (!missilerun) missilecount++; /* use timeclock here instead of gettimeofday to get a sync(d, 0) * just in case there are graphics we need to draw. */ timeclock(&tend); tdiff = limit - ((tend.tv_sec-tstart.tv_sec)*1e6+tend.tv_usec-tstart.tv_usec); if (tdiff > 0) { tend.tv_sec = 0; tend.tv_usec = tdiff; select(0, 0, 0, 0, &tend); } #ifdef DEVELOPER passes++; #endif //DEVELOPER } }
int main(void) { /* init ncurses */ WINDOW * mainwin; if (( mainwin = initscr()) == NULL) { fprintf(stderr, "ERROR initializing ncurses.\n"); exit(1); } /* Define all internally used variables */ int loopy, loopx; int keyin = 0; /* Initialize BigMap array to all blanks */ for (loopy = 1; loopy <= 84; loopy++) { for (loopx = 1; loopx <= 84; loopx++) { bigmap[loopy][loopx]=' '; } } /* Create the inpenetrable walls around the big map */ /* Top and Bottom wall */ for (loopy = 1; loopy <= 2; loopy++) { for (loopx = 1; loopx <= 84; loopx++) { bigmap[loopy][loopx] = '#'; bigmap[loopy+82][loopx] = '#'; } } /* Left and Right wall */ for (loopx = 1; loopx <= 2; loopx++) { for(loopy = 1; loopy <=84; loopy++) { bigmap[loopy][loopx] = '#'; bigmap[loopy][loopx+82] = '#'; } } /* Initialize the tanks shields to 100 and their previous character to 'B' indicating they were on the Base */ for (loopx = 1; loopx <= 8; loopx++) { shields[loopx] = 100; twas[loopx] = 'B'; } /*********** Main programming starts here ***********/ /* hide the cursor */ curs_set(FALSE); // disable the cursor drawscr(); initgame(); views(); /* Main Game Loop - Exits when ESC is pressed */ while(keyin != 27) { keyin = check_keybrd(); switch(keyin) { case 172: movetank(UP); break; case 180: movetank(DOWN); break; case 175: movetank(LEFT); break; case 177: movetank(RIGHT); break; case 182: clrtext(); break; case 49: tank = 1; views(); break; case 50: tank = 2; views(); break; case 51: tank = 3; views(); break; case 52: tank = 4; views(); break; case 53: tank = 5; views(); break; case 54: tank = 6; views(); break; case 55: tank = 7; views(); break; case 56: tank = 8; views(); break; case 33: decoy = 1; views(); break; case 64: decoy = 2; views(); break; case 35: decoy = 3; views(); break; } remote(); refresh(); } curs_set(1); /* Show Cursor */ return(0); }