/* GL-117 Copyright 2001, 2002 Thomas A. Drexl aka heptargon This file is part of GL-117. GL-117 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GL-117 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GL-117; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This file includes the main program. */ /* To fully understand the GL-117 code, please read the methods from bottom to top! */ /* TODO: - options => video => resolution and fullscreen (both with restart) - correct transport2 (left side corrupt in VRML) and add mission with transport2 - southern seashore landscape (additional missions) - alpine snow landscape (additional missions) - tree colors (fall, spring), draw more tree textures - particle systems: rain, clouds to fly through */ #ifndef IS_MAIN_H #include "main.h" #include "menu.h" #include "maploader.h" #include "dirs.h" #include "gl.h" #include "land.h" #include "net.h" #include "mathtab.h" #include "cockpit.h" #include "conf.h" #include "mission.h" #include "glland.h" #include "common.h" #include int mousex, mousey; int debug = 1; bool multiplayer = false, isserver = false; int day = 1; int weather = WEATHER_SUNNY; float sungamma = 45.0; int camera = 0; float camx = 0, camy = 0, camz = 0, camphi = 0, camgamma = 0, camtheta = 0; float view_x = 0, view_y = 0; float sunlight = 1.0, sunlight_dest = 1.0; float blackout = 0, redout = 0; int lighting = 1; int mode = 0; // pre-defined screen resolutions (x, y, bpp, fullscreen) int resolution [4] [4] = { { 1024, 768, 32, 1 }, { 800, 600, 32, 1 }, { 640, 480, 32, 1 }, { 640, 480, 32, 0 } }; float nearclippingplane = 0.25; // do NOT lower this! bool sunblinding = false; Dirs *dirs; Server *server = NULL; Client *client = NULL; /*#ifdef HAVE_SDL SDL_Thread *threadnet = NULL; #endif*/ int game = GAME_INIT; int debuglevel = LOG_MOST; int showcollision = 0; int brightness = 0; int contrast = 10; SoundSystem *sound = NULL; GL *gl; float getView () { if (weather == WEATHER_THUNDERSTORM && view > 40.0) return 40.0; return view; } int clouds = 0; CTexture *texradar1, *texradar2, *texarrow;//, *texcounter; MapLoader *maploader; float visibleangle = 80.0F; CTexture *texsun, *texflare1, *texflare2, *texflare3, *texflare4, *texmoon = NULL, *texcross, *texcross2, *texranks, *texmedals; CTexture *texclouds1, *texclouds2, *texclouds3; PilotList *pilots; CExplosion *explosion [maxexplosion]; CBlackSmoke *blacksmoke [maxblacksmoke]; GLLandscape *l = NULL; Font *font1, *font2; CTexture *textitle; Uint32 lasttime = 0; CLoad3DS g_Load3ds; CModel model_fig; CModel model_figa; CModel model_figb; CModel model_figc; CModel model_figd; CModel model_fige; CModel model_figf; CModel model_figg; CModel model_figh; CModel model_figi; CModel model_figt; CModel model_figu; CModel model_cannon1; CModel model_cannon2; CModel model_cannon1b; CModel model_cannon2b; CModel model_flare1; CModel model_chaff1; CModel model_missile1; CModel model_missile2; CModel model_missile3; CModel model_missile4; CModel model_missile5; CModel model_missile6; CModel model_missile7; CModel model_missile8; CModel model_flak1; CModel model_flarak1; CModel model_tent1; CModel model_ship1; CModel model_ship2; CModel model_gl117; CModel model_tank1; CModel model_container1; CModel model_truck1; CModel model_truck2; CModel model_trsam; CModel model_pickup1; CModel model_pickup2; CModel model_tank2; CModel model_tent4; CModel model_hall1; CModel model_hall2; CModel model_oilrig; CModel model_egg; CModel model_radar; CModel model_mine1; CModel model_aster1; CModel model_base1; CModel model_barrier1; CModel model_rubble1; CModel model_depot1; CModel model_house1; DynamicObj *flare [maxflare]; DynamicObj *chaff [maxchaff]; AIObj *missile [maxmissile]; DynamicObj *laser [maxlaser]; AIObj *fighter [maxfighter]; Star *star [maxstar]; DynamicObj *groundobj [maxgroundobj]; Flash *flash1; Space *space; AIObj *fplayer; CSpaceObj *sphere; CSphere *objsphere; HighClouds *highclouds; HighClouds *highclouds2; CModel *obj, *objlaser, *objmissile; CVector3 *clip1, *clip2, *tlnull, *tlinf, *tlminf; CRotation *rotnull, *rotmissile; GLenum polygonMode = GL_FILL; GLfloat light_position0[] = { 0.0, 0.5, -1.0, 0 }; #define max(x,y) ((x)>(y)?(x):(y)) int NX, NY; int joysticks; Mission *mission = NULL; Mission *missionnew = NULL; int keyb_elev = 0, keyb_roll = 0, keyb_rudder = 0; int keyb_lshift = 0; Container allmenus; Container famemenu; Container fightermenu; Container missionmenu; Container quitmenu; Container statsmenu; Component *currentsubmenu = NULL; Component *currentoptmenu = NULL; Container *mainmenu, *submenu [10], *optmenu [5], *controlsmenu [5]; Button *mainbutton [10]; Button *optbutton [10]; bool firststart = false; bool missionactive = false; CColor colorwhite (255, 255, 255, 255); CColor colorblue (50, 50, 255, 255); CColor colorgreen (100, 255, 100, 255); CColor colororange (255, 150, 100, 255); CColor colorred (255, 0, 0, 255); CColor coloryellow (255, 255, 0, 200); CColor colorgrey (150, 150, 150, 200); CColor colorlightgrey (210, 210, 210, 255); void drawRank (float xp, float yp, float zp, int rank, float zoom) { rank --; if (rank < 0) return; float x = xp / 10.0, y = yp / 10.0, z = zp; float tx1 = 0.5 * (rank % 2); float tx2 = tx1 + 0.5; float ty1 = 0.755 - 0.25 * (rank / 2); float ty2 = ty1 + 0.24; zoom /= 10; gl->enableTextures (texranks->textureID); if (antialiasing) gl->enableLinearTexture (texranks->textureID); else gl->disableLinearTexture (texranks->textureID); gl->enableAlphaBlending (); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.35); // Example how to pass the glBegin()...glEnd() code using vertex lists /* float vertex [sizeof (float) * 9]; glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer (3, GL_FLOAT, sizeof (float) * 9, &vertex [0]); glColorPointer (4, GL_FLOAT, sizeof (float) * 9, &vertex [3]); glTexCoordPointer (2, GL_FLOAT, sizeof (float) * 9, &vertex [7]); int mz = 0; vertex [mz ++] = x; vertex [mz ++] = y; vertex [mz ++] = z; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 200.0F/255.0F; vertex [mz ++] = tx1; vertex [mz ++] = ty1; vertex [mz ++] = x + zoom * 2; vertex [mz ++] = y; vertex [mz ++] = z; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 200.0F/255.0F; vertex [mz ++] = tx2; vertex [mz ++] = ty1; vertex [mz ++] = x + zoom * 2; vertex [mz ++] = y + zoom; vertex [mz ++] = z; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 200.0F/255.0F; vertex [mz ++] = tx2; vertex [mz ++] = ty2; vertex [mz ++] = x; vertex [mz ++] = y + zoom; vertex [mz ++] = z; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 1; vertex [mz ++] = 200.0F/255.0F; vertex [mz ++] = tx1; vertex [mz ++] = ty2; glDrawArrays (GL_QUADS, 0, 4);*/ glBegin (GL_QUADS); glColor4ub (255, 255, 255, 200); glTexCoord2f (tx1, ty1); glVertex3f (x, y, z); glTexCoord2f (tx2, ty1); glVertex3f (x + zoom * 2, y, z); glTexCoord2f (tx2, ty2); glVertex3f (x + zoom * 2, y + zoom, z); glTexCoord2f (tx1, ty2); glVertex3f (x, y + zoom, z); glEnd (); glDisable (GL_ALPHA_TEST); gl->disableAlphaBlending (); glDisable (GL_TEXTURE_2D); } void drawMedal (float xp, float yp, float zp, int medal, float zoom, int missionid) { if (medal < 0) return; if (missionid < MISSION_CAMPAIGN1 || missionid > MISSION_CAMPAIGN2) return; float x = xp / 10.0 - zoom / 20, y = yp / 10.0 - zoom / 20, z = zp; float tx1 = 0.5 * (medal % 2); float tx2 = tx1 + 0.5; float ty1 = 0.5 * (medal / 2); float ty2 = ty1 + 0.5; zoom /= 10; gl->enableTextures (texmedals->textureID); if (antialiasing) gl->enableLinearTexture (texmedals->textureID); else gl->disableLinearTexture (texmedals->textureID); gl->enableAlphaBlending (); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.1); glBegin (GL_QUADS); glColor4ub (255, 255, 255, 200); glTexCoord2f (tx1, ty1); glVertex3f (x, y, z); glTexCoord2f (tx2, ty1); glVertex3f (x + zoom, y, z); glTexCoord2f (tx2, ty2); glVertex3f (x + zoom, y + zoom, z); glTexCoord2f (tx1, ty2); glVertex3f (x, y + zoom, z); glEnd (); glDisable (GL_ALPHA_TEST); gl->disableAlphaBlending (); glDisable (GL_TEXTURE_2D); } void drawMouseCursor () { glPushMatrix (); glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); gluOrtho2D (0, width, 0, height); glScalef (1, -1, 1); glTranslatef (0, -height, 0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gl->enableAlphaBlending (); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.1); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); gl->enableTextures (texcross2->textureID); int crossradius = width / 35; glTranslatef (mousex, mousey, 0); glBegin (GL_QUADS); glColor4ub (255, 255, 255, 255); glTexCoord2i (0, 0); glVertex2d (-crossradius, -crossradius); glTexCoord2i (0, 1); glVertex2d (-crossradius, crossradius); glTexCoord2i (1, 1); glVertex2d (crossradius, crossradius); glTexCoord2i (1, 0); glVertex2d (crossradius, -crossradius); glEnd (); glDisable (GL_ALPHA_TEST); glDisable (GL_TEXTURE_2D); gl->disableAlphaBlending (); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); glPopMatrix (); glPopMatrix (); } int getMedal (int score) { if (score >= 350) return 1; else if (score >= 300) return 0; else if (score >= 250) return 3; else if (score >= 200) return 2; return -1; } void gl117_rotateColors (int inittimer_gl117) { int i; for (i = 0; i < model_gl117.numObjects; i ++) { for (int i2 = 0; i2 < model_gl117.object [i]->numVertices; i2 ++) { model_gl117.object [i]->vertex [i2].color.c [0] = (int) (75.0F * SIN(i2 * 100 + inittimer_gl117 / 2) + 155.0F); model_gl117.object [i]->vertex [i2].color.c [1] = model_gl117.object [i]->vertex [i2].color.c [0]; model_gl117.object [i]->vertex [i2].color.c [2] = 100; } } } void adjustBrightness () { // adjust brightness setting (blending) if (brightness < 0) { glColor4ub (0, 0, 0, -brightness); float xf = 2.0, yf = 1.5, zf = 1.0; glDisable (GL_DEPTH_TEST); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); glVertex3f (-xf, -yf, -zf); glVertex3f (-xf, yf, -zf); glVertex3f (xf, yf, -zf); glVertex3f (xf, -yf, -zf); glEnd (); glDisable (GL_BLEND); // glEnable (GL_DEPTH_TEST); } else if (brightness > 0) { glColor4ub (255, 255, 255, brightness); float xf = 2.0, yf = 1.5, zf = 1.0; glDisable (GL_DEPTH_TEST); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); glVertex3f (-xf, -yf, -zf); glVertex3f (-xf, yf, -zf); glVertex3f (xf, yf, -zf); glVertex3f (xf, -yf, -zf); glEnd (); glDisable (GL_BLEND); // glEnable (GL_DEPTH_TEST); } } #ifndef USE_GLUT SDL_Joystick *sdljoystick [maxjoysticks]; int sdljoystickaxes [maxjoysticks]; #endif int sdldisplay = true; int sdlreshape = true; Cockpit *cockpit; float fps = 30; int glutwindow; bool initing = true; int flash = 0; int lastshield = 0; int getTrainingIdFromValue (int n) { int z = 0; if (n == z ++) return MISSION_TUTORIAL; else if (n == z ++) return MISSION_TUTORIAL2; else if (n == z ++) return MISSION_DOGFIGHT; else if (n == z ++) return MISSION_TUTORIAL3; else if (n == z ++) return MISSION_FREEFLIGHT1; else if (n == z ++) return MISSION_DEATHMATCH1; else if (n == z ++) return MISSION_DEATHMATCH2; else if (n == z ++) return MISSION_DEATHMATCH3; else if (n == z ++) return MISSION_TEAMBASE1; else if (n == z ++) return MISSION_WAVES1; else { return MISSION_CUSTOM1 + n - 10; } return 0; } int getCampaignIdFromValue (int n) { int z = 0; if (n == z ++) return MISSION_TEST1; else if (n == z ++) return MISSION_TEST2; else if (n == z ++) return MISSION_TRANSPORT; else if (n == z ++) return MISSION_CONVOY; else if (n == z ++) return MISSION_DOGFIGHT2; else if (n == z ++) return MISSION_AIRBATTLE; else if (n == z ++) return MISSION_SADEFENSE; else if (n == z ++) return MISSION_SCOUT; else if (n == z ++) return MISSION_BASE; else if (n == z ++) return MISSION_DEPOT; else if (n == z ++) return MISSION_DEFEND1; else if (n == z ++) return MISSION_DOGFIGHT3; else if (n == z ++) return MISSION_TANK1; else if (n == z ++) return MISSION_CONVOY2; else if (n == z ++) return MISSION_SHIP1; else if (n == z ++) return MISSION_SHIP2; else if (n == z ++) return MISSION_SHIP3; else if (n == z ++) return MISSION_CANYON1; else if (n == z ++) return MISSION_CANYON2; else if (n == z ++) return MISSION_TUNNEL1; else if (n == z ++) return MISSION_CANYON3; else if (n == z ++) return MISSION_MOON1; else if (n == z ++) return MISSION_MOONBATTLE; else if (n == z ++) return MISSION_MOON2; else if (n == z ++) return MISSION_MOON3; return 0; } int getCampaignValueFromId (int n) { int z = 0; if (n == MISSION_TEST1) z = 0; else if (n == MISSION_TEST2) z = 1; else if (n == MISSION_TRANSPORT) z = 2; else if (n == MISSION_CONVOY) z = 3; else if (n == MISSION_DOGFIGHT2) z = 4; else if (n == MISSION_AIRBATTLE) z = 5; else if (n == MISSION_SADEFENSE) z = 6; else if (n == MISSION_SCOUT) z = 7; else if (n == MISSION_BASE) z = 8; else if (n == MISSION_DEPOT) z = 9; else if (n == MISSION_DEFEND1) z = 10; else if (n == MISSION_DOGFIGHT3) z = 11; else if (n == MISSION_TANK1) z = 12; else if (n == MISSION_CONVOY2) z = 13; else if (n == MISSION_SHIP1) z = 14; else if (n == MISSION_SHIP2) z = 15; else if (n == MISSION_SHIP3) z = 16; else if (n == MISSION_CANYON1) z = 17; else if (n == MISSION_CANYON2) z = 18; else if (n == MISSION_TUNNEL1) z = 19; else if (n == MISSION_CANYON3) z = 20; else if (n == MISSION_MOON1) z = 21; else if (n == MISSION_MOONBATTLE) z = 22; else if (n == MISSION_MOON2) z = 23; else if (n == MISSION_MOON3) z = 24; return z; } void setPlaneVolume () { if (game == GAME_PLAY) { int lev = (int) ((float) 128 * fplayer->thrust / fplayer->maxthrust) - 32; sound->stop (SOUND_PLANE1); sound->engine = (int) (fplayer->thrust / fplayer->maxthrust * 20) - 10; sound->setVolume (SOUND_PLANE1, lev); sound->playLoop (SOUND_PLANE1); } else { sound->setVolume (SOUND_PLANE1, 0); } } void setLightSource (int gamma) { light_position0 [0] = -cosi [gamma]; light_position0 [1] = sine [gamma]; light_position0 [2] = 0; glLightfv (GL_LIGHT0, GL_POSITION, light_position0); } CModel *getModel (int id) { if (id == FIGHTER_FALCON) return &model_fig; else if (id == FIGHTER_SWALLOW) return &model_figa; else if (id == FIGHTER_HAWK) return &model_figb; else if (id == FIGHTER_HAWK2) return &model_figc; else if (id == FIGHTER_BUZZARD) return &model_figd; else if (id == FIGHTER_CROW) return &model_fige; else if (id == FIGHTER_PHOENIX) return &model_figf; else if (id == FIGHTER_REDARROW) return &model_figg; else if (id == FIGHTER_BLACKBIRD) return &model_figh; else if (id == FIGHTER_STORM) return &model_figi; else if (id == FIGHTER_TRANSPORT) return &model_figt; else if (id == FIGHTER_TRANSPORT2) return &model_figu; else if (id == MISSILE_AIR1) return &model_missile1; else if (id == MISSILE_AIR2) return &model_missile2; else if (id == MISSILE_AIR3) return &model_missile3; else if (id == MISSILE_GROUND1) return &model_missile4; else if (id == MISSILE_GROUND2) return &model_missile5; else if (id == MISSILE_DF1) return &model_missile6; else if (id == MISSILE_FF1) return &model_missile7; else if (id == MISSILE_FF2) return &model_missile8; else if (id == TANK_AIR1) return &model_tank1; else if (id == TANK_GROUND1) return &model_tank2; else if (id == TANK_TRSAM1) return &model_trsam; else if (id == TANK_PICKUP1) return &model_pickup1; else if (id == TANK_TRUCK1) return &model_truck1; else if (id == TANK_TRUCK2) return &model_truck2; else if (id == SHIP_CRUISER) return &model_ship1; else if (id == SHIP_DESTROYER1) return &model_ship2; else if (id == FLAK_AIR1) return &model_flak1; else if (id == FLARAK_AIR1) return &model_flarak1; else if (id == STATIC_TENT1) return &model_tent1; else if (id == STATIC_TENT4) return &model_tent4; else if (id == STATIC_CONTAINER1) return &model_container1; else if (id == STATIC_HALL1) return &model_hall1; else if (id == STATIC_HALL2) return &model_hall2; else if (id == STATIC_OILRIG1) return &model_oilrig; else if (id == STATIC_COMPLEX1) return &model_egg; else if (id == STATIC_RADAR1) return &model_radar; else if (id == STATIC_BASE1) return &model_base1; else if (id == STATIC_DEPOT1) return &model_depot1; else if (id == STATIC_BARRIER1) return &model_barrier1; else if (id == ASTEROID) return &model_aster1; return &model_fig; } int game_levelInit () { int i, i2; // init all objects for (i = 0; i < maxfighter; i ++) { fighter [i]->dinit (); fighter [i]->aiinit (); // fighter [i]->fighterinit (); fighter [i]->explode = 0; fighter [i]->tl->x = 0; fighter [i]->tl->z = -i * 10; fighter [i]->party = 0; fighter [i]->zoom = 0.35; fighter [i]->deactivate (); fighter [i]->recheight = 15; fighter [i]->recthrust = 0.2; fighter [i]->rectheta = 0; fighter [i]->o = &model_fig; } for (i = 0; i < maxgroundobj; i ++) { groundobj [i]->dinit (); groundobj [i]->zoom = 1; groundobj [i]->id = STATIC_PASSIVE; groundobj [i]->deactivate (); } // if (l != NULL) delete l; if (!multiplayer || isserver || !isserver) // clients do not need the mission { Mission *missionold = mission; mission = missionnew; missionnew = NULL; mission->difficulty = difficulty; mission->start (); if (mission->id >= MISSION_CUSTOM1 && mission->id <= MISSION_CUSTOM2) { if (((MissionCustom *) mission)->reterror) { display ("Could not startup mission", LOG_ERROR); delete mission; mission = missionold; return 0; } } if (missionold != NULL) { delete missionold; missionold = NULL; } } initing = true; flash = 0; if (clouds == 0) highclouds->setTexture (NULL); else if (clouds == 1) highclouds->setTexture (texclouds1); else if (clouds == 2) highclouds->setTexture (texclouds2); else if (clouds == 3) highclouds->setTexture (texclouds3); if (clouds == 0) highclouds2->setTexture (NULL); else if (clouds == 1) highclouds2->setTexture (texclouds2); else if (clouds == 2) highclouds2->setTexture (NULL); else if (clouds == 3) highclouds2->setTexture (NULL); // place missiles to racks for (i = 0; i < maxfighter; i ++) { if (fighter [i]->id >= FIGHTER1 && fighter [i]->id <= FIGHTER2) for (i2 = 0; i2 < 4; i2 ++) { int type = fighter [i]->missilerack [i2]; CModel *rm = getModel (MISSILE1 + type); fighter [i]->refmodel [i2 * 3] = rm; fighter [i]->refmodel [i2 * 3 + 1] = rm; fighter [i]->refmodel [i2 * 3 + 2] = rm; fighter [i]->reftl [i2 * 3 + 1].z = fighter [i]->reftl [i2 * 3].z - 0.04; fighter [i]->reftl [i2 * 3 + 2].z = fighter [i]->reftl [i2 * 3].z + 0.04; fighter [i]->reftl [i2 * 3].y = fighter [i]->reftl [i2 * 3 + 1].y - 0.04; int tmp = fighter [i]->missilerackn [i2]; fighter [i]->refscale [i2 * 3] = 0.25; fighter [i]->refscale [i2 * 3 + 1] = 0.25; fighter [i]->refscale [i2 * 3 + 2] = 0.25; if (tmp < 3) fighter [i]->refscale [i2 * 3] = 0; if (tmp < 2) fighter [i]->refscale [i2 * 3 + 1] = 0; } } // initialize object's height over the surface for (i = 0; i < maxfighter; i ++) { if (fighter [i]->id >= FLAK1 && fighter [i]->id <= FLAK2) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom; } else if (fighter [i]->id == SHIP_DESTROYER1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom / 4; } else if (fighter [i]->id == SHIP_CRUISER) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom / 4; } else if (fighter [i]->id >= TANK1 && fighter [i]->id <= TANK2) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom * 0.55; } else if (fighter [i]->id == STATIC_TENT1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z); } else if (fighter [i]->id == STATIC_CONTAINER1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom / 2; } else if (fighter [i]->id == STATIC_HALL1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom / 3; } else if (fighter [i]->id == STATIC_HALL2) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom / 3; } else if (fighter [i]->id == STATIC_TENT4) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom / 3; } else if (fighter [i]->id == STATIC_OILRIG1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + fighter [i]->zoom / 5; } else if (fighter [i]->id == STATIC_COMPLEX1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + 0.55 * fighter [i]->zoom; } else if (fighter [i]->id == STATIC_RADAR1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + 0.7 * fighter [i]->zoom; } else if (fighter [i]->id == STATIC_BASE1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + 0.5 * fighter [i]->zoom; } else if (fighter [i]->id == STATIC_DEPOT1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + 0.5 * fighter [i]->zoom; } else if (fighter [i]->id == STATIC_BARRIER1) { fighter [i]->tl->y = l->getExactHeight (fighter [i]->tl->x, fighter [i]->tl->z) + 0.3 * fighter [i]->zoom; } else if (fighter [i]->id == MISSILE_MINE1) { fighter [i]->tl->y = l->getHeight (fighter [i]->tl->x, fighter [i]->tl->z) + 5 + myrandom (20); } else if (fighter [i]->id == ASTEROID) { ; } else { fighter [i]->tl->y = l->getHeight (fighter [i]->tl->x, fighter [i]->tl->z) + 20; } } for (i = 0; i < maxlaser; i ++) { laser [i]->deactivate (); if (day) { laser [i]->o = &model_cannon1; laser [i]->zoom = 0.08; laser [i]->drawlight = false; } else { laser [i]->o = &model_cannon2; laser [i]->zoom = 0.1; } } for (i = 0; i < maxmissile; i ++) { missile [i]->aiinit (); missile [i]->deactivate (); } for (i = 0; i < maxflare; i ++) { flare [i]->dinit (); flare [i]->deactivate (); } for (i = 0; i < maxchaff; i ++) { chaff [i]->dinit (); chaff [i]->deactivate (); } for (i = 0; i < maxstar; i ++) { star [i]->phi = myrandom (360); star [i]->gamma = myrandom (85); star [i]->size = 0.6 + 0.15 * myrandom (8); } CColor skycolor; if (day && weather == WEATHER_SUNNY) { if (sungamma < 35) { skycolor.setColor ((unsigned short) (127 + 70 - 2 * sungamma), 127, 127); objsphere->setColor (&skycolor); } else { skycolor.setColor (127, 127, 127 + 5); objsphere->setColor (&skycolor); } if (sungamma < 35) { gl->fogcolor [0] = (float) (127 + 70 - 2 * sungamma) / 256.0; gl->fogcolor [1] = 0.5; gl->fogcolor [2] = 0.5; } else { gl->fogcolor [0] = 0.5; gl->fogcolor [1] = 0.5; gl->fogcolor [2] = 0.52; } skycolor.setColor (50, 200, 255); objsphere->setNorthPoleColor (&skycolor, 1.8); if (sungamma < 35) { skycolor.setColor ((unsigned short) (180 + 70 - 2 * sungamma), 180, 180); objsphere->setPoleColor (270, (int) (90 - sungamma), &skycolor, 0.3); } else { skycolor.setColor (200, 200, 200); objsphere->setPoleColor (270, (int) (90 - sungamma), &skycolor, 0.3); } } else if (!day && weather == WEATHER_SUNNY) { skycolor.setColor (64, 64, 64); objsphere->setColor (&skycolor); gl->fogcolor [0] = 0.25; gl->fogcolor [1] = 0.25; gl->fogcolor [2] = 0.25; if (l->type != LAND_MOON) { skycolor.setColor (0, 0, 170); objsphere->setNorthPoleColor (&skycolor, 1.8); skycolor.setColor (64, 64, 64); objsphere->setPoleColor (270, (int) (90 - sungamma), &skycolor, 0.3); } else { skycolor.setColor (0, 0, 0); objsphere->setNorthPoleColor (&skycolor, 1.8); } } else if (day && weather == WEATHER_THUNDERSTORM) { skycolor.setColor (102, 102, 102); objsphere->setColor (&skycolor); gl->fogcolor [0] = 0.4; gl->fogcolor [1] = 0.4; gl->fogcolor [2] = 0.4; skycolor.setColor (102, 102, 102); objsphere->setNorthPoleColor (&skycolor, 1.8); } else if (!day && weather == WEATHER_THUNDERSTORM) { skycolor.setColor (40, 40, 40); objsphere->setColor (&skycolor); gl->fogcolor [0] = 0.16; gl->fogcolor [1] = 0.16; gl->fogcolor [2] = 0.16; skycolor.setColor (40, 40, 40); objsphere->setNorthPoleColor (&skycolor, 1.8); } else if (weather == WEATHER_CLOUDY) { skycolor.setColor (20, 20, 20); objsphere->setColor (&skycolor); gl->fogcolor [0] = 0.08; gl->fogcolor [1] = 0.08; gl->fogcolor [2] = 0.08; } glDeleteLists (objsphere->list1, 1); glDeleteLists (objsphere->list2, 1); glDeleteLists (objsphere->list3, 1); objsphere->list1 = -1; objsphere->list2 = -1; objsphere->list3 = -1; // glLightfv( GL_LIGHT0, GL_AMBIENT, light_ambient ); /* float light_specular [3] = {0.5, 0.5, 0.5}; glLightfv( GL_LIGHT0, GL_SPECULAR, light_specular );*/ setLightSource ((int) sungamma); glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); // glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); glEnable (GL_LIGHT0); // Turn on a light with defaults set float light_ambient [4] = {0.2, 0.2, 0.2, 1.0}; float light_diffuse [4] = {1.0, 1.0, 1.0, 1.0}; float light_specular [4] = {1.0, 1.0, 1.0, 1.0}; glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); glEnable (GL_LIGHTING); // Turn on lighting glEnable (GL_COLOR_MATERIAL); // Allow color glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); // glDisable (GL_DITHER); fplayer->missiletype = fplayer->firstMissile (); initing = false; lastshield = (int) fplayer->shield; fps = 30; redout = 0; blackout = 0; if (!fplayer->ai) fplayer->realism = physics; /*#ifdef HAVE_SDL_NET if (multiplayer) { if (threadnet != NULL) SDL_KillThread (threadnet); threadnet = SDL_CreateThread (net_thread_main, NULL); } #endif*/ return 1; } void game_reshape () { glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); float v = getView (); if (camera == 50) v = 100000.0; gluPerspective (visibleangle, (float) width / height, nearclippingplane * GLOBALSCALE, v * GLOBALSCALE); glPolygonMode (GL_FRONT_AND_BACK, polygonMode); #ifndef USE_GLUT /* if (controls == 1) SDL_ShowCursor (1); else*/ SDL_ShowCursor (0); #endif } void menu_reshape () { glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); float v = getView (); if (camera == 50) v = 100000.0; gluPerspective (visibleangle, 1.0, nearclippingplane * GLOBALSCALE, v * GLOBALSCALE); glPolygonMode (GL_FRONT_AND_BACK, polygonMode); #ifndef USE_GLUT SDL_ShowCursor (0); #endif } void credits_reshape () { glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); float v = getView (); if (camera == 50) v = 100000.0; gluPerspective (visibleangle, 1.0, nearclippingplane * GLOBALSCALE, v * GLOBALSCALE); glPolygonMode (GL_FRONT_AND_BACK, polygonMode); #ifndef USE_GLUT SDL_ShowCursor (0); #endif } void stats_reshape () { glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); float v = getView (); if (camera == 50) v = 100000.0; gluPerspective (visibleangle, 1.0, nearclippingplane * GLOBALSCALE, v * GLOBALSCALE); glPolygonMode (GL_FRONT_AND_BACK, polygonMode); #ifndef USE_GLUT SDL_ShowCursor (0); #endif } void playRandomMusic () { int r = myrandom (6); if (r == 0) sound->loadMusic (MUSIC_DARK1); else if (r == 1) sound->loadMusic (MUSIC_STANDBY1); else if (r == 2) sound->loadMusic (MUSIC_ELECTRO1); else if (r == 3) sound->loadMusic (MUSIC_STARS1); else if (r == 4) sound->loadMusic (MUSIC_SOFTTEC1); else sound->loadMusic (MUSIC_AMBIENT1); sound->playMusic (1); #ifdef HAVE_SDL_MIXER Mix_HookMusicFinished (playRandomMusic); #endif } void switch_menu () { lasttime = 0; setLightSource ((int) sungamma); game = GAME_MENU; menu_reshape (); sound->stop (SOUND_PLANE1); if (!sound->musicplaying) playRandomMusic (); allmenus.visible = true; allmenus.components [0]->setVisible (true); if (currentsubmenu) { currentsubmenu->setVisible (true); } if (missionactive) mainbutton [6]->setVisible (true); else mainbutton [6]->setVisible (false); #ifdef HAVE_SDL SDL_WM_GrabInput (SDL_GRAB_OFF); #endif } bool ispromoted; int statsitemselected = 0; void switch_stats () { lasttime = 0; setLightSource ((int) sungamma); game = GAME_STATS; statsitemselected = 0; int lastrank = pilots->pilot [pilots->aktpilot]->ranking; (void) pilots->pilot [pilots->aktpilot]->getRank (); ispromoted = false; if (lastrank < pilots->pilot [pilots->aktpilot]->ranking) ispromoted = true; stats_reshape (); sound->stop (SOUND_PLANE1); if (!sound->musicplaying) { int missionstate = mission->processtimer (1); if (missionstate == 1) sound->loadMusic (MUSIC_WINNER1); else sound->loadMusic (MUSIC_LOSER1); sound->playMusic (); } } void createMission (int missionid) { if (missionid >= MISSION_MULTIPLAYER) { multiplayer = true; } else { multiplayer = false; isserver = false; } if (missionnew != NULL) delete missionnew; if (missionid == MISSION_DEMO) missionnew = new MissionDemo1 (); else if (missionid == MISSION_TEST1) missionnew = new MissionTest1 (); else if (missionid == MISSION_TEST2) missionnew = new MissionTest2 (); else if (missionid == MISSION_TRANSPORT) missionnew = new MissionTransport (); else if (missionid == MISSION_CONVOY) missionnew = new MissionConvoy (); else if (missionid == MISSION_DOGFIGHT2) missionnew = new MissionDogfight2 (); else if (missionid == MISSION_AIRBATTLE) missionnew = new MissionAirBattle (); else if (missionid == MISSION_SADEFENSE) missionnew = new MissionGround1 (); else if (missionid == MISSION_SCOUT) missionnew = new MissionScout (); else if (missionid == MISSION_BASE) missionnew = new MissionBase (); else if (missionid == MISSION_DEPOT) missionnew = new MissionDepot (); else if (missionid == MISSION_DEFEND1) missionnew = new MissionDefend1 (); else if (missionid == MISSION_DOGFIGHT3) missionnew = new MissionDogfight3 (); else if (missionid == MISSION_TANK1) missionnew = new MissionTank1 (); else if (missionid == MISSION_CONVOY2) missionnew = new MissionConvoy2 (); else if (missionid == MISSION_SHIP1) missionnew = new MissionShip1 (); else if (missionid == MISSION_SHIP2) missionnew = new MissionShip2 (); else if (missionid == MISSION_SHIP3) missionnew = new MissionShip3 (); else if (missionid == MISSION_CANYON1) missionnew = new MissionCanyon1 (); else if (missionid == MISSION_CANYON2) missionnew = new MissionCanyon2 (); else if (missionid == MISSION_CANYON3) missionnew = new MissionCanyon3 (); else if (missionid == MISSION_TUNNEL1) missionnew = new MissionTunnel1 (); else if (missionid == MISSION_MOON1) missionnew = new MissionMoonDefense1 (); else if (missionid == MISSION_MOONBATTLE) missionnew = new MissionMoonBattle (); else if (missionid == MISSION_MOON2) missionnew = new MissionMoonDogfight1 (); else if (missionid == MISSION_MOON3) missionnew = new MissionMoonBase1 (); else if (missionid == MISSION_TUTORIAL) missionnew = new MissionTutorial1 (); else if (missionid == MISSION_TUTORIAL2) missionnew = new MissionTutorial2 (); else if (missionid == MISSION_DOGFIGHT) missionnew = new MissionDogfight1 (); else if (missionid == MISSION_TUTORIAL3) missionnew = new MissionTutorial3 (); else if (missionid == MISSION_FREEFLIGHT1) missionnew = new MissionFreeFlight1 (); else if (missionid == MISSION_DEATHMATCH1) missionnew = new MissionDeathmatch1 (); else if (missionid == MISSION_DEATHMATCH2) missionnew = new MissionDeathmatch2 (); else if (missionid == MISSION_DEATHMATCH3) missionnew = new MissionDeathmatch3 (); else if (missionid == MISSION_TEAMBASE1) missionnew = new MissionTeamBase1 (); else if (missionid == MISSION_WAVES1) missionnew = new MissionWaves1 (); else if (missionid == MISSION_MULTIPLAYER_DOGFIGHT) missionnew = new MissionMultiDogfight1 (); else if (missionid >= MISSION_CUSTOM1 && missionid <= MISSION_CUSTOM2) { missionnew = new MissionCustom (); missionnew->id = missionid; ((MissionCustom *) missionnew)->init (); } if (mission != NULL) { if (mission->id == missionnew->id) { missionnew->wantfighter = mission->wantfighter; missionnew->wantweapon = mission->wantweapon; } } } void switch_mission (int missionid) { lasttime = 0; setLightSource (60); game = GAME_MISSION; createMission (missionid); if (missionid >= MISSION_CUSTOM1 && missionid <= MISSION_CUSTOM2) { if (((MissionCustom *) missionnew)->reterror) { display ("Could not init mission", LOG_ERROR); // play error sound switch_menu (); return; } } menu_reshape (); sound->stop (SOUND_PLANE1); if (!sound->musicplaying) playRandomMusic (); } void switch_fame () { lasttime = 0; setLightSource (60); game = GAME_FAME; menu_reshape (); sound->stop (SOUND_PLANE1); if (!sound->musicplaying) playRandomMusic (); } void switch_fighter () { lasttime = 0; setLightSource (60); game = GAME_FIGHTER; menu_reshape (); sound->stop (SOUND_PLANE1); if (!sound->musicplaying) playRandomMusic (); } void switch_create () { lasttime = 0; setLightSource (60); game = GAME_CREATE; isserver = true; if (server != NULL) delete server; server = new Server (); menu_reshape (); sound->stop (SOUND_PLANE1); if (!sound->musicplaying) playRandomMusic (); } void switch_join () { lasttime = 0; setLightSource (60); game = GAME_JOIN; isserver = false; if (client != NULL) delete client; client = new Client (); menu_reshape (); sound->stop (SOUND_PLANE1); if (!sound->musicplaying) playRandomMusic (); } int creditstimer, finishtimer; void switch_credits () { lasttime = 0; game = GAME_CREDITS; creditstimer = 50 * timestep; credits_reshape (); sound->stop (SOUND_PLANE1); sound->stop (SOUND_CANNON1); } void switch_finish () { lasttime = 0; game = GAME_FINISH; creditstimer = 50 * timestep; credits_reshape (); if (sound->musicplaying) sound->haltMusic (); sound->loadMusic (MUSIC_ELECTRO1); sound->playMusic (); sound->stop (SOUND_PLANE1); sound->stop (SOUND_CANNON1); } void switch_quit () { lasttime = 0; game = GAME_QUIT; save_saveconfig (); // this configuration seems to work => save it } void switch_game () { lasttime = 0; setLightSource ((int) sungamma); game = GAME_PLAY; game_reshape (); if (sound->musicplaying) sound->haltMusic (); sound->playLoop (SOUND_PLANE1); setPlaneVolume (); #ifdef HAVE_SDL SDL_WM_GrabInput (SDL_GRAB_ON); #endif } bool startcannon = false; void event_setAntialiasing () { if (antialiasing) { gl->enableLinearTexture (font1->texture->textureID); gl->enableLinearTexture (font2->texture->textureID); if (texmoon != NULL) { gl->enableLinearTexture (texmoon->textureID); gl->enableLinearTexture (texsun->textureID); gl->enableLinearTexture (texearth->textureID); } } else { gl->disableLinearTexture (font1->texture->textureID); gl->disableLinearTexture (font2->texture->textureID); if (texmoon != NULL) { gl->disableLinearTexture (texmoon->textureID); gl->disableLinearTexture (texsun->textureID); gl->disableLinearTexture (texearth->textureID); } } } void event_fireCannon () { if (!fplayer->active) return; if (fplayer->firecannonttl > 0) return; if (fplayer->ammo == 0) return; #ifdef USE_GLUT fplayer->fireCannon (laser); #else fplayer->autofire = true; #endif } void event_stopCannon () { fplayer->autofire = false; } void event_fireMissile () { if (!fplayer->active) return; if (fplayer->firemissilettl > 0) return; if (fplayer->fireMissile (fplayer->missiletype + MISSILE1, missile)) sound->play (SOUND_MISSILE1, false); } void event_fireChaff () { if (!fplayer->active) return; if (fplayer->firechaffttl > 0) return; if (fplayer->fireChaff (chaff, missile)) sound->play (SOUND_CHAFF1, false); } void event_fireFlare () { if (!fplayer->active) return; if (fplayer->fireflarettl > 0) return; if (fplayer->fireFlare (flare, missile)) sound->play (SOUND_CHAFF1, false); } void event_selectMissile () { if (!fplayer->active) return; fplayer->missiletype = fplayer->nextMissile (fplayer->missiletype); } void event_targetNearest () { if (!fplayer->active) return; fplayer->targetNearestEnemy ((AIObj **) fighter); sound->play (SOUND_CLICK1, false); } void event_targetNext () { if (!fplayer->active) return; fplayer->targetNext ((AIObj **) fighter); sound->play (SOUND_CLICK1, false); } void event_targetPrevious () { if (!fplayer->active) return; fplayer->targetPrevious ((AIObj **) fighter); sound->play (SOUND_CLICK1, false); } void event_targetLocking () { if (!fplayer->active) return; fplayer->targetLockingEnemy ((AIObj **) fighter); sound->play (SOUND_CLICK1, false); } void event_thrustUp () { if (!fplayer->active) return; fplayer->thrustUp (); fplayer->thrustUp (); } void event_thrustDown () { if (!fplayer->active) return; fplayer->thrustDown (); fplayer->thrustDown (); } void game_key (int key, int x, int y) { unsigned int hikey = key; unsigned int lokey = key; if (camera == 50 && game == GAME_PAUSE) { camera = 0; game = GAME_PLAY; return; } else if (key == 27) { switch_menu (); } else if (hikey == key_firemissile || lokey == key_firemissile) { event_fireMissile (); } else if (hikey == key_dropflare || lokey == key_dropflare) { event_fireFlare (); } else if (hikey == key_dropchaff || lokey == key_dropchaff) { event_fireChaff (); } else if (hikey == key_firecannon || lokey == key_firecannon) { event_fireCannon (); } else if (hikey == key_selectmissile || lokey == key_selectmissile) { event_selectMissile (); } else if (hikey == key_thrustup || lokey == key_thrustup) { event_thrustUp (); } else if (hikey == key_thrustdown || lokey == key_thrustdown) { event_thrustDown (); } else if (key >= '1' && key <= '9') { fplayer->recthrust = fplayer->maxthrust * (1.0 / 18.0 * (key - '0') + 0.5); sound->play (SOUND_CLICK1, false); } else if (hikey == key_targetnearest || lokey == key_targetnearest) { event_targetNearest (); } else if (hikey == key_targetnext || lokey == key_targetnext) { event_targetNext (); } else if (hikey == key_targetprevious || lokey == key_targetprevious) { event_targetPrevious (); } else if (hikey == key_targetlocking || lokey == key_targetlocking) { event_targetLocking (); } /* else if (key == 'K') { if (fplayer->target != NULL) fplayer->target->shield = -1; } else if (key == 'V') { visibleangle += 10.0; if (visibleangle > 120.0) visibleangle = 50.0; }*/ else if (hikey == key_firecannon || lokey == key_firecannon) { fplayer->autofire = false; } switch (key - 256) // standard special keys { case KEY_LSHIFT: keyb_lshift = 1; break; case KEY_UP: keyb_elev = -1; break; case KEY_DOWN: keyb_elev = 1; break; case KEY_LEFT: if (keyb_lshift) keyb_rudder = -1; else keyb_roll = 1; break; case KEY_RIGHT: if (keyb_lshift) keyb_rudder = 1; else keyb_roll = -1; break; case KEY_F1: camera = 0; game_reshape (); break; case KEY_F2: camera = 1; game_reshape (); break; case KEY_F3: camera = 2; game_reshape (); break; case KEY_F4: camera = 6; game_reshape (); break; case KEY_F5: camera = 7; game_reshape (); break; case KEY_F6: camera = 9; game_reshape (); break; case KEY_F7: camera = 8; game_reshape (); break; case KEY_F8: camera = 5; game_reshape (); break; default: return; } #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } void game_keyup (int key, int x, int y) { unsigned int hikey = (unsigned int) key; unsigned int lokey = (unsigned int) key; if (hikey == key_firecannon || lokey == key_firecannon) { event_stopCannon (); } switch (key - 256) // standard special keys { case KEY_LSHIFT: keyb_lshift = 0; break; case KEY_UP: keyb_elev = 0; break; case KEY_DOWN: keyb_elev = 0; break; case KEY_LEFT: keyb_roll = 0; keyb_rudder = 0; break; case KEY_RIGHT: keyb_roll = 0; keyb_rudder = 0; break; case KEY_LALT: keyb_rudder = 0; break; case KEY_LCTRL: keyb_rudder = 0; break; } #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } int aktcam = 0; void game_mouse (int button, int state, int x, int y) { if (state == MOUSE_DOWN && fplayer->active) { if (button == mouse_firecannon) { fplayer->autofire = !fplayer->autofire; } else if (button == mouse_firemissile) { event_fireMissile (); } else if (button == mouse_selectmissile) { event_selectMissile (); } } } float dtheta = 0, dgamma = 0; int lastmousex = 0; int lastmx = 0, lastmy = 0; void game_mouserelmotion (int xrel, int yrel) { if (controls != CONTROLS_MOUSE || !mouse_relative) return; float xr = (float) xrel / width, yr = (float) yrel / height; float roll = (float) -xr * 20; if (roll > 1.0F) roll = 1.0F; else if (roll < -1.0F) roll = -1.0F; fplayer->rolleffect = roll; if (roll < 1E-3) fplayer->ruddereffect = (float) xr * 200; else fplayer->ruddereffect = 0.0f; if (fplayer->ruddereffect > 1.0) fplayer->ruddereffect = 1.0; else if (fplayer->ruddereffect < -1.0) fplayer->ruddereffect = -1.0; fplayer->elevatoreffect = (float) yr * fabs (yr) * 20000; if (!mouse_reverse) fplayer->elevatoreffect *= -1; if (fplayer->elevatoreffect > 1.0f) fplayer->elevatoreffect = 1.0f; else if (fplayer->elevatoreffect < -0.5f) fplayer->elevatoreffect = -0.5f; } void game_mousemotion (int x, int y) { if (controls != CONTROLS_MOUSE || mouse_relative) return; float mx = width / 2, my = height / 2; float dx = x - mx, dy = my - y; dx *= mouse_sensitivity / 70.0F; dy *= mouse_sensitivity / 70.0F; if (mouse_reverse) dy *= -1; // mouse interface code added by Lourens Veen float nx = dx / width; // normalised x-coordinate, -1 at lefthand // side of the screen, 1 at righthand side if (mouse_autorudder) { if (fabs(nx) < (1.0f/3.0f)) if (nx < 0.0f) fplayer->ruddereffect = 729.0f*nx*(nx+1.0f/3.0f)*(nx+1.0f/3.0f)/4.0f; else fplayer->ruddereffect = 729.0f*nx*(nx-1.0f/3.0f)*(nx-1.0f/3.0f)/4.0f; else fplayer->ruddereffect = 0.0f; } else { fplayer->ruddereffect = 0; } const float roll_deadarea = (float) mouse_autorudder / 1000.0F; //(1.0f/30.0f); if (fabs(nx) > roll_deadarea) { if (nx > 0.0f) nx -= roll_deadarea; else nx += roll_deadarea; if (nx > 0) fplayer->rolleffect = -(exp(log(nx) * 1.3f)) * 3.0f; else fplayer->rolleffect = (exp(log(-nx) * 1.3f)) * 3.0f; if (fplayer->rolleffect < -1.0F) fplayer->rolleffect = -1.0F; if (fplayer->rolleffect > 1.0F) fplayer->rolleffect = 1.0F; } else fplayer->rolleffect = 0.0f; fplayer->elevatoreffect = dy / height * 2.5; if (fplayer->elevatoreffect > 1.0f) fplayer->elevatoreffect = 1.0f; else if (fplayer->elevatoreffect < -0.5f) fplayer->elevatoreffect = -0.5f; #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } int jaxis [maxjaxis * maxjoysticks]; int getJoystickAxisIndex (int n) { int idx = (n / 1000) * 10 + (n % 1000); if (idx < 0) idx = 0; if (idx >= maxjaxis) idx = 0; return idx; } void game_joystickaxis (int x, int y, int rudder, int throttle) { if (fplayer->ai) return; float xx = x / 32768.0; xx *= fabs (xx); fplayer->rolleffect = (float) -xx; fplayer->elevatoreffect = (float) y / 30000; if (fplayer->elevatoreffect > 1.0) fplayer->elevatoreffect = 1.0; else if (fplayer->elevatoreffect < -1.0) fplayer->elevatoreffect = -1.0; if (fplayer->elevatoreffect < -0.5) fplayer->elevatoreffect = -0.5; fplayer->ruddereffect = (float) rudder / 30000; if (fplayer->ruddereffect > 1.0) fplayer->ruddereffect = 1.0; else if (fplayer->ruddereffect < -1.0) fplayer->ruddereffect = -1.0; fplayer->recthrust = fplayer->maxthrust * 0.75 - fplayer->maxthrust / 4 * throttle / 32638; } void game_joystickbutton (int button) { if (!fplayer->active) return; if (button == joystick_firecannon) { fplayer->fireCannon (laser); #ifdef HAVE_SDL_MIXER if (!startcannon) { sound->playLoop (SOUND_CANNON1); startcannon = true; } #else sound->play (SOUND_CANNON1, 1); #endif } if (button == joystick_firemissile) { event_fireMissile (); } if (button == joystick_dropflare) { event_fireFlare (); } if (button == joystick_dropchaff) { event_fireChaff (); } if (button == joystick_selectmissile) { event_selectMissile (); } if (button == joystick_targetnearest) { event_targetNearest (); } if (button == joystick_targetlocking) { event_targetLocking (); } if (button == joystick_targetnext) { event_targetNext (); } if (button == joystick_targetprevious) { event_targetPrevious (); } if (button == joystick_thrustup) { event_thrustUp (); } if (button == joystick_thrustdown) { event_thrustDown (); } } void game_joystickhat (int normhat) { #ifndef USE_GLUT game_joystickbutton (normhat); #endif } int frames = 0, time2 = 0, time1 = 0; void frame () { frames ++; #ifndef USE_GLUT time2 = SDL_GetTicks (); #else time2 = glutGet (GLUT_ELAPSED_TIME); #endif if (time2 - time1 > 1000) { if (time2 - time1 < 1500) fps = (float) frames * 1000.0 / (time2 - time1); time1 = time2; frames = 0; } } void game_view () { frame (); #ifdef USE_GLUT glutSwapBuffers(); #else SDL_GL_SwapBuffers (); #endif } int missionending = 0; int missionstate = 0; int menuitem = 0, menutimer = 0, menuitemselected = -1, missionmenutimer; int missionmenuitemselected = 0, missionmenufighterselected = -1, missionmenuweaponselected = -1; void drawCircles (CColor *colorstd) { int i; float zf = -3, yf, xf; int t = 360 - (missionmenutimer * 10 / timestep) % 360; for (i = 0; i < 20; i ++) { yf = -3 + 0.3 * i; // - (float) (missionmenutimer & 63) / 64.0; glBegin (GL_QUAD_STRIP); for (int i2 = 0; i2 < 20; i2 ++) { xf = -3 + 0.3 * i2; yf = -3 + 0.3 * i; float cola = sine [(int) (sqrt (xf * xf + yf * yf) * 200 + t) % 360] / 10 + 0.2; if (colorstd == &colorblue) glColor3f (0, 0, cola); else glColor3f (cola, 0, 0); glVertex3f (xf, yf, zf); yf = -3 + 0.3 * (i + 1); cola = sine [(int) (sqrt (xf * xf + yf * yf) * 200 + t) % 360] / 10 + 0.2; if (colorstd == &colorblue) glColor3f (0, 0, cola); else glColor3f (cola, 0, 0); glVertex3f (xf, yf, zf); } glEnd (); } } void drawQuads (CColor *colorstd) { int i; float zf = -3, yf; for (i = 0; i < 14; i ++) { yf = -3 + 0.5 * i - (float) (missionmenutimer / timestep & 63) / 64.0; glBegin (GL_QUAD_STRIP); for (int i2 = 0; i2 < 14; i2 ++) { float cola = sine [(i * 100+missionmenutimer*4 / timestep) % 360] / 10 + sine [(i2 * 100) % 360] / 10 + 0.2; if (colorstd == &colorblue) glColor3f (0, 0, cola); else glColor3f (cola, 0, 0); glVertex3f (-3 + 0.5 * i2, -3 + 0.5 * i, zf + sine [(i * 100) % 360] / 2); cola = sine [((i+1) * 100+missionmenutimer*4 / timestep) % 360] / 10 + sine [(i2 * 100) % 360] / 10 + 0.2; if (colorstd == &colorblue) glColor3f (0, 0, cola); else glColor3f (cola, 0, 0); glVertex3f (-3 + 0.5 * i2, -2.5 + 0.5 * i, zf + sine [((i+1) * 100) % 360] / 2); } glEnd (); } } void drawPlasma (CColor *colorstd) { int i; float yf; float zf1 = -2.98; float yind = 200.0 * sin (0.003 * missionmenutimer / timestep) + 200.0; float xind = 200.0 * cos (0.003 * missionmenutimer / timestep) + 200.0; float yind2 = -200.0 * sin (0.003 * missionmenutimer / timestep) + 200.0; float xind2 = -200.0 * cos (0.003 * missionmenutimer / timestep) + 200.0; for (i = 0; i < 21; i ++) { yf = -2.5 + 0.25 * i; float yif = yind + i * 5; int yi = (int) yif; float yr = yif - yi; float yif2 = yind2 + i * 5; int yi2 = (int) yif2; float yr2 = yif2 - yi2; glBegin (GL_QUAD_STRIP); for (int i2 = 0; i2 < 21; i2 ++) { float xf = -2.5 + 0.25 * i2; float xif = xind + i2 * 5; int xi = (int) xif; float xr = xif - xi; float xif2 = xind2 + i2 * 5; int xi2 = (int) xif2; float xr2 = xif2 - xi2; float h1 = xr * yr * l->h [yi + 1] [xi + 1] + (1.0 - xr) * (1.0 - yr) * l->h [yi] [xi] + xr * (1.0 - yr) * l->h [yi] [xi + 1] + (1.0 - xr) * yr * l->h [yi + 1] [xi]; float h2 = xr * yr * l->h [yi + 1 + 5] [xi + 1] + (1.0 - xr) * (1.0 - yr) * l->h [yi + 5] [xi] + xr * (1.0 - yr) * l->h [yi + 5] [xi + 1] + (1.0 - xr) * yr * l->h [yi + 1 + 5] [xi]; float h3 = xr2 * yr2 * l->h [yi2 + 1] [xi2 + 1] + (1.0 - xr2) * (1.0 - yr2) * l->h [yi2] [xi2] + xr2 * (1.0 - yr2) * l->h [yi2] [xi2 + 1] + (1.0 - xr2) * yr2 * l->h [yi2 + 1] [xi2]; float h4 = xr2 * yr2 * l->h [yi2 + 1 + 5] [xi2 + 1] + (1.0 - xr2) * (1.0 - yr2) * l->h [yi2 + 5] [xi2] + xr2 * (1.0 - yr2) * l->h [yi2 + 5] [xi2 + 1] + (1.0 - xr2) * yr2 * l->h [yi2 + 1 + 5] [xi2]; float intens = sin (0.15 * (h1 / 256 + 0.5 * missionmenutimer / timestep)) * 0.14 + 0.14; float intens2 = sin (0.15 * (h3 / 256 + 0.5 * missionmenutimer / timestep)) * 0.06 + 0.06; if (colorstd == &colorblue) glColor3f (intens2, 0, intens); else glColor3f (intens, 0, intens2); glVertex3f (xf, yf, zf1); intens = sin (0.15 * (h2 / 256 + 0.5 * missionmenutimer / timestep)) * 0.16 + 0.16; intens2 = sin (0.15 * (h4 / 256 + 0.5 * missionmenutimer / timestep)) * 0.08 + 0.08; if (colorstd == &colorblue) glColor3f (intens2, 0, intens); else glColor3f (intens, 0, intens2); glVertex3f (xf, yf + 0.25, zf1); } glEnd (); } } void menu_key (unsigned char key, int x, int y) { if (key == 27) { if (missionactive) { switch_game (); } else { switch_quit (); } } } void pleaseWait () { float xf = 1.0, yf = 0.2, zf = -2.5; int c1 = 100, c2 = 10, c3 = 180; glBegin (GL_QUADS); glColor4ub (c2, c2, c2, 255); glVertex3f (-xf, -yf, zf); glColor4ub (c1, c1, c1, 255); glVertex3f (xf, -yf, zf); glColor4ub (c2, c2, c2, 255); glVertex3f (xf, yf, zf); glColor4ub (c1, c1, c1, 255); glVertex3f (-xf, yf, zf); glEnd (); glLineWidth (LINEWIDTH(1)); glBegin (GL_LINE_STRIP); glColor4ub (c3, c3, c3, 255); glVertex3f (-xf, -yf, zf); glVertex3f (xf, -yf, zf); glVertex3f (xf, yf, zf); glVertex3f (-xf, yf, zf); glVertex3f (-xf, -yf, zf); glEnd (); font1->drawTextCentered (0, -0.5, -1.5, "PLEASE WAIT...", &colorwhite); game_view (); } void stats_key (unsigned char key, int x, int y) { if (key == 27) { pleaseWait (); display ("Initing new mission", LOG_MOST); missionactive = false; createMission (MISSION_DEMO); game_levelInit (); sound->haltMusic (); switch_menu (); } } void credits_key (unsigned char key, int x, int y) { if (key) { // sound->haltMusic (); switch_menu (); } } void finish_key (unsigned char key, int x, int y) { if (key) { // sound->haltMusic (); switch_menu (); } } void mission_key (unsigned char key, int x, int y) { if (key == 27) { switch_menu (); } else if (key == 13) { pleaseWait (); if (!game_levelInit ()) { switch_menu (); return; } switch_game (); missionactive = true; } } void fame_key (unsigned char key, int x, int y) { if (key == 27) { switch_menu (); } } void create_key (unsigned char key, int x, int y) { if (key == 's') { // server->sendMessage (0, "s", 1); if (server->checkStart()) { printf ("Starting.."); createMission (MISSION_MULTIPLAYER_DOGFIGHT); game_levelInit (); switch_game (); missionactive = true; } } if (key == 27) { switch_menu (); } } void join_key (unsigned char key, int x, int y) { if (key == 's') { createMission (MISSION_MULTIPLAYER_DOGFIGHT); game_levelInit (); switch_game (); missionactive = true; } if (key == 27) { switch_menu (); } } void fighter_key (unsigned char key, int x, int y) { if (key == 27) { switch_menu (); } } char *getModelText (int id) { if (id == FIGHTER_FALCON) return "THE FALCON IS A NIMBLE AND\nFAST FIGHTER PROVIDING\nBOTH AIR-AIR AND\nAIR-GROUND-MISSILES."; else if (id == FIGHTER_HAWK) return "THE HAWK IS A TYPICAL\nALLROUNDER AND DESIGNED\nFOR GROUND ATTACKS."; else if (id == FIGHTER_HAWK2) return "THE HAWK II IS A ..."; return "NO INFO"; } char *getModelName (int id) { if (id == FIGHTER_FALCON) return "GL-16 FALCON"; else if (id == FIGHTER_HAWK) return "GL-22 HAWK"; else if (id == FIGHTER_HAWK2) return "GL-23 HAWK II"; else if (id == FIGHTER_REDARROW) return "GL-15 REDARROW"; else if (id == FIGHTER_PHOENIX) return "GL-117 PHOENIX"; else if (id == FIGHTER_STORM) return "GL-50 STORM"; else if (id == FIGHTER_CROW) return "CROW"; else if (id == FIGHTER_BUZZARD) return "BUZZARD"; else if (id == FIGHTER_SWALLOW) return "SWALLOW"; else if (id == FIGHTER_BLACKBIRD) return "BLACKBIRD"; else if (id == MISSILE_AIR1) return "AIR-AIR MISSILE PACK"; else if (id == MISSILE_GROUND1) return "AIR-GROUND MISSILE PACK"; else if (id == MISSILE_DF1) return "DUMB FIRE MISSILE PACK"; return "NO INFO"; } void mission_mouse (int button, int state, int x, int y) { float rx = (float) x / width; float ry = (float) y / height; missionmenuitemselected = -1; missionmenufighterselected = -1; if (ry >= 0.53 && ry <= 0.65) { if (rx >= 0.18 && rx < 0.28) { missionmenufighterselected = 0; if (state == MOUSE_DOWN) missionnew->wantfighter = 0; } if (rx >= 0.28 && rx < 0.38 && missionnew->selfighters >= 2) { missionmenufighterselected = 1; if (state == MOUSE_DOWN) missionnew->wantfighter = 1; } if (rx >= 0.38 && rx < 0.48 && missionnew->selfighters >= 3) { missionmenufighterselected = 2; if (state == MOUSE_DOWN) missionnew->wantfighter = 2; } } missionmenuweaponselected = -1; if (ry >= 0.53 && ry <= 0.65) { if (rx >= 0.54 && rx < 0.64) { missionmenuweaponselected = 0; if (state == MOUSE_DOWN) missionnew->wantweapon = 0; } if (rx >= 0.64 && rx < 0.74 && missionnew->selweapons >= 2) { missionmenuweaponselected = 1; if (state == MOUSE_DOWN) missionnew->wantweapon = 1; } if (rx >= 0.74 && rx < 0.84 && missionnew->selweapons >= 3) { missionmenuweaponselected = 2; if (state == MOUSE_DOWN) missionnew->wantweapon = 2; } } } void drawArrow (float x, float y, float w, float h) { float zf = -3; gl->enableTextures (texarrow->textureID); gl->enableAlphaBlending (); glBegin (GL_QUADS); glColor3ub (180, 180, 180); if (w > h) { glTexCoord2f (0, 1); glVertex3f (x, y, zf); glTexCoord2f (0, 0); glVertex3f (x + w, y, zf); glTexCoord2f (1, 0); glVertex3f (x + w, y + h, zf); glTexCoord2f (1, 1); glVertex3f (x, y + h, zf); } else { glTexCoord2f (1, 0); glVertex3f (x, y - h, zf); glTexCoord2f (1, 1); glVertex3f (x, y, zf); glTexCoord2f (0, 1); glVertex3f (x + w, y, zf); glTexCoord2f (0, 0); glVertex3f (x + w, y - h, zf); } glEnd (); glDisable (GL_BLEND); glDisable (GL_TEXTURE_2D); } void mission_display () { allmenus.setVisible (false); missionmenu.setVisible (true); missionmenu.draw (); char buf [256]; int i; float piloty = 5; Pilot *p = pilots->pilot [pilots->aktpilot]; CColor *colorstd = &colorred; if (p->mission_state [missionnew->id] == 1) colorstd = &colorblue; CColor *col = &menu_colwhite; Font *font2 = font1; CVector3 vec; CVector3 tl (-4.5, 5.5, -8.0); CRotation rot; rot.a = 270; rot.b = (270 - missionmenutimer * 4 / timestep) % 360; rot.c = 90; // Draw dummy missile glEnable (GL_LIGHTING); model_missile1.draw (&vec, &tl, &rot, 0.05, 1.0, 0); glDisable (GL_LIGHTING); glEnable (GL_LIGHTING); glEnable (GL_DEPTH_TEST); tl.x = -0.24; tl.y = -0.075; tl.z = -0.5; rot.a = 300; rot.b = 0; for (i = 0; i < missionnew->selfighters; i ++) { tl.x = -0.24 + (float) i * 0.085; if (missionnew->wantfighter == i) rot.c = (5 + missionmenutimer * 4 / timestep) % 360; else rot.c = 5; getModel (missionnew->selfighter [i])->draw (&vec, &tl, &rot, 0.04, 0.1, 0); } tl.x = 0; tl.y = -0.075; tl.z = -0.5; rot.a = 300; rot.b = 0; for (i = 0; i < missionnew->selweapons; i ++) { tl.x = 0.08 + (float) i * 0.07; if (missionnew->wantweapon == i) rot.c = (5 + missionmenutimer * 4 / timestep) % 360; else rot.c = 5; getModel (missionnew->selweapon [i])->draw (&vec, &tl, &rot, 0.04, 0.1, 0); } glDisable (GL_DEPTH_TEST); glDisable (GL_LIGHTING); float textx = -12, texty = 9.8; font1->zoom = 0.105; font2->zoom = 0.105; float fontscale = 1.05; font1->drawTextCentered (0, texty / fontscale, -2, missionnew->name, col); texty -= 1.1; font1->zoom = 0.05; font2->zoom = 0.05; fontscale = 0.5; font1->drawText (textx / fontscale, texty / fontscale, -2, "BRIEFING:", col); texty -= 1; font1->drawText (textx / fontscale, texty / fontscale, -2, missionnew->briefing, col); float xstats = 0.8, ystats = 5; float xstatstab = 5; font1->drawText (xstats / fontscale, ystats / fontscale, -2, "STATUS:", col); if (p->mission_state [missionnew->id] == 1) font1->drawText (xstatstab / fontscale, ystats / fontscale, -2, "SUCCESS", colorstd); else if (p->mission_state [missionnew->id] == 2) font1->drawText (xstatstab / fontscale, ystats / fontscale, -2, "FAILED", colorstd); else font1->drawText (xstatstab / fontscale, ystats / fontscale, -2, "EMPTY", colorstd); if (missionnew->id >= MISSION_CAMPAIGN1 && missionnew->id <= MISSION_CAMPAIGN2) { texty = ystats - 0.7; font1->drawText (xstats / fontscale, texty / fontscale, -2, "SCORE:", col); int score = p->mission_score [missionnew->id]; if (score < -10000 || score > 100000) score = 0; sprintf (buf, "%d", score); font1->drawText (xstatstab / fontscale, texty / fontscale, -2, buf, colorstd); texty -= 0.7; font1->drawText (xstats / fontscale, texty / fontscale, -2, "KILLS:", col); sprintf (buf, "%d AIRCRAFTS", p->mission_fighterkills [missionnew->id]); font1->drawText (xstatstab / fontscale, texty / fontscale, -2, buf, colorstd); // drawMedal (xstatstab + 2, ystats - 3, -2, getMedal (p->mission_score [missionnew->id]), 2, mission->id); } else { texty = ystats - 0.7; font1->drawText (xstats / fontscale, texty / fontscale, -2, "SCORE:", col); font1->drawText (xstatstab / fontscale, texty / fontscale, -2, "TRAINING", col); } font1->drawText (textx / fontscale, piloty / fontscale, -2, "PILOTS:", col); strcpy (buf, pilots->pilot [pilots->aktpilot]->getShortRank ()); strcat (buf, " "); strcat (buf, pilots->pilot [pilots->aktpilot]->name); font2->drawText ((textx + 1.5) / fontscale, (piloty - 0.8) / fontscale, -2, buf, col); drawRank (textx, piloty - 0.8, -2, pilots->pilot [pilots->aktpilot]->ranking, 0.5); for (i = 1; i < missionnew->alliedfighters; i ++) if (missionnew->alliedpilot [i - 1] >= 0 && missionnew->alliedpilot [i - 1] < 100) { drawRank (textx, piloty - 1 - 0.6 * i, -2, pilots->pilot [pilots->aktpilot]->tp [missionnew->alliedpilot [i - 1]]->ranking, 0.5); font2->drawText ((textx + 1.5) / fontscale, (piloty - 1 - 0.6 * i) / fontscale, -2, pilots->pilot [pilots->aktpilot]->tp [missionnew->alliedpilot [i - 1]]->getShortName (), col); } font1->drawText (textx / fontscale, -1 / fontscale, -2, "CHOOSE FIGHTER:", col); font1->drawText (xstats / fontscale, -1 / fontscale, -2, "CHOOSE WEAPON PACK:", col); font2->drawText (textx / fontscale, -6 / fontscale, -2, getModelName (missionnew->selfighter [missionnew->wantfighter]), col); font2->drawText (xstats / fontscale, -6 / fontscale, -2, getModelName (missionnew->selweapon [missionnew->wantweapon]), col); font1->zoom = 0.1; font2->zoom = 0.1; drawMouseCursor (); } void fame_mouse (int button, int state, int x, int y) { missionmenuitemselected = -1; } void create_mouse (int button, int state, int x, int y) { float rx = (float) x / width; float ry = (float) y / height; missionmenuitemselected = -1; if (ry >= 0.8 && ry <= 0.9) { if (rx >= 0.4 && rx <= 0.6) { missionmenuitemselected = 0; if (state == MOUSE_DOWN) { create_key (27, 0, 0); } } } } void create_display () { CColor *colorstd = &colorblue; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glPushMatrix (); drawQuads (colorstd); #ifdef HAVE_SDL_NET float my = 0; int i; for (i = 0; i < server->num_clients; i ++) { font1->drawTextCentered (0, my, -2.5, server->clients [i].name); my -= 2; } #endif font1->drawTextCentered (0, 9, -1.5, "CREATE GAME"); if (missionmenuitemselected == 0) font1->drawTextScaled (-2, -12, -2, "BACK", colorstd, -missionmenutimer * 5); else font1->drawText (-2, -12, -2, "BACK"); glPopMatrix (); adjustBrightness (); drawMouseCursor (); } void join_mouse (int button, int state, int x, int y) { float rx = (float) x / width; float ry = (float) y / height; missionmenuitemselected = -1; if (ry >= 0.8 && ry <= 0.9) { if (rx >= 0.4 && rx <= 0.6) { missionmenuitemselected = 0; if (state == MOUSE_DOWN) { create_key (27, 0, 0); } } } } void join_display () { CColor *colorstd = &colorblue; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glPushMatrix (); drawQuads (colorstd); font1->drawTextCentered (0, 9, -1.5, "JOIN GAME"); if (missionmenuitemselected == 0) font1->drawTextScaled (-2, -12, -2, "BACK", colorstd, -missionmenutimer * 5); else font1->drawText (-2, -12, -2, "BACK"); glPopMatrix (); adjustBrightness (); drawMouseCursor (); } int aktfighter = 0; void fighter_mouse (int button, int state, int x, int y) { } void fighter_display () { allmenus.setVisible (false); fightermenu.setVisible (true); fightermenu.draw (); AIObj ffighter; char buf [256]; int i; CVector3 vec; CVector3 tl; tl.y = -0.04; tl.z = -0.4; CRotation rot; rot.a = 300; rot.b = 0; rot.c = (5 + missionmenutimer * 4 / timestep) % 360; CModel *model = NULL; int id = 0; if (aktfighter == 0) { model = &model_fig; id = FIGHTER_FALCON; } else if (aktfighter == 1) { model = &model_fige; id = FIGHTER_CROW; } else if (aktfighter == 2) { model = &model_figb; id = FIGHTER_HAWK; } else if (aktfighter == 3) { model = &model_figi; id = FIGHTER_STORM; } else if (aktfighter == 4) { model = &model_figa; id = FIGHTER_SWALLOW; } else if (aktfighter == 5) { model = &model_figd; id = FIGHTER_BUZZARD; } else if (aktfighter == 6) { model = &model_figc; id = FIGHTER_HAWK2; } else if (aktfighter == 7) { model = &model_figg; id = FIGHTER_REDARROW; } else if (aktfighter == 8) { model = &model_figf; id = FIGHTER_PHOENIX; } else if (aktfighter == 9) { model = &model_figh; id = FIGHTER_BLACKBIRD; } glEnable (GL_DEPTH_TEST); glEnable (GL_LIGHTING); model->draw (&vec, &tl, &rot, 0.11, 0.5, 0); glDisable (GL_LIGHTING); glDisable (GL_DEPTH_TEST); ffighter.o = model; ffighter.newinit (id, 1, 0); float fontzoom = 0.7; float textx = -9.5; font1->zoom = 0.07; font1->drawText (textx / fontzoom, 9.7 / fontzoom, -2, getModelName (id), &menu_colwhite); float yf = 9.6 - 1.35; strcpy (buf, "TYPE: "); if (ffighter.id == FIGHTER_FALCON || ffighter.id == FIGHTER_CROW || ffighter.id == FIGHTER_BUZZARD || ffighter.id == FIGHTER_REDARROW || ffighter.id == FIGHTER_BLACKBIRD) strcat (buf, "FIGHTER"); else if (ffighter.id == FIGHTER_HAWK || ffighter.id == FIGHTER_HAWK2) strcat (buf, "FIGHTER-BOMBER"); else strcat (buf, "BOMBER"); font1->drawText (textx / fontzoom, yf / fontzoom, -2, buf, &menu_colwhite); yf -= 1; strcpy (buf, "SPEED: "); int stars = (int) ((ffighter.maxthrust - 0.2) * 40); font1->drawText (textx / fontzoom, yf / fontzoom, -2, buf, &menu_colwhite); for (i = 0; i < stars; i ++) drawMedal (4 + i * 1.1, yf + 0.7, -2, 0, 1, MISSION_CAMPAIGN1); yf -= 1; strcpy (buf, "NIMBILITY: "); stars = (int) ((ffighter.manoeverability - 0.3) * 20 + 1); font1->drawText (textx / fontzoom, yf / fontzoom, -2, buf, &menu_colwhite); for (i = 0; i < stars; i ++) drawMedal (4 + i * 1.1, yf + 0.7, -2, 0, 1, MISSION_CAMPAIGN1); yf -= 1; strcpy (buf, "SHIELD: "); stars = (int) ((ffighter.maxshield - 30) / 30); font1->drawText (textx / fontzoom, yf / fontzoom, -2, buf, &menu_colwhite); for (i = 0; i < stars; i ++) drawMedal (4 + i * 1.1, yf + 0.7, -2, 0, 1, MISSION_CAMPAIGN1); yf -= 1; strcpy (buf, "FIREPOWER: "); stars = ffighter.statfirepower; font1->drawText (textx / fontzoom, yf / fontzoom, -2, buf, &menu_colwhite); for (i = 0; i < stars; i ++) drawMedal (4 + i * 1.1, yf + 0.7, -2, 0, 1, MISSION_CAMPAIGN1); font1->zoom = 0.1; drawMouseCursor (); } void fame_display () { allmenus.setVisible (false); famemenu.setVisible (true); famemenu.draw (); char buf [256]; int i, i2; Pilot *p = pilots->pilot [pilots->aktpilot]; float textx = -10; int sum = 0; for (i = MISSION_CAMPAIGN1; i < MISSION_CAMPAIGN2; i ++) sum += p->mission_fighterkills [i]; p->tp [10]->fighterkills = sum; strcpy (p->tp [10]->name, p->name); p->tp [10]->ranking = p->ranking; int index [11]; for (i = 0; i < 11; i ++) index [i] = i; for (i = 0; i < 11; i ++) for (i2 = 0; i2 < i; i2 ++) { if (p->tp [index [i]]->fighterkills < p->tp [index [i2]]->fighterkills) { int temp = index [i]; index [i] = index [i2]; index [i2] = temp; } } for (i = 0; i < 11; i ++) { font1->zoom = 0.07; drawRank (textx + 0.2, i - 3.7, -2, p->tp [index [i]]->ranking, 0.7); sprintf (buf, "%s %s", p->tp [index [i]]->getRank (), p->tp [index [i]]->name); font1->drawText ((textx + 2) / 0.7, (i - 3.7) / 0.7, -2, buf, &menu_colwhite); sprintf (buf, "%d", p->tp [index [i]]->fighterkills); font1->drawText ((textx + 18) / 0.7, (i - 3.7) / 0.7, -2, buf, &menu_colwhite); font1->zoom = 0.1; } drawMouseCursor (); } CModel *explsphere; CSphere *mysphere; void game_quit () { int i; volumesound = sound->volumesound; volumemusic = sound->volumemusic; save_config (); save_configInterface (); pilots->save (dirs->getSaves ("pilots")); display ("Pilots saved", LOG_MOST); for (i = 0; i < maxlaser; i ++) delete (laser [i]); for (i = 0; i < maxmissile; i ++) delete (missile [i]); for (i = 0; i < maxflare; i ++) delete (flare [i]); for (i = 0; i < maxchaff; i ++) delete (chaff [i]); for (i = 0; i < maxexplosion; i ++) delete (explosion [i]); for (i = 0; i < maxstar; i ++) delete (star [i]); for (i = 0; i < maxgroundobj; i ++) delete (groundobj [i]); for (i = 0; i < maxblacksmoke; i ++) delete (blacksmoke [i]); delete pilots; delete tlinf; delete tlminf; delete tlnull; delete explsphere; delete objsphere; delete sphere; delete flash1; delete cockpit; delete font1; delete font2; delete space; delete dirs; delete gl; #ifndef USE_GLUT // SDL_CloseAudio(); // SDL_FreeWAV(wave.sound); // SDL_Quit (); // done atexit() delete sound; #endif exit (EXIT_NORMAL); } void quit_key (unsigned char key, int x, int y) { if (key == 'y' || key == 'Y') game_quit (); else switch_menu (); } void quit_mouse (int button, int state, int x, int y) { float rx = (float) x / width; float ry = (float) y / height; missionmenuitemselected = -1; if (ry >= 0.5 && ry <= 0.55) { if (rx >= 0.35 && rx <= 0.45) { missionmenuitemselected = 0; if (state == MOUSE_DOWN) { quit_key ('y', 0, 0); } } if (rx >= 0.55 && rx <= 0.65) { missionmenuitemselected = 1; if (state == MOUSE_DOWN) { quit_key (27, 0, 0); } } } } void menu_mouse (int button, int state, int x, int y) { } void stats_mouse (int button, int state, int x, int y) { } /**************************************************************************** DISPLAY EVENTS ****************************************************************************/ void drawMissionElement (float x, float y, float z, int thismissionid, int missionid, int selected, char *string) { Pilot *p = pilots->pilot [pilots->aktpilot]; drawMedal (x - 0.8, y + 0.6, z, getMedal (p->mission_score [thismissionid]), 1.0, thismissionid); } void stats_display () { allmenus.setVisible (false); statsmenu.setVisible (true); statsmenu.draw (); float yf = 1.4, zf = -2.5; drawMedal (-5.5, 5.8, -1.5, getMedal (fplayer->score), 1.6, mission->id); drawMedal (5.5, 5.8, -1.5, getMedal (fplayer->score), 1.6, mission->id); char buf [100]; float xf1 = -12, xf2 = 0, xf3 = 8; float linedist = 1.3, linedist2 = 1.1; yf = 6.5; zf = -2.5; CColor *color; Pilot *p = pilots->pilot [pilots->aktpilot]; color = &menu_colwhite; if (missionstate == 1) { font1->drawTextCentered (0, 7, -2, "SUCCESS", &colorblue); } else { font1->drawTextCentered (0, 7, -2, "FAILED", &colorred); } font1->drawText (xf1, yf, zf, "SCORE:", color); sprintf (buf, "%d", fplayer->score); font1->drawText (xf3, yf, zf, buf, color); yf -= linedist * 1.2; font1->drawText (xf1, yf, zf, "DIFFICULTY:", color); if (mission->difficulty == 0) font1->drawText (xf2, yf, zf, "EASY", color); else if (mission->difficulty == 1) font1->drawText (xf2, yf, zf, "NORMAL", color); else if (mission->difficulty == 2) font1->drawText (xf2, yf, zf, "HARD", color); if (mission->difficulty == 0) font1->drawText (xf3, yf, zf, "-25", color); else if (mission->difficulty == 1) font1->drawText (xf3, yf, zf, "+25", color); else if (mission->difficulty == 2) font1->drawText (xf3, yf, zf, "+75", color); yf -= linedist; font1->drawText (xf1, yf, zf, "FLIGHT MODEL:", color); if (!fplayer->realism) font1->drawText (xf2, yf, zf, "ACTION", color); else font1->drawText (xf2, yf, zf, "SIM", color); if (!fplayer->realism) font1->drawText (xf3, yf, zf, "-25", color); else font1->drawText (xf3, yf, zf, "+25", color); int timebonus = 0; if (mission->timer < mission->maxtime) timebonus = (mission->maxtime - mission->timer) * 100 / mission->maxtime; yf -= linedist; font1->drawText (xf1, yf, zf, "TIME BONUS:", color); sprintf (buf, "%d%%", timebonus); font1->drawText (xf2, yf, zf, buf, color); sprintf (buf, "+%d", timebonus); font1->drawText (xf3, yf, zf, buf, color); int shieldbonus = (int) (fplayer->shield * 100 / fplayer->maxshield); yf -= linedist; font1->drawText (xf1, yf, zf, "SHIELD BONUS:", color); sprintf (buf, "%d%%", shieldbonus); font1->drawText (xf2, yf, zf, buf, color); sprintf (buf, "+%d", shieldbonus); font1->drawText (xf3, yf, zf, buf, color); yf -= linedist; font1->drawText (xf1, yf, zf, "KILLS:", color); if (fplayer->fighterkills > 0) { sprintf (buf, "%d AIR", fplayer->fighterkills); font1->drawText (xf2, yf, zf, buf, color); sprintf (buf, "+%d", fplayer->fighterkills * 20); font1->drawText (xf3, yf, zf, buf, color); yf -= linedist2; } if (fplayer->tankkills > 0) { sprintf (buf, "%d TANKS", fplayer->tankkills); font1->drawText (xf2, yf, zf, buf, color); sprintf (buf, "+%d", fplayer->tankkills * 10); font1->drawText (xf3, yf, zf, buf, color); yf -= linedist2; } if (fplayer->shipkills > 0) { sprintf (buf, "%d SHIPS", fplayer->shipkills); font1->drawText (xf2, yf, zf, buf, color); sprintf (buf, "+%d", fplayer->shipkills * 12); font1->drawText (xf3, yf, zf, buf, color); yf -= linedist2; } if (fplayer->otherkills > 0) { sprintf (buf, "%d OTHERS", fplayer->otherkills); font1->drawText (xf2, yf, zf, buf, color); sprintf (buf, "+%d", fplayer->otherkills * 5); font1->drawText (xf3, yf, zf, buf, color); yf -= linedist2; } yf -= (linedist - linedist2); if (ispromoted) { yf = -6; font1->drawTextCentered (0, yf, zf, "PROMOTED TO", color); yf -= 1.5; sprintf (buf, "%s", p->getRank ()); font1->drawTextCentered (0, yf, zf, buf, color); drawRank (-11, yf + 0.2, zf, pilots->pilot [pilots->aktpilot]->ranking, 2); drawRank (7, yf + 0.2, zf, pilots->pilot [pilots->aktpilot]->ranking, 2); } yf = -9; drawMouseCursor (); } void test () { view ++; if (view > VIEW_MAX) view = VIEW_MIN; } void menu_display () { int i; glInitNames (); glPushName (0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); int menutimernorm = menutimer * 5 / timestep; if (menutimernorm != 0) menutimernorm %= 360; if (menutimernorm < 0) menutimernorm *= -1; CColor color2 (255, 255, (int) (255.0 * cosi [menutimernorm]), 255); Pilot *p = pilots->pilot [pilots->aktpilot]; if (allmenus.components [3]->isVisible ()) { ((Container *) allmenus.components [3])->components [0]->setVisible (true); for (i = 1; i < 25; i ++) { if (p->mission_state [getCampaignIdFromValue (i - 1)] == 1) ((Container *) allmenus.components [3])->components [i]->setVisible (true); else ((Container *) allmenus.components [3])->components [i]->setVisible (false); } } allmenus.draw (); if (allmenus.components [1]->isVisible ()) { float textx2 = -0.7, yf = 10.15, zf = -2, ydiff = 1; drawRank (textx2, yf, zf, pilots->pilot [pilots->aktpilot]->ranking, 0.8); yf -= 2; for (i = 0; i < pilots->aktpilots; i ++) { drawRank (textx2, yf, zf, pilots->pilot [i]->ranking, 0.8); yf -= ydiff; } } if (allmenus.components [3]->isVisible ()) { float textx2 = 11, yf = 9.05, zf = -2, ydiff = 0.8; for (i = 0; i < 24; i ++) { drawMedal (textx2 - 0.8, yf + 0.6, zf, getMedal (p->mission_score [getCampaignIdFromValue (i)]), 0.8, getCampaignIdFromValue (i)); yf -= ydiff; } } drawMouseCursor (); } int selectMouse (int x, int y, int motionx, int motiony, int mode, bool shift) { // glutSwapBuffers (); GLuint selectBuff [20 * 4]; GLint hits, viewport [4]; // Select buffer parameters glSelectBuffer (20 * 4, selectBuff); glGetIntegerv (GL_VIEWPORT, viewport); // Enter to selection mode glEnable (GL_DEPTH_TEST); glDisable (GL_LIGHTING); glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); // Set-up pick matrix gluPickMatrix (x, viewport [3] - y, 5, 5, viewport); // Set our perpective transformation matrix gluPerspective (visibleangle, 1.0, nearclippingplane * GLOBALSCALE, view * GLOBALSCALE); // gluPerspective (60.0, 1.0, 0.2, 200.0); glMatrixMode (GL_MODELVIEW); // Render all scene and fill selection buffer glRenderMode (GL_SELECT); menu_display (); // Get hits and go back to normal rendering hits = glRenderMode (GL_RENDER); // Get first model in selection buffer stack GLuint *ptr = selectBuff; int mypicks = 0; int pickz2 = -1; int pick [100]; if (hits > 0) { int i; GLuint z = 0xFFFFFFFF; for (i = 0; i < hits; i ++) { int names = *ptr; ptr ++; GLuint z1 = *ptr; ptr ++; ptr ++; if (motionx < 0 && motiony < 0) { if (z1 < z) { z = z1; pickz2 = *ptr; mypicks = 1; } } else { pick [mypicks] = *ptr; mypicks ++; } ptr += names; if (mypicks >= 20) break; } } glMatrixMode (GL_PROJECTION); glPopMatrix (); glMatrixMode (GL_MODELVIEW); char buf [STDSIZE]; sprintf (buf, "selectMouse: picks=%d, pickz=%d, shift=%d", mypicks, pickz2, shift); display (buf, LOG_ALL); return pickz2; } void pause_display () { glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glPushMatrix (); font1->drawText (-3, -1, -1, "PAUSED", &colorwhite); glPopMatrix (); } void credits_mouse (int button, int state, int x, int y) { switch_menu (); } void credits_display () { #ifdef SHOW_SOFTWARE_PATENTS float xt = -22, yt = 12, zf = -2.4, ydist = 0.7; glPushMatrix (); // glTranslatef (0, -3.5 + 0.014 * (float) creditstimer / timestep, 0); glTranslatef (0, -3.4 + 0.004 * (float) creditstimer / timestep, 0); CColor *col = &colorwhite; CColor *col2 = &coloryellow; float fontzoom = 1.0; font1->zoom = 0.1; font2->zoom = 0.1; font1->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "MONEY VERSUS DEMOCRACY", col2); font1->drawTextCentered (0, (yt -= 3 * ydist) / fontzoom, zf, "PATENTS ON SOFTWARE", col2); fontzoom = 0.8; font1->zoom = 0.08; font2->zoom = 0.08; font1->drawText (xt, (yt -= 5 * ydist) / fontzoom, zf, "WHAT ARE PATENTS?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "PATENTS IN EUROPE COST ABOUT 30000-50000 EURO (= US$).", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "THEY GRANT PROPERTY FOR SOMETHING, THAT NOONE CAN PUBLISH", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "EXCEPT THE PATENT OWNER.", col); font1->drawText (xt, (yt -= 4 * ydist) / fontzoom, zf, "WHO CAN AFFORD PATENTS?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "ONLY HUGE COMPANIES.", col); font1->drawText (xt, (yt -= 4 * ydist) / fontzoom, zf, "WHAT CAN BE PATENTED?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "CURRENTLY EVERYTHING. AMAZON HAS A PATENT TO SELL PRODUCTS", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "WITH ONE MOUSE CLICK. THERE ARE EUROPEAN PATENTS ON THE", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "PROGRESS BAR, ON THE UNDO FUNCTION, ETC.", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "CURRENTLY EURO SOFTWARE PATENTS ARE STOPPED UNTIL THE END", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "OF SUMMER 2004.", col); font1->drawText (xt, (yt -= 4 * ydist) / fontzoom, zf, "AN EXAMPLE FOR PATENTS ON COURT?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "IN 2001 MICROSOFT HAD TO PAY 500000000 US$, BECAUSE ANOTHER", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "COMPANY HAD A PATENT ON BROWSER PLUGINS (US).", col); font1->drawText (xt, (yt -= 4 * ydist) / fontzoom, zf, "WHAT IS SOFTWARE?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "SOFTWARE IS BASED ON ABSTRACT DESCRIPTIONS, WHICH EVERYONE", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "CAN FORMULATE IN PROSE LANGUAGE. CODE IS JUST A MIRROR", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "IMAGE OF THE DESCRIPTION.", col); font1->drawText (xt, (yt -= 4 * ydist) / fontzoom, zf, "WHY DOES MICROSOFT WANT PATENTS?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "TO PATENT CONCEPTS, AND DICTATE WHICH SYSTEMS MAY USE THEM.", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "EVENTUALLY TO ELIMINATE LINUX AND OPEN SOURCE.", col); font1->drawText (xt, (yt -= 4 * ydist) / fontzoom, zf, "WHY CAN EVERYTHING BE PATENTED?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "HUGE COMPANIES ARE PUSHING FOR EXECUTIVE POWERS.", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "PATENT LAWYERS ARE TAKING THE MONEY.", col); font1->drawText (xt, (yt -= 4 * ydist) / fontzoom, zf, "WHAT IS DEMOCRACY?", col2); font2->drawText (xt, (yt -= 2 * ydist) / fontzoom, zf, "YOUR POWER TO STOP THIS ABUSE.", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "VOTE AGAINST SOFTWARE PATENTS ON HTTP://PETITION.EUROLINUX.ORG.", col); font2->drawText (xt, (yt -= 1.5 * ydist) / fontzoom, zf, "TELL YOUR FRIENDS AND SEARCH THE INTERNET FOR MORE INSANITY.", col); #else float yt = 12, zf = -2.4, ydist = 0.7; glPushMatrix (); glTranslatef (0, -3.5 + 0.014 * (float) creditstimer / timestep, 0); CColor *col = &colorwhite; CColor *col2 = &coloryellow; float fontzoom = 1; font2->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "GAME PROGRAMMING,", col); font2->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "GRAPHICS, MODELS, SOUND & MUSIC", col); font1->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "THOMAS A. DREXL", col2); font1->zoom = 0.08; font2->zoom = 0.08; fontzoom = 0.8; font2->drawTextCentered (0, (yt -= 4 * ydist) / fontzoom, zf, "SPECIAL THANKS TO...", col); font2->drawTextCentered (0, (yt -= 4 * ydist) / fontzoom, zf, "LENS FLARES & FURTHER DEBUGGING", col); font1->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "PIOTR PAWLOW", col2); font2->drawTextCentered (0, (yt -= 4 * ydist) / fontzoom, zf, "MOUSE INTERFACE & LANDSCAPE IMPROVEMENTS", col); font1->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "LOURENS VEEN", col2); font2->drawTextCentered (0, (yt -= 4 * ydist) / fontzoom, zf, "PUBLISHING & FURTHER GAME IDEAS", col); font1->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "BERNHARD KAINDL", col2); font2->drawTextCentered (0, (yt -= 4 * ydist) / fontzoom, zf, "MOON TERRAIN", col); font1->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "NORBERT DREXL", col2); font2->drawTextCentered (0, (yt -= 4 * ydist) / fontzoom, zf, "PHYSICAL MODEL (ACTION) & COCKPIT IMPROVEMENTS", col); font1->drawTextCentered (0, (yt -= 2 * ydist) / fontzoom, zf, "ARNE REINERS", col2); font2->drawTextCentered (0, (yt -= 4 * ydist) / fontzoom, zf, "...AND THANKS TO ALL PEOPLE GIVING FEEDBACK AND ADVICE", col); float xf = -10; font1->zoom = 0.1; font2->zoom = 0.1; fontzoom = 1; font1->drawTextCentered (0, (yt -= 10 * ydist) / fontzoom, zf, "***********************", col); font1->drawTextCentered (0, (yt -= 10 * ydist) / fontzoom, zf, "DO YOU WANT TO CONTRIBUTE?", col); font1->zoom = 0.08; font2->zoom = 0.08; fontzoom = 0.8; font2->drawText (xf / fontzoom, (yt -= 4 * ydist) / fontzoom, zf, "LOTS OF THINGS ARE STILL NEEDED:", col); font2->drawText (xf / fontzoom, (yt -= 2 * ydist) / fontzoom, zf, "- DRAW TEXTURES OF TREES, BUILDINGS, ETC", col); font2->drawText (xf / fontzoom, (yt -= 2 * ydist) / fontzoom, zf, "- DESIGN 3D MODELS", col); font2->drawText (xf / fontzoom, (yt -= 2 * ydist) / fontzoom, zf, "- CREATE SOUNDTRACKS", col); font2->drawText (xf / fontzoom, (yt -= 2 * ydist) / fontzoom, zf, "- MAKE MISSION SUGGESTIONS", col); font2->drawText (xf / fontzoom, (yt -= 2 * ydist) / fontzoom, zf, "- GIVE FEEDBACK AND ADVICE", col); font1->zoom = 0.1; font2->zoom = 0.1; glPopMatrix (); #endif } void finish_display () { glTranslatef (0, -3.5 + 0.01 * (float) finishtimer / timestep, 0); CColor *col = &colorwhite; font1->drawTextCentered (0, 12, -3, "CONGRATULATIONS!", col); font1->drawTextCentered (0, 10, -3, "THE WORLD HAS BEEN SAVED YET AGAIN.", col); font1->drawTextCentered (0, 6, -3, "HOPE YOU HAD FUN PLAYING GL-117!", col); font1->drawTextCentered (0, 4, -3, "THIS GAME HAS ORIGINALLY BEEN DEVELOPED AS PART", col); font1->drawTextCentered (0, 2, -3, "OF THE COURSE \"APPLICATIONS OF COMPUTER GRAPHICS\"", col); font1->drawTextCentered (0, 0, -3, "AT THE TECHNICAL UNIVERSITY OF MUNICH, GERMANY.", col); font1->drawTextCentered (0, -2, -3, "IN FEBRUARY 2002 THE WORK WAS DONE AND I", col); font1->drawTextCentered (0, -4, -3, "PRESENTED THE PROTOTYPE OF A FLIGHT SIM,", col); font1->drawTextCentered (0, -6, -3, "YET WITHOUT TEXTURES, JOYSTICK, SOUNDS, MUSIC,", col); font1->drawTextCentered (0, -8, -3, "NO CAMPAIGN!", col); font1->drawTextCentered (0, -10, -3, "TWO MONTHS LATER THE FIRST RELEASE OF GL-117 WAS READY.", col); font1->drawTextCentered (0, -12, -3, "FURTHER RELEASES FOLLOWED, FEEDBACK ARRIVED, AND", col); font1->drawTextCentered (0, -14, -3, "PROGRAMMERS JOINED (LISTED IN THE CREDITS SECTION).", col); font1->drawTextCentered (0, -16, -3, "SPECIAL THANKS TO JOSEF DREXL FOR THE MODELING IDEAS,", col); font1->drawTextCentered (0, -18, -3, "AND THE UNIX AWARD GOES TO WOLFGANG HOMMEL ;-)", col); } void quit_display () { allmenus.setVisible (false); quitmenu.setVisible (true); quitmenu.draw (); font1->drawTextCentered (0, 0, -2, "REALLY QUIT?", &menu_colwhite); drawMouseCursor (); } /**************************************************************************** IN-GAME DISPLAY EVENT ****************************************************************************/ int vibration = 0; int starttime; void game_display () { int i; double sunx = 0, suny = 0, sunz; if (dithering) glEnable (GL_DITHER); else glDisable (GL_DITHER); bool sunvisible = false; float pseudoview = getView (); float mycamtheta = camtheta, mycamphi = camphi + view_x , mycamgamma = camgamma + view_y; if (vibration > 0) { if (camera == 0) { float sinvib = sin ((float) vibration / timestep); mycamphi += 0.2 * vibration * sinvib / timestep; mycamgamma += 0.2 * vibration * sinvib / timestep; } } // calculate light factor if (camera == 0 && sunblinding && day && weather == WEATHER_SUNNY) { float np = fplayer->phi - 180; if (np >= 180) np -= 360; float sunfactor = fabs (np) + fabs (fplayer->gamma - 180 - sungamma); if (sunfactor < 50) { sunfactor = (50 - sunfactor) / 10; if (sunfactor < 1.0) sunfactor = 1.0; } else sunfactor = 1.0; sunlight_dest = sunfactor; if (game == GAME_PLAY) pseudoview /= sunfactor; } else { if (day) sunlight_dest = 1.0; else sunlight_dest = 0.75; if (flash > 0) { sunlight_dest = (float) flash / timestep; } } // show a short flash when an object explodes if (dynamiclighting) { for (i = 0; i < maxfighter; i ++) { if (fighter [i]->draw) if (fighter [i]->explode > 0) if (fighter [i] != fplayer) { float dgamma = fabs (fplayer->getAngleH (fighter [i])); float dphi = fabs (fplayer->getAngle (fighter [i])); if (dphi < 45 && dgamma < 45) { float ddist = fplayer->distance (fighter [i]); if (ddist < 40) { ddist /= 15; ddist ++; dphi /= 25; dphi ++; dgamma /= 25; dgamma ++; if (fighter [i]->explode < 8 * timestep) sunlight_dest = (float) fighter [i]->explode / timestep * 4 / ddist / dphi / dgamma; else if (fighter [i]->explode < 16 * timestep) sunlight_dest = (16.0 - fighter [i]->explode / timestep) * 4 / ddist / dphi / dgamma; } } } } } // sunlight for glittering does not look good /* if (camera == 0 && l->glittering > 1.0F) { sunlight += l->glittering * 1.0F - 1.0F; }*/ l->glittering = 0; // turn down global sunlight when menu is showing if (game != GAME_PLAY && sunlight > 0.9F) sunlight = 0.9F; // start rendering glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glScalef (GLOBALSCALE, GLOBALSCALE, GLOBALSCALE); glShadeModel (GL_SMOOTH); glPushMatrix (); if (camera != 1 && camera != 5) glRotatef (-mycamtheta, 0.0, 0.0, 1.0); glRotatef (mycamgamma, 1.0, 0.0, 0.0); glRotatef (-mycamphi, 0.0, 1.0, 0.0); // draw sky glDisable (GL_FOG); glDisable (GL_DEPTH_TEST); float mylight = sunlight; if (!day) mylight /= 0.75; if (mylight > 1.0 && day) mylight = mylight / 5.0 + 0.8; else if (mylight > 1.0 && !day) mylight = mylight / 5.0 + 0.8; gl->foglum = mylight; sphere->drawGL (tlminf, tlinf, tlnull, space->alpha, mylight, true, false); if (weather == WEATHER_SUNNY || weather == WEATHER_CLOUDY) { if (!day) { glPointSize (LINEWIDTH(1.0F)); int stars = maxstar; if (weather != WEATHER_CLOUDY) stars = maxstar / 2; for (i = 0; i < stars; i ++) { glPushMatrix (); glRotatef (star [i]->phi, 0.0, 1.0, 0.0); glRotatef (star [i]->gamma, 1.0, 0.0, 0.0); glTranslatef (0, 0, -10); star [i]->draw (); glPopMatrix (); } } } glEnable (GL_DEPTH_TEST); glEnable (GL_FOG); if (quality >= 1 && clouds > 0) { float cloudfog = pseudoview; if (cloudfog > 110) cloudfog = 110; gl->enableFog (cloudfog); highclouds->zoom = 400; float ch2 = -382 - fplayer->tl->y / 10.0; CVector3 tlsphere2 (0, ch2, 0); highclouds->drawGL (&tlsphere2, fplayer->tl); glDisable (GL_FOG); } // draw sun or moon (or earth) float fac = view, zfac = view * 0.2; if (weather == WEATHER_SUNNY || weather == WEATHER_CLOUDY) { glRotatef (180, 0.0, 1.0, 0.0); if (camera == 0) glRotatef (sungamma, 1.0, 0.0, 0.0); else glRotatef (mycamgamma + sungamma, 1.0, 0.0, 0.0); float zf = -11; if (day) zf = -10; if (l->type == LAND_MOON && !day) zf = -8; // diplay bigger earth glTranslatef (0, 0, zf); gl->extractFrustum (); if (gl->isPointInFrustum (-1, 1, 0) || gl->isPointInFrustum (-1, -1, 0) || gl->isPointInFrustum (1, -1, 0) || gl->isPointInFrustum (1, 1, 0)) { glDisable (GL_DEPTH_TEST); if (day) gl->enableTextures (texsun->textureID); else if (l->type != LAND_MOON) gl->enableTextures (texmoon->textureID); else gl->enableTextures (texearth->textureID); if (day && l->type != 1) glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); gl->enableAlphaBlending (); glEnable (GL_ALPHA_TEST); float alphamax = 0.1; if (day) alphamax = 0.1; glAlphaFunc (GL_GEQUAL, alphamax); glBegin (GL_QUADS); fac = view; zfac = view * 3.5; if (day && l->type != LAND_MOON) { float gm = (40.0 - sungamma) / 80.0; if (gm < 0) gm = 0; if (gm > 0.5) gm = 0.5; glColor4f (1.0, 1.0 - gm, 0.8 - gm, 1.0); } else glColor4f (1.0, 1.0, 1.0, 1.0); glTexCoord2d (0, 1); glVertex3f (-1, 1, 0); glTexCoord2d (1, 1); glVertex3f (1, 1, 0); glTexCoord2d (1, 0); glVertex3f (1, -1, 0); glTexCoord2d (0, 0); glVertex3f (-1, -1, 0); glEnd (); // Where is the sun? double proj[16]; double modl[16]; int vp[4]; glGetDoublev( GL_PROJECTION_MATRIX, proj ); glGetDoublev( GL_MODELVIEW_MATRIX, modl ); glGetIntegerv( GL_VIEWPORT, vp ); gluProject (0, 0, 0, modl, proj, vp, &sunx, &suny, &sunz); if ((sunx>=vp[0])&&(suny>=vp[1])&&(sunx<(vp[0]+vp[2]))&&(suny<(vp[1]+vp[3]))) sunvisible = true; glDisable (GL_ALPHA_TEST); glEnable (GL_DEPTH_TEST); glDisable (GL_TEXTURE_2D); gl->disableAlphaBlending (); } } glPopMatrix (); glPushMatrix (); if (camera != 1 && camera != 5) glRotatef (-mycamtheta, 0.0, 0.0, 1.0); glRotatef (mycamgamma, 1.0, 0.0, 0.0); glDisable (GL_FOG); glRotatef (-mycamphi, 0.0, 1.0, 0.0); glScalef (1, 1, 1); glTranslatef (-camx, -camy, -camz); if (camera != 50) { gl->enableFog (pseudoview); } // draw terrain l->calcDynamicLight (explosion, laser, (DynamicObj **) missile, flare); glEnable (GL_CULL_FACE); glCullFace (GL_FRONT); l->draw ((int) mycamphi, (int) (-mycamgamma + 180.0)); glDisable (GL_CULL_FACE); // draw objects gl->extractFrustum (); if (camera != 50) { space->lum = sunlight; float dayfac = 1.0; if (!day) dayfac = 0.5; if (weather == WEATHER_SUNNY || weather == WEATHER_CLOUDY) { for (i = 0; i < space->no; i ++) { if (space->o [i]->tl->y < l->getExactRayHeight (space->o [i]->tl->x, space->o [i]->tl->z)) space->o [i]->lum = 0.5 * dayfac; else space->o [i]->lum = 1.0 * dayfac; } } else { for (i = 0; i < space->no; i ++) space->o [i]->lum = dayfac; } // printf ("%2.1f*%2.1f ", fplayer->lum, sunlight); if (flash > 7 * timestep) { if (antialiasing) flash1->draw (); else flash1->drawHQ (); } if (lighting) { glEnable( GL_LIGHTING); glEnable( GL_LIGHT0 ); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); space->drawGL (); // draw all objects glDisable (GL_LIGHTING); glDepthMask (GL_FALSE); for (i = 0; i < space->no; i ++) { AIObj *dobj = (AIObj *) space->o [i]; if (dobj->id >= MISSILE1) if (dobj->draw && dobj->drawlight && dobj->active) { if (dobj->smoke) if ((dobj->id >= MISSILE1 && dobj->id <= MISSILE2) || (dobj->id >= FIGHTER1 && dobj->id <= FIGHTER2)) if (!(dobj->ttl == 0 && dobj->id >= MISSILE1 && dobj->id <= MISSILE2)) { dobj->smoke->draw (); } } } glDepthMask (GL_TRUE); } else { space->drawGL (); } } glDisable (GL_TEXTURE_2D); glDisable (GL_LIGHTING); if (camera == 0) { glDisable (GL_DEPTH_TEST); if (antialiasing) glEnable (GL_LINE_SMOOTH); cockpit->drawTargeter (); if (antialiasing) glDisable (GL_LINE_SMOOTH); glEnable (GL_DEPTH_TEST); } glPopMatrix (); // draw flares if (specialeffects) if (sunvisible && /*camera == 0 &&*/ sunblinding && day) { CTexture* fl_texture[]= {texflare1,texflare3,texflare2,texflare4,texflare2,texflare4,texflare3,0}; double fl_position[]= {0.2, 1.6, 3.2, 8.1, -1.4, -2.2, -3.5, 0}; double fl_size[]= {0.8, 0.6, 0.5, 0.4, 0.8, 0.4, 0.5, 0}; double proj[16]; double modl[16]; double dr[2]; int vp[4]; double objx,objy,objz; glGetDoublev( GL_PROJECTION_MATRIX, proj ); glGetDoublev( GL_MODELVIEW_MATRIX, modl ); glGetIntegerv( GL_VIEWPORT, vp ); glGetDoublev( GL_DEPTH_RANGE, dr ); double cx=vp[2]/2+vp[0]; double cy=vp[3]/2+vp[1]; glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); int i=0; double flarez_eye=4; double flarez_win=(-proj[10]+proj[14]/flarez_eye)*(dr[1]-dr[0])/2+(dr[1]+dr[0])/2; while (CTexture *tex=fl_texture[i]) { double position=fl_position[i]; double flarex,flarey,size=fl_size[i]/GLOBALSCALE; i++; flarex=(cx-sunx)*position+sunx; flarey=(cy-suny)*position+suny; if (gluUnProject (flarex, flarey, flarez_win, modl, proj, vp, &objx, &objy, &objz)==GL_TRUE) { gl->enableTextures (tex->textureID); gl->enableAlphaBlending (); glDisable (GL_ALPHA_TEST); glDisable (GL_DEPTH_TEST); glDisable (GL_FOG); glBegin (GL_QUADS); glColor4f (1.0, 1.0, 1.0, 1.0); glTexCoord2d (0, 1); glVertex3f (-size+objx, size+objy, objz); glTexCoord2d (1, 1); glVertex3f (size+objx, size+objy, objz); glTexCoord2d (1, 0); glVertex3f (size+objx, -size+objy, objz); glTexCoord2d (0, 0); glVertex3f (-size+objx, -size+objy, objz); glEnd (); } } glEnable (GL_DEPTH_TEST); glDisable (GL_TEXTURE_2D); gl->disableAlphaBlending (); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } // sunblinding test if (sunvisible) { GLfloat zbuf[1]; glReadPixels((int)sunx,(int)suny,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,zbuf); sunblinding=(zbuf[0]<1)?false:true; } else { sunblinding=false; } // draw cockpit if (camera == 0) { if (antialiasing) glEnable (GL_LINE_SMOOTH); glPushMatrix (); glRotatef (view_y, 1, 0, 0); glRotatef (-view_x, 0, 1, 0); cockpit->drawCross (); cockpit->drawHeading (); glPopMatrix (); if (antialiasing) glDisable (GL_LINE_SMOOTH); cockpit->drawRadar (); cockpit->drawTargetedElement (); cockpit->drawWeapon (); cockpit->drawCounter (); cockpit->drawThrustBar (); cockpit->drawRelativeHeightBar (); } // draw blackout/redout (blending) if (camera == 0) { int black = (int) blackout; if (black > 255) black = 255; int red = (int) redout; if (red > 255) red = 255; float xf = 2.0, yf = 1.5, zf = 1.0; if (black > 0) { glColor4ub (0, 0, 0, black); } else if (red > 0) { glColor4ub (255, 0, 0, red); } if (black > 0 || red > 0) { glDisable (GL_DEPTH_TEST); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin (GL_QUADS); glVertex3f (-xf, -yf, -zf); glVertex3f (-xf, yf, -zf); glVertex3f (xf, yf, -zf); glVertex3f (xf, -yf, -zf); glEnd (); gl->disableAlphaBlending (); glDisable (GL_BLEND); glEnable (GL_DEPTH_TEST); } } if (brightness) { adjustBrightness (); glEnable (GL_DEPTH_TEST); } // draw mission dependant informations mission->draw (); glPushMatrix (); glDisable (GL_DEPTH_TEST); glPopMatrix (); char buf [25]; sprintf (buf, "FPS: %d", (int) fps); font1->drawText (-25, 25, -3.5, buf, &colorwhite); bool write = false; if (firststart) { int akttime; #ifndef USE_GLUT akttime = SDL_GetTicks (); #else akttime = glutGet (GLUT_ELAPSED_TIME); #endif if (akttime - starttime < 20000) if ((akttime - starttime) / 300 % 3) { font1->drawTextCentered (0, 0, -1.8, "PLEASE WAIT WHILE", &colorred); font1->drawTextCentered (0, -1, -1.8, "ADJUSTING QUALITY", &colorred); write = true; } } if (fps >= 5 && fps <= 20 && !write) { font1->drawTextCentered (0, -8, -2, "FPS TOO LOW", &colorred); font1->drawTextCentered (0, -9, -2, "TURN DOWN VIEW OR QUALITY", &colorred); } if (fps < 5 && !write) { font1->drawTextCentered (0, -8, -2, "FPS FAR TOO LOW", &colorred); font1->drawTextCentered (0, -9, -2, "SEE \"README\" OR \"FAQ\" FILES", &colorred); font1->drawTextCentered (0, -10, -2, "HIT \"ESC\" AND 'Y' TO EXIT THE GAME", &colorred); } if (controls == CONTROLS_MOUSE && !mouse_relative) drawMouseCursor (); } /**************************************************************************** TIMER EVENTS ****************************************************************************/ float lastthrust; int gametimer; void game_timer (int dt) { // if (multiplayer) return; int i, i2; sunlight += (sunlight_dest - sunlight) / 10 * dt / timestep; gametimer += dt; cockpit->dt = dt; l->lsticker += dt; if (l->lsticker >= 36000000) l->lsticker = 0; if (vibration > 0) { vibration -= dt; } if (fplayer->autofire && fplayer->active) { if (fplayer->ammo != 0) { fplayer->fireCannon (laser); #ifdef HAVE_SDL_MIXER if (!startcannon) { sound->playLoop (SOUND_CANNON1); startcannon = true; } #else sound->play (SOUND_CANNON1, 1); #endif } } #ifdef HAVE_SDL_MIXER else { if (startcannon) { startcannon = false; sound->stop (SOUND_CANNON1); } } #endif if (lastshield > fplayer->shield && !fplayer->ai) { sound->play (SOUND_HIT1, false); lastshield = (int) fplayer->shield; vibration = 25 * timestep; } // create flash during thunderstorm if (weather == WEATHER_THUNDERSTORM && flash <= 0 && !myrandom (2000 / dt)) { flash = 18 * timestep; int fphi = (int) camphi + myrandom (50) - 25; if (fphi < 0) fphi += 360; else if (fphi >= 360) fphi -= 360; float pseudoview = getView (); float fdist = myrandom ((int) pseudoview - 20) + 10; float fx = fplayer->tl->x - sine [fphi] * fdist; float fz = fplayer->tl->z - cosi [fphi] * fdist; flash1->set (fx, l->getHeight (fx, fz), fz, (int) camphi); int lev = (int) (128.0 - 80.0 * fdist / (pseudoview - 10)); sound->setVolume (SOUND_THUNDER1, lev); sound->play (SOUND_THUNDER1, false); } if (initing) return; if (flash > 0) flash -= dt; if (flash <= 7 * timestep && flash > 0) flash -= dt; if (!fplayer->ai) if (sound->engine != (int) ((fplayer->thrust / fplayer->maxthrust * 20) - 10)) { setPlaneVolume (); lastthrust = fplayer->thrust; } // collision tests for (i = 0; i < maxfighter; i ++) { for (i2 = 0; i2 < maxlaser; i2 ++) if (laser [i2]->active) fighter [i]->collide (laser [i2], dt); for (i2 = 0; i2 < maxmissile; i2 ++) if (missile [i2]->active) fighter [i]->collide (missile [i2], dt); for (i2 = 0; i2 < i; i2 ++) if (fighter [i2]->active) if (i != i2) fighter [i]->collide (fighter [i2], dt); } for (i = 0; i < maxflare; i ++) { for (i2 = 0; i2 < maxmissile; i2 ++) if (missile [i2]->active) flare [i]->collide (missile [i2], dt); } for (i = 0; i < maxchaff; i ++) { for (i2 = 0; i2 < maxmissile; i2 ++) if (missile [i2]->active) chaff [i]->collide (missile [i2], dt); } // move objects for (i = 0; i < maxfighter; i ++) { fighter [i]->aiAction (dt, (AIObj **) fighter, missile, laser, flare, chaff); float lev; if (fighter [i]->explode == 1 && (lev = fplayer->distance (fighter [i])) < 32) { sound->setVolume (SOUND_EXPLOSION1, 128); float angle = fplayer->getAngle (fighter [i]); angle = 180 - angle; sound->setPosition (SOUND_EXPLOSION1, (int) angle, (int) (lev * 4.0)); sound->play (SOUND_EXPLOSION1, false); } } for (i = 0; i < maxlaser; i ++) { laser [i]->move (dt); } for (i = 0; i < maxmissile; i ++) { missile [i]->aiAction (dt, (AIObj **) fighter, missile, laser, flare, chaff); } for (i = 0; i < maxflare; i ++) { flare [i]->move (dt); } for (i = 0; i < maxchaff; i ++) { chaff [i]->move (dt); } for (i = 0; i < maxexplosion; i ++) explosion [i]->move (dt); for (i = 0; i < maxblacksmoke; i ++) blacksmoke [i]->move (dt); // show blackout/redout if (blackout > 0) blackout -= 3.0F * dt / timestep; if (blackout < 0) blackout = 0; if (redout > 0) redout -= 3.0F * dt / timestep; if (redout < 0) redout = 0; if (blackout > 400) blackout = 400; if (redout > 400) redout = 400; float testout; if (redout < 1) { testout = (fplayer->realspeed * fplayer->elevatoreffect - 0.13F) * 40.0F; if (testout > 0) blackout += testout * dt / timestep; } if (blackout < 1) { testout = (fplayer->realspeed * fplayer->elevatoreffect + 0.065F) * 80.0F; if (testout < 0) redout -= testout * dt / timestep; } // show own explosion from chase cam if (fplayer->shield <= 0) camera = 1; float cf = -fplayer->zoom / 2; camtheta = fplayer->theta; if (camera == 0) // cockpit { float cgamma = fplayer->gamma + 25.0F * COS(fplayer->theta); float cphi = fplayer->phi + 25.0F * SIN(fplayer->theta); float fac = fplayer->zoom / 2; camx = fplayer->tl->x + COS(cgamma) * SIN(cphi) * fac; camy = fplayer->tl->y - SIN(cgamma) * fac; camz = fplayer->tl->z + COS(cgamma) * COS(cphi) * fac; camphi = fplayer->phi; camgamma = -fplayer->gamma + 180; fplayer->draw = 0; } if (camera == 1) // chase { cf = fplayer->zoom * 3; camx = fplayer->tl->x + cf * SIN(fplayer->phi); camy = fplayer->tl->y + fplayer->zoom; camz = fplayer->tl->z + cf * COS(fplayer->phi); camphi = fplayer->phi; fplayer->draw = 1; camgamma = 20; } else if (camera == 2) // backwards { cf = -fplayer->zoom * 3; camx = fplayer->tl->x + cf * SIN(fplayer->phi); camy = fplayer->tl->y + fplayer->zoom; camz = fplayer->tl->z + cf * COS(fplayer->phi); camphi = fplayer->phi + 180.0; fplayer->draw = 1; camgamma = 20; } else if (camera == 3) // other players { cf = fighter [aktcam]->zoom * 3; camx = fighter [aktcam]->tl->x + cf * SIN(fighter [aktcam]->phi); camy = fighter [aktcam]->tl->y + fighter [aktcam]->zoom; camz = fighter [aktcam]->tl->z + cf * COS(fighter [aktcam]->phi); camphi = fighter [aktcam]->phi; camgamma = 20; camtheta = fighter [aktcam]->theta; fplayer->draw = 1; } else if (camera == 4) // missile { cf = missile [0]->zoom * 10; camx = missile [0]->tl->x + cf * SIN(missile [0]->phi); camy = missile [0]->tl->y + fplayer->zoom * 2; camz = missile [0]->tl->z + cf * COS(missile [0]->phi); camphi = missile [0]->phi; fplayer->draw = 1; } else if (camera == 5) // top { cf = fplayer->zoom * 15; camx = fplayer->tl->x + cf * SIN(fplayer->phi); camy = fplayer->tl->y + 5.5; camz = fplayer->tl->z + cf * COS(fplayer->phi); camphi = fplayer->phi; fplayer->draw = 1; camgamma = 50; } else if (camera == 6) // left { cf = fplayer->zoom * 2; camphi = fplayer->phi + 90.0; if (camphi >= 360) camphi -= 360; else if (camphi < 0) camphi += 360; camx = fplayer->tl->x + cf * SIN(camphi); camy = fplayer->tl->y + fplayer->zoom; camz = fplayer->tl->z + cf * COS(camphi); fplayer->draw = 1; camgamma = 20; } else if (camera == 7) // right { cf = fplayer->zoom * 2; camphi = fplayer->phi + 270.0; if (camphi >= 360) camphi -= 360; else if (camphi < 0) camphi += 360; camx = fplayer->tl->x + cf * SIN(camphi); camy = fplayer->tl->y + fplayer->zoom; camz = fplayer->tl->z + cf * COS(camphi); fplayer->draw = 1; camgamma = 20; } else if (camera == 8) // top near { cf = fplayer->zoom * 5; camx = fplayer->tl->x + cf * SIN(fplayer->phi); camy = fplayer->tl->y + 2.5; camz = fplayer->tl->z + cf * COS(fplayer->phi); camphi = fplayer->phi; fplayer->draw = 1; camgamma = 50; } else if (camera == 9) // top very near { cf = fplayer->zoom * 2; camx = fplayer->tl->x + cf * SIN(fplayer->phi); camy = fplayer->tl->y + 1.0; camz = fplayer->tl->z + cf * COS(fplayer->phi); camphi = fplayer->phi; fplayer->draw = 1; camgamma = 50; } else if (camera == 50) { camx = 20; camz = 80; camy = 250; camphi = 20; camgamma = 75; game = GAME_PAUSE; } if (camphi >= 360.0) camphi -= 360.0; #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif fplayer->rectheta -= dtheta; fplayer->recgamma += dgamma; missionstate = mission->processtimer (dt); if (missionstate == 2) { missionending ++; if (missionending >= 25) { missionending = 0; fplayer->score = mission->getScore (missionstate); if (!mission->id == MISSION_DEMO) { switch_stats (); } else { pleaseWait (); createMission (MISSION_DEMO); game_levelInit (); } } } if (missionstate == 1) { missionending ++; if (missionending >= 25) { missionending = 0; fplayer->score = mission->getScore (missionstate); if (mission->id != MISSION_DEMO) { if (mission->id != MISSION_MOON3) switch_stats (); else switch_finish (); } else { pleaseWait (); createMission (MISSION_DEMO); game_levelInit (); } } } if (controls == CONTROLS_KEYBOARD) { float fac = 0.005; if (keyb_elev == 0) fplayer->elevatoreffect = 0; else fplayer->elevatoreffect += (float) dt * keyb_elev * fac; if (keyb_roll == 0) fplayer->rolleffect = 0; else fplayer->rolleffect += (float) dt * keyb_roll * fac; if (keyb_rudder == 0) fplayer->ruddereffect = 0; else fplayer->ruddereffect += (float) dt * keyb_rudder * fac; if (fplayer->elevatoreffect > 1.0) fplayer->elevatoreffect = 1.0; if (fplayer->elevatoreffect < -0.5) fplayer->elevatoreffect = -0.5; if (fplayer->rolleffect > 1.0) fplayer->rolleffect = 1.0; if (fplayer->rolleffect < -1.0) fplayer->rolleffect = -1.0; if (fplayer->ruddereffect > 1.0) fplayer->ruddereffect = 1.0; if (fplayer->ruddereffect < -1.0) fplayer->ruddereffect = -1.0; } } float lastfps = -1; int newcamera = 0; void menu_timer (Uint32 dt) { char buf [256]; menutimer += dt; int cycle = (menutimer / timestep) % 256; if (cycle == 0) { newcamera = 0; } if (cycle == 200 && !newcamera) { newcamera = 1; if (camera == 5) { camera = 1; if (missile [0]->active) camera = 4; } else if (camera == 1 || camera == 4) camera = 2; else if (camera == 2) camera = 5; } int akttime; #ifndef USE_GLUT akttime = SDL_GetTicks (); #else akttime = glutGet (GLUT_ELAPSED_TIME); #endif if (firststart) if (akttime - starttime < 20000) { if (lastfps != fps) { lastfps = fps; if (fps > 40) { if (view < quality * 20 + 60 && view < 100) view += 20; else if (quality < 5) { quality ++; view = quality * 20 + 30; if (quality >= 1) { antialiasing = 1; specialeffects = 1; dithering = 1; dynamiclighting = 0; } } sprintf (buf, "%d", (int) quality); ((Label *) optmenu [0]->components [1])->setText (buf); sprintf (buf, "%d", (int) view); ((Label *) optmenu [0]->components [3])->setText (buf); } else if (fps < 30) { if (view > quality * 20 + 30 && view > 20) view -= 20; else if (quality > 0) { quality --; view = quality * 20 + 60; if (quality < 1) { antialiasing = 0; specialeffects = 0; dithering = 0; dynamiclighting = 0; } } sprintf (buf, "%d", (int) quality); ((Label *) optmenu [0]->components [1])->setText (buf); sprintf (buf, "%d", (int) view); ((Label *) optmenu [0]->components [3])->setText (buf); } menu_reshape (); } } #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } void stats_timer (Uint32 dt) { menutimer += dt; #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } void mission_timer (Uint32 dt) { missionmenutimer += dt; #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } void credits_timer (Uint32 dt) { creditstimer += dt; #ifdef SHOW_SOFTWARE_PATENTS if (creditstimer > 2500 * timestep) creditstimer = 0; #else if (creditstimer > 700 * timestep) creditstimer = 0; #endif #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } void finish_timer (Uint32 dt) { finishtimer += dt; if (finishtimer > 800 * timestep) finishtimer = 0; #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } void create_timer (Uint32 dt) { #ifndef USE_GLUT // server->createSocketSet (); server->getClient (); SDL_Delay (100); mission_timer (dt); #endif } void join_timer (Uint32 dt) { #ifdef HAVE_SDL_NET #ifndef USE_GLUT char buf [STDSIZE]; if (client->sock == NULL) client->getServer ("127.0.0.1", "client1"); else { SDL_Delay (100); mission_timer (dt); client->getMessage (buf); if (buf [0] == 's') { createMission (MISSION_MULTIPLAYER_DOGFIGHT); game_levelInit (); switch_game (); missionactive = true; } } #endif #endif } /**************************************************************************** GAME DATA INITIALIZATION ****************************************************************************/ // calculate missile rack positions for a fighter void setMissiles (CModel *model) { int i; CVector3 tlmissile (0, 0.3, 0.3); for (i = 0; i < model->numObjects; i ++) { if (model->object [i]->numVertices == 4) { CObject *o = model->object [i]; float sumx = 0, sumz = 0; float maxy = 2; int i2; for (i2 = 0; i2 < o->numVertices; i2 ++) { sumx += o->vertex [i2].vector.x; if (o->vertex [i2].vector.y < maxy) maxy = o->vertex [i2].vector.y; sumz += o->vertex [i2].vector.z; } tlmissile.x = sumx / 4.0F; tlmissile.y = maxy; tlmissile.z = sumz / 4.0F; tlmissile.y = maxy; model->addRefPoint (&tlmissile); } } } // initialize game data void myInit () { int i, i2; // useful global variables/constants tlinf = new CVector3 (1E10, 1E10, 1E10); tlminf = new CVector3 (-1E10, -1E10, -1E10); tlnull = new CVector3 (0, 0, 0); rotnull = new CRotation (); rotmissile = new CRotation (); rotmissile->a = 90; rotmissile->c = 270; // initialize all global variables for (i = 0; i < maxgroundobj; i ++) { groundobj [i] = new DynamicObj (space, &model_tent1, 3); } explsphere = new CSphere (); ((CSphere *) explsphere)->init (1, 9); CColor explcolor (255, 255, 1); explsphere->setColor (&explcolor); explsphere->alpha = true; for (i = 0; i < explsphere->object [0]->numVertices; i ++) { explsphere->object [0]->vertex [i].color.setColor (myrandom (100) + 155, myrandom (100) + 100, 0, myrandom (3) / 2 * 255); } for (i = 0; i < maxexplosion; i ++) { explosion [i] = new CExplosion (space, explsphere); } for (i = 0; i < maxblacksmoke; i ++) { blacksmoke [i] = new CBlackSmoke (space); } for (i = 0; i < maxfighter; i ++) { fighter [i] = new AIObj (space, &model_fig, 0.4); for (i2 = 0; i2 < 12; i2 ++) fighter [i]->addRefModel (&model_missile1, tlnull, rotmissile, 0.2); } highclouds = new HighClouds (25); highclouds->setTexture (texclouds3); highclouds2 = new HighClouds (25); highclouds2->setTexture (texclouds3); objsphere = new CSphere (1, 9, 1, 1, 1); sphere = new CSpaceObj (objsphere, 10.0); sphere->rot->a = 90; sphere->rot->b = 90; sphere->rot->c = 270; sphere->draw = 2; sphere->drawlight = false; flash1 = new Flash (); for (i = 0; i < maxlaser; i ++) { laser [i] = new DynamicObj (space, &model_cannon1, 0.07); } for (i = 0; i < maxmissile; i ++) { missile [i] = new AIObj (space, &model_missile1, 0.1); } for (i = 0; i < maxflare; i ++) { flare [i] = new DynamicObj (space, &model_flare1, 0.1); } for (i = 0; i < maxchaff; i ++) { chaff [i] = new DynamicObj (space, &model_chaff1, 0.1); } for (i = 0; i < maxstar; i ++) { star [i] = new Star (myrandom (360), myrandom (85), 0.4 + 0.1 * myrandom (8)); } cockpit = new Cockpit (); pleaseWait (); createMission (MISSION_DEMO); game_levelInit (); menu_reshape (); } /**************************************************************************** INTRO ****************************************************************************/ CRotation rot; CRotation rot2; CVector3 tl; CVector3 tl2; int initexplode = 0; int initexplode1 = 0; int i; int inittimer = 0; int inittimer_gl117 = 0; void init_reshape () { // use whole window glViewport (0, 0, (GLint) width, (GLint) height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); // angle, aspectratio, nearclip, farclip gluPerspective (visibleangle, 1.0, nearclippingplane, 80); glPolygonMode (GL_FRONT_AND_BACK, polygonMode); } // load game data (this method does not really belong to the intro itself) void myFirstInit () { display ("Creating calculation tables", LOG_ALL); mathtab_init (); display ("Creating advanced OpenGL methods", LOG_ALL); gl = new GL (); // create textures (OpenGL) display ("Loading textures", LOG_ALL); texgrass = gl->genTextureTGA (dirs->getTextures ("grass1.tga"), 0, 0, 1, false); texrocks = gl->genTextureTGA (dirs->getTextures ("rocks1.tga"), 0, 0, 1, false); texwater = gl->genTextureTGA (dirs->getTextures ("water1.tga"), 0, 0, 1, false); texsand = gl->genTextureTGA (dirs->getTextures ("sand1.tga"), 0, 0, 1, false); texredsand = gl->genTextureTGA (dirs->getTextures ("redsand1.tga"), 0, 0, 1, false); texredstone = gl->genTextureTGA (dirs->getTextures ("redstone2.tga"), 0, 0, 1, false); texgravel1 = gl->genTextureTGA (dirs->getTextures ("gravel1.tga"), 0, 0, 1, false); texglitter1 = gl->genTextureTGA (dirs->getTextures ("glitter.tga"), 0, -1, 0, true); textree = gl->genTextureTGA (dirs->getTextures ("tree1.tga"), 0, -1, 1, true); textreeu = gl->genTextureTGA (dirs->getTextures ("treeu1.tga"), 0, -1, 1, true); textree2 = gl->genTextureTGA (dirs->getTextures ("tree2.tga"), 0, -1, 1, true); textreeu2 = gl->genTextureTGA (dirs->getTextures ("treeu2.tga"), 0, -1, 1, true); textree3 = gl->genTextureTGA (dirs->getTextures ("tree3.tga"), 0, 3, 1, true); textreeu3 = gl->genTextureTGA (dirs->getTextures ("treeu3.tga"), 0, 3, 1, true); textree4 = gl->genTextureTGA (dirs->getTextures ("tree4.tga"), 0, 3, 1, true); textreeu4 = gl->genTextureTGA (dirs->getTextures ("treeu4.tga"), 0, 3, 1, true); textree5 = gl->genTextureTGA (dirs->getTextures ("tree5.tga"), 0, -1, 1, true); textreeu5 = gl->genTextureTGA (dirs->getTextures ("treeu5.tga"), 0, -1, 1, true); texcactus1 = gl->genTextureTGA (dirs->getTextures ("cactus1.tga"), 0, 3, 1, true); texcactusu1 = gl->genTextureTGA (dirs->getTextures ("cactusu1.tga"), 0, 3, 1, true); texsmoke = gl->genTextureTGA (dirs->getTextures ("smoke1.tga"), 0, -1, 1, true); texsmoke2 = gl->genTextureTGA (dirs->getTextures ("smoke2.tga"), 0, -1, 1, true); texsmoke3 = gl->genTextureTGA (dirs->getTextures ("smoke3.tga"), 0, 5, 1, true); texsun = gl->genTextureTGA (dirs->getTextures ("sun2.tga"), 1, -1, 0, true); texmoon = gl->genTextureTGA (dirs->getTextures ("moon1.tga"), 1, 2, 0, true); texearth = gl->genTextureTGA (dirs->getTextures ("earth.tga"), 1, 0, 0, true); texflare1 = gl->genTextureTGA (dirs->getTextures ("flare1.tga"), 1, -1, 0, true); texflare2 = gl->genTextureTGA (dirs->getTextures ("flare2.tga"), 1, -1, 0, true); texflare3 = gl->genTextureTGA (dirs->getTextures ("flare3.tga"), 1, -1, 0, true); texflare4 = gl->genTextureTGA (dirs->getTextures ("flare4.tga"), 1, -1, 0, true); texcross = gl->genTextureTGA (dirs->getTextures ("cross.tga"), 0, -1, 1, true); texcross2 = gl->genTextureTGA (dirs->getTextures ("cross2.tga"), 0, -1, 1, true); texranks = gl->genTextureTGA (dirs->getTextures ("ranks.tga"), 0, 0, 0, true); texmedals = gl->genTextureTGA (dirs->getTextures ("medals.tga"), 0, 0, 0, true); texclouds1 = gl->genTextureTGA (dirs->getTextures ("clouds1.tga"), 0, -1, 1, true); texclouds2 = gl->genTextureTGA (dirs->getTextures ("clouds2.tga"), 0, 4, 1, true); texclouds3 = gl->genTextureTGA (dirs->getTextures ("clouds3.tga"), 0, 6, 1, true); texradar1 = gl->genTextureTGA (dirs->getTextures ("radar2.tga"), 0, -1, 0, true); texradar2 = gl->genTextureTGA (dirs->getTextures ("radar1.tga"), 0, -1, 0, true); texarrow = gl->genTextureTGA (dirs->getTextures ("arrow.tga"), 0, -1, 0, true); display ("Loading Fonts", LOG_ALL); font1 = new Font (dirs->getTextures ("font1.tga"), 32, '!', 64); // font1 = new Font (dirs->getTextures ("font3.tga"), 37, '!', 100); font2 = new Font (dirs->getTextures ("font2.tga"), 32, '!', 64); display ("Loading 3ds models:", LOG_ALL); display (" * gl-16.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_fig, dirs->getModels ("gl-16.3ds")); model_fig.setName ("FALCON"); display (" * gl-15.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figa, dirs->getModels ("gl-15.3ds")); model_figa.setName ("SWALLOW"); display (" * gl-14c.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figb, dirs->getModels ("gl-14c.3ds")); model_figb.setName ("HAWK"); display (" * gl-14d.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figc, dirs->getModels ("gl-14d.3ds")); model_figc.setName ("HAWK II"); display (" * gl-21b.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figd, dirs->getModels ("gl-21b.3ds")); model_figd.setName ("BUZZARD"); display (" * gl-21.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_fige, dirs->getModels ("gl-21.3ds")); model_fige.setName ("CROW"); display (" * gl-14b.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figf, dirs->getModels ("gl-14b.3ds")); model_figf.setName ("PHOENIX"); display (" * gl-14.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figg, dirs->getModels ("gl-14.3ds")); model_figg.setName ("RED ARROW"); display (" * gl-29.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figh, dirs->getModels ("gl-29.3ds")); model_figh.setName ("BLACKBIRD"); model_figh.scaleTexture (0.3, 0.3); display (" * gl-50.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figi, dirs->getModels ("gl-50.3ds")); model_figi.setName ("STORM"); display (" * transp2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figt, dirs->getModels ("transp2.3ds")); model_figt.setName ("TRANSPORT"); display (" * transp4.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_figu, dirs->getModels ("transp4.3ds")); model_figu.setName ("TRANSPORT"); // cannon at daylight float cannoncube = 0.025; display (" * cannon1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_cannon1, dirs->getModels ("cannon1.3ds")); model_cannon1.cubex = cannoncube; model_cannon1.cubey = cannoncube; model_cannon1.cubez = cannoncube; display (" * cannon1b.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_cannon1b, dirs->getModels ("cannon1b.3ds")); model_cannon1b.cubex = cannoncube; model_cannon1b.cubey = cannoncube; model_cannon1b.cubez = cannoncube; // cannon at night display (" * cannon2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_cannon2, dirs->getModels ("cannon2.3ds")); model_cannon2.nolight = true; model_cannon2.alpha = true; for (i = 0; i < 4; i ++) { model_cannon2.object [0]->vertex [i].color.c [0] = 255; model_cannon2.object [0]->vertex [i].color.c [1] = 255; model_cannon2.object [0]->vertex [i].color.c [2] = 0; model_cannon2.object [0]->vertex [i].color.c [3] = 255; } model_cannon2.object [0]->vertex [1].color.c [3] = 50; model_cannon2.object [0]->vertex [2].color.c [3] = 50; model_cannon2.cubex = cannoncube; model_cannon2.cubey = cannoncube; model_cannon2.cubez = cannoncube; display (" * cannon2b.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_cannon2b, dirs->getModels ("cannon2b.3ds")); model_cannon2b.nolight = true; model_cannon2b.alpha = true; for (int i2 = 0; i2 < 2; i2 ++) { for (i = 0; i < 4; i ++) { model_cannon2b.object [i2]->vertex [i].color.c [0] = 255; model_cannon2b.object [i2]->vertex [i].color.c [1] = 255; model_cannon2b.object [i2]->vertex [i].color.c [2] = 0; model_cannon2b.object [i2]->vertex [i].color.c [3] = 255; } model_cannon2b.object [i2]->vertex [1].color.c [3] = 50; model_cannon2b.object [i2]->vertex [2].color.c [3] = 50; } model_cannon2b.cubex = cannoncube; model_cannon2b.cubey = cannoncube; model_cannon2b.cubez = cannoncube; display (" * flare1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_flare1, dirs->getModels ("flare1.3ds")); model_flare1.setName ("FLARE"); model_flare1.alpha = true; model_flare1.nolight = true; display (" * chaff1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_chaff1, dirs->getModels ("chaff1.3ds")); model_chaff1.setName ("CHAFF"); model_chaff1.alpha = true; model_chaff1.nolight = true; display (" * missile1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile1, dirs->getModels ("missile1.3ds")); model_missile1.setName ("AAM HS MK1"); display (" * missile2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile2, dirs->getModels ("missile2.3ds")); model_missile2.setName ("AAM HS MK2"); display (" * missile3.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile3, dirs->getModels ("missile3.3ds")); model_missile3.setName ("AAM HS MK3"); display (" * missile4.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile4, dirs->getModels ("missile4.3ds")); model_missile4.setName ("AGM MK1"); display (" * missile5.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile5, dirs->getModels ("missile5.3ds")); model_missile5.setName ("AGM MK2"); display (" * missile6.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile6, dirs->getModels ("missile6.3ds")); model_missile6.setName ("DFM"); display (" * missile7.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile7, dirs->getModels ("missile7.3ds")); model_missile7.setName ("AAM FF MK1"); display (" * missile8.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_missile8, dirs->getModels ("missile8.3ds")); model_missile8.setName ("AAM FF MK2"); display (" * flak2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_flak1, dirs->getModels ("flak2.3ds")); model_flak1.setName ("SA CANNON"); display (" * flarak1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_flarak1, dirs->getModels ("flarak1.3ds")); model_flarak1.setName ("SAM"); display (" * ship1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_ship1, dirs->getModels ("ship1.3ds")); model_ship1.setName ("CRUISER"); display (" * tent1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_tent1, dirs->getModels ("tent1.3ds")); model_tent1.setName ("TENT"); display (" * gl-117.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_gl117, dirs->getModels ("gl-117.3ds")); model_gl117.displaylist = false; display (" * tank1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_tank1, dirs->getModels ("tank1.3ds")); model_tank1.setName ("WIESEL"); model_tank1.scaleTexture (0.5, 0.5); display (" * container1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_container1, dirs->getModels ("container1.3ds")); model_container1.setName ("CONTAINER"); display (" * ship2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_ship2, dirs->getModels ("ship2.3ds")); model_ship2.setName ("LIGHT DESTROYER"); display (" * truck1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_truck1, dirs->getModels ("truck1.3ds")); model_truck1.setName ("TRUCK"); display (" * truck2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_truck2, dirs->getModels ("truck2.3ds")); model_truck2.setName ("TRUCK"); display (" * trsam.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_trsam, dirs->getModels ("trsam.3ds")); model_trsam.setName ("MOBILE SAM"); display (" * pickup1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_pickup1, dirs->getModels ("pickup1.3ds")); model_pickup1.setName ("PICKUP"); display (" * pickup2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_pickup2, dirs->getModels ("pickup2.3ds")); model_pickup2.setName ("PICKUP"); display (" * tank2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_tank2, dirs->getModels ("tank2.3ds")); model_tank2.setName ("PANTHER"); model_tank2.scaleTexture (0.5, 0.5); display (" * tent4.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_tent4, dirs->getModels ("tent4.3ds")); model_tent4.setName ("BIG TENT"); display (" * hall1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_hall1, dirs->getModels ("hall1.3ds")); model_hall1.setName ("HALL"); display (" * hall2.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_hall2, dirs->getModels ("hall2.3ds")); model_hall2.setName ("HALL"); display (" * oilrig.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_oilrig, dirs->getModels ("oilrig.3ds")); model_oilrig.setName ("OILRIG"); model_oilrig.alpha = true; display (" * egg.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_egg, dirs->getModels ("egg.3ds")); model_egg.scaleTexture (0.08, 0.08); model_egg.setName ("COMPLEX"); display (" * radar.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_radar, dirs->getModels ("radar.3ds")); model_radar.setName ("RADAR"); display (" * mine1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_mine1, dirs->getModels ("mine1.3ds")); model_mine1.setName ("MINE"); display (" * aster1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_aster1, dirs->getModels ("aster1.3ds")); model_aster1.setName ("ASTEROID"); display (" * base1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_base1, dirs->getModels ("base1.3ds")); model_base1.setName ("MOON BASE"); display (" * barrier.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_barrier1, dirs->getModels ("barrier.3ds")); model_barrier1.setName ("MOON BASE"); model_barrier1.scaleTexture (10, 10); model_barrier1.alpha = true; display (" * rubble.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_rubble1, dirs->getModels ("rubble.3ds")); model_base1.setName ("RUBBLE"); display (" * depot1.3ds", LOG_ALL); g_Load3ds.Import3DS (&model_depot1, dirs->getModels ("depot1.3ds")); model_depot1.setName ("DEPOT"); model_depot1.scaleTexture (2, 2); g_Load3ds.Import3DS (&model_house1, dirs->getModels ("house1.3ds")); model_house1.setName ("HOUSE"); setMissiles (&model_fig); setMissiles (&model_figa); setMissiles (&model_figb); setMissiles (&model_figc); setMissiles (&model_figd); setMissiles (&model_fige); setMissiles (&model_figf); setMissiles (&model_figg); setMissiles (&model_figh); setMissiles (&model_figi); // enable Z-Buffer glEnable (GL_DEPTH_TEST); // fill polygons (GL_LINE for wireframe models) glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); display ("Setting up world geometry", LOG_ALL); space = new Space (); space->drawlight = true; clip1 = space->z1; clip2 = space->z2; clip1->x = -ZOOM; clip1->y = -ZOOM; clip1->z = -ZOOM; clip2->x = ZOOM; clip2->y = ZOOM; clip2->z = ZOOM; // prepare intro init_reshape (); tl.x = 0.0; tl.y = 0.0; tl.z = -5.0; tl2.x = 0.0; tl2.y = 0.0; tl2.z = -5.0; rot.a = 270; rot2.c = 90; rot2.a = 270; rot2.b = 270; initexplode = 0; initexplode1 = 0; textitle = new CTexture (); textitle = gl->genTextureTGA (dirs->getTextures ("patents.tga"), 0, 0, 0, true); sungamma = 60; setLightSource (60); event_setAntialiasing (); glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); // glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); glEnable (GL_LIGHT0); glEnable (GL_LIGHTING); glEnable (GL_COLOR_MATERIAL); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); } void init_key (int key, int x, int y) { gl->clearScreen (); // exit intro myInit (); switch_menu (); fplayer->ai = true; camera = 5; #ifndef USE_GLUT starttime = SDL_GetTicks (); #else starttime = glutGet (GLUT_ELAPSED_TIME); #endif } void init_mouse (int button, int state, int x, int y) { init_key (32, x, y); } const int maxfx = 256; const int maxfy = 64; int heat [maxfy] [maxfx]; int heat2 [maxfy] [maxfx]; void init_display () { CVector3 vec; CColor color (200, 200, 200, 255); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glPushMatrix (); glEnable (GL_DEPTH_TEST); glEnable (GL_LIGHTING); // draw fighter glPushMatrix (); glTranslatef (0, 0, -5); model_fig.draw (&vec, &tl, &rot, 1.0, 2.0, initexplode1); glPopMatrix (); glDisable (GL_DEPTH_TEST); glEnable (GL_BLEND); if (inittimer_gl117 > 2000) { float xf = 1.3F, yf = 0.65F, zf = 2.0F; int col = (inittimer_gl117 - 2000) / 2; if (col < 0 || col > 255) col = 255; glColor3ub (col, col, col); glPushMatrix (); glTranslatef (0, 0.5F, 0); gl->enableTextures (textitle->textureID); if (antialiasing) gl->enableLinearTexture (textitle->textureID); else gl->disableLinearTexture (textitle->textureID); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBegin (GL_QUADS); glTexCoord2d (0, 1); glVertex3f (-xf, yf, -zf); glTexCoord2d (1, 1); glVertex3f (xf, yf, -zf); glTexCoord2d (1, 0); glVertex3f (xf, -yf, -zf); glTexCoord2d (0, 0); glVertex3f (-xf, -yf, -zf); glEnd (); glPopMatrix (); glDisable (GL_BLEND); } glDisable (GL_LIGHTING); glPopMatrix (); // draw fire (heat array) glDisable (GL_DEPTH_TEST); glEnable (GL_BLEND); float xf = 1.75F, yf = 1.78F, zf = 2.0F; glPushMatrix (); gl->enableTextures (5000); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBegin (GL_QUADS); glTexCoord2d (0, 1); glVertex3f (-xf, -yf, -zf); glTexCoord2d (1, 1); glVertex3f (xf, -yf, -zf); glTexCoord2d (1, 0); glVertex3f (xf, yf, -zf); glTexCoord2d (0, 0); glVertex3f (-xf, yf, -zf); glEnd (); glPopMatrix (); glDisable (GL_BLEND); font2->drawText (20, -20, -3, VERSIONSTRING, &color); } void genFireLine () { int i, i2; for (i = 0; i < maxfx; i ++) { heat [maxfy - 1] [i] = myrandom (400); } for (i = 0; i < 5; i ++) { int r = myrandom (maxfx - 7) + 3; for (i2 = -3; i2 <= 3; i2 ++) { heat [maxfy - 1] [r + i2] = 1200; // insert hot spots at the bottom line } } } unsigned char firetex [maxfx * maxfy * 4]; void proceedFire () { int i, i2; for (i = maxfy - 2; i >= 1; i --) for (i2 = 2; i2 < maxfx - 2; i2 ++) { heat2 [i] [i2] = 0 * heat [i + 1] [i2 - 2] + 4 * heat [i + 1] [i2 - 1] + 16 * heat [i + 1] [i2] + 4 * heat [i + 1] [i2 + 1] + 0 * heat [i + 1] [i2 + 2]; // heat diffusion heat2 [i] [i2] += 0 * heat [i] [i2 - 2] + 4 * heat [i] [i2 - 1] + 16 * heat [i] [i2] + 4 * heat [i] [i2 + 1] + 0 * heat [i] [i2 + 2]; // heat diffusion heat2 [i] [i2] /= 48; heat2 [i] [i2] -= (int) (300.0F / maxfy); // heat sink if (heat2 [i] [i2] < 0) heat2 [i] [i2] = 0; } memcpy (heat, heat2, maxfx * maxfy * sizeof (int)); // copy back buffer to heat array for (i = 0; i < maxfy; i ++) { for (i2 = 0; i2 < maxfx + 1; i2 ++) { // rotate through fire colors (white-yellow-red-black-blue-black) // col in [0...512] int yind = i; int h = heat [yind] [i2]; int b = h * 5; if (h > 30) b = (60 - h) * 5; if (h >= 60) b = 0; h -= 50; int r = h * 2; // blend out late for red->black if (r > 255) r = 255; else if (r < 0) r = 0; h -= 127; int g = h * 2; // blend out for yellow->red if (g > 255) g = 255; else if (g < 0) g = 0; h -= 127; if (h > 0) { b = h - 256; // blend out early to get white->yellow if (b > 255) b = 255; } else if (b < 0) b = 0; int a = r >= b ? r : b; // alpha value: transparent after yellow-red phase glColor4ub (r, g, b, a); firetex [(i * maxfx + i2) * 4] = r; firetex [(i * maxfx + i2) * 4 + 1] = g; firetex [(i * maxfx + i2) * 4 + 2] = b; firetex [(i * maxfx + i2) * 4 + 3] = a; } glEnd (); } glPopMatrix (); glBindTexture (GL_TEXTURE_2D, 5000); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D (GL_TEXTURE_2D, 0, 4, maxfx, maxfy, 0, GL_RGBA, GL_UNSIGNED_BYTE, firetex); } int initsynchrotimer = 0; void init_timer (Uint32 dt) { inittimer_gl117 += dt; initsynchrotimer += dt; if (initsynchrotimer > 20) { initsynchrotimer -= 20; dt = 20; } else return; int r = myrandom (100); if (r == 50) r = myrandom (100); // do not optimize this: random number generator initialization tl.x = 6.0 * pow (1.5, -(5 + tl.z)); tl.y = (tl.z + 3) * (tl.z + 3) * 0.02 - 0.8; //0.9 * tl.x; tl.z += 0.14; tl2.y = 0.3F; if (initexplode1 == -1 && tl2.z < 3) { tl2.z += 0.25; } if (tl2.z < 3) { rot2.b -= 20; if (rot2.b < 0) rot2.b += 360; } if (tl.z > -4.0) { rot.b ++; } if (inittimer == 0) { memset (heat, 0, maxfx * maxfy * sizeof (int)); memset (heat2, 0, maxfx * maxfy * sizeof (int)); } genFireLine (); proceedFire (); if (inittimer >= 75) { initexplode1 = -1; } if (inittimer >= 350) { initexplode += dt; } if (inittimer >= 400) { init_key (27, 0, 0); // switch to menu } inittimer ++; #ifdef USE_GLUT glutPostRedisplay(); #else sdldisplay = true; #endif } /**************************************************************************** ABSTRACT EVENT BRANCHES ****************************************************************************/ static void myKeyboardFunc (unsigned char uckey, int x, int y) { int key = (int) uckey; if (key >= 'a' && key <= 'z') key = toupper (key); if (game == GAME_PLAY || game == GAME_PAUSE) game_key (key, x, y); else if (game == GAME_INIT) init_key (key, x, y); else if (game == GAME_MENU) { allmenus.eventKey (key); menu_key (key, x, y); } else if (game == GAME_CREDITS) credits_key (key, x, y); else if (game == GAME_CREATE) create_key (key, x, y); else if (game == GAME_JOIN) join_key (key, x, y); else if (game == GAME_MISSION) mission_key (key, x, y); else if (game == GAME_STATS) stats_key (key, x, y); else if (game == GAME_FAME) fame_key (key, x, y); else if (game == GAME_FIGHTER) fighter_key (key, x, y); else if (game == GAME_FINISH) finish_key (key, x, y); else if (game == GAME_QUIT) quit_key (key, x, y); } static void myKeyboardFuncUp (unsigned char key, int x, int y) { if (game == GAME_PLAY || game == GAME_PAUSE) game_keyup ((int) key, x, y); } static void mySpecialFunc (int key, int x, int y) { if (game == GAME_PLAY || game == GAME_PAUSE) game_key (key + 256, x, y); else if (game == GAME_MENU) { allmenus.eventSpecial (key); } } static void mySpecialFuncUp (int key, int x, int y) { if (game == GAME_PLAY || game == GAME_PAUSE) game_keyup (key + 256, x, y); } static void myPassiveRelMotionFunc (int xrel, int yrel) { if (game == GAME_PLAY) if (controls == CONTROLS_MOUSE) game_mouserelmotion (xrel, yrel); } static void myPassiveMotionFunc (int x, int y) { mousex = x; mousey = y; if (game == GAME_PLAY) game_mousemotion (x, y); else if (game == GAME_MENU) { allmenus.eventMouse (x, y, 0); menu_mouse (-1, -1, x, y); } else if (game == GAME_STATS) { statsmenu.eventMouse (x, y, 0); stats_mouse (-1, -1, x, y); } else if (game == GAME_MISSION) { missionmenu.eventMouse (x, y, 0); mission_mouse (-1, -1, x, y); } else if (game == GAME_FAME) { famemenu.eventMouse (x, y, 0); fame_mouse (-1, -1, x, y); } else if (game == GAME_FIGHTER) { fightermenu.eventMouse (x, y, 0); fighter_mouse (-1, -1, x, y); } else if (game == GAME_CREATE) create_mouse (-1, -1, x, y); else if (game == GAME_JOIN) join_mouse (-1, -1, x, y); else if (game == GAME_QUIT) { quitmenu.eventMouse (x, y, 0); quit_mouse (-1, -1, x, y); } } static void myMouseFunc (int button, int state, int x, int y) { #ifdef USE_GLUT button ++; #endif if (game == GAME_PLAY) { if (controls == CONTROLS_MOUSE) game_mouse (button, state, x, y); } else if (game == GAME_INIT) { init_mouse (button, state, x, y); } else if (game == GAME_MENU) { #ifdef USE_GLUT if (state == 0) #endif allmenus.eventMouse (x, y, button); menu_mouse (button, state, x, y); } else if (game == GAME_MISSION) { #ifdef USE_GLUT if (state == 0) #endif missionmenu.eventMouse (x, y, button); mission_mouse (button, state, x, y); } else if (game == GAME_STATS) { #ifdef USE_GLUT if (state == 0) #endif statsmenu.eventMouse (x, y, button); stats_mouse (button, state, x, y); } else if (game == GAME_FAME) { #ifdef USE_GLUT if (state == 0) #endif famemenu.eventMouse (x, y, button); fame_mouse (button, state, x, y); } else if (game == GAME_FIGHTER) { #ifdef USE_GLUT if (state == 0) #endif fightermenu.eventMouse (x, y, button); fighter_mouse (button, state, x, y); } else if (game == GAME_CREATE) { create_mouse (button, state, x, y); } else if (game == GAME_JOIN) { join_mouse (button, state, x, y); } else if (game == GAME_QUIT) { #ifdef USE_GLUT if (state == 0) #endif quitmenu.eventMouse (x, y, button); quit_mouse (button, state, x, y); } else if (game == GAME_CREDITS) { #ifdef USE_GLUT if (state == 0) #endif credits_mouse (button, state, x, y); } } static void myReshapeFunc (int width, int height) { ::width = width; ::height = height; ::wantwidth = width; ::wantheight = height; if (game == GAME_PLAY || game == GAME_PAUSE) game_reshape (); else if (game == GAME_MENU || game == GAME_MISSION || game == GAME_QUIT) menu_reshape (); else if (game == GAME_INIT) init_reshape (); else if (game == GAME_CREDITS || game == GAME_FINISH) credits_reshape (); else if (game == GAME_STATS) stats_reshape (); } static void myDisplayFunc () { if (game == GAME_INIT) { init_display (); game_view (); } else if (game == GAME_PLAY) { game_display (); game_view (); } else if (game == GAME_PAUSE) { game_display (); pause_display (); game_view (); } else if (game == GAME_MENU) { if (camera == 50) camera = 0; game_display (); menu_display (); game_view (); } else if (game == GAME_CREDITS) { if (camera == 50) camera = 0; game_display (); credits_display (); game_view (); } else if (game == GAME_MISSION) { if (camera == 50) camera = 0; game_display (); mission_display (); game_view (); } else if (game == GAME_STATS) { if (camera == 50) camera = 0; game_display (); stats_display (); game_view (); } else if (game == GAME_FAME) { game_display (); fame_display (); game_view (); } else if (game == GAME_FIGHTER) { game_display (); fighter_display (); game_view (); } else if (game == GAME_CREATE) { create_display (); game_view (); } else if (game == GAME_JOIN) { join_display (); game_view (); } else if (game == GAME_FINISH) { if (camera == 50) camera = 0; game_display (); finish_display (); game_view (); } else if (game == GAME_QUIT) { game_display (); quit_display (); game_view (); } } static void myIdleFunc () { #ifdef USE_GLUT glutPostRedisplay (); #endif } static void myJoystickAxisFunc (int x, int y, int t, int r) { if (game == GAME_PLAY) { if (controls == CONTROLS_JOYSTICK) game_joystickaxis (x, y, t, r); } } static void myJoystickButtonFunc (int button) { if (game == GAME_PLAY) { if (controls == CONTROLS_JOYSTICK) game_joystickbutton (button); } else if (game == GAME_MENU) { allmenus.eventJoystick (button); } } static void myJoystickHatFunc (int hat) { int normhat = hat; #ifndef USE_GLUT if (hat % 1000 == SDL_HAT_RIGHT) normhat = 100; if (hat % 1000 == SDL_HAT_UP) normhat = 101; if (hat % 1000 == SDL_HAT_LEFT) normhat = 102; if (hat % 1000 == SDL_HAT_DOWN) normhat = 103; normhat += (hat / 1000) * 1000; #endif if (game == GAME_PLAY) { if (controls == CONTROLS_JOYSTICK) game_joystickhat (normhat); } else if (game == GAME_MENU) { allmenus.eventJoystick (normhat); } } static void myTimerFunc (int value) { Uint32 akttime, dt; #ifndef USE_GLUT akttime = SDL_GetTicks (); #else akttime = glutGet (GLUT_ELAPSED_TIME); #endif if (lasttime == 0) dt = 1; else dt = akttime - lasttime; lasttime = akttime; if (dt > 1000) { dt = 1; if (game == GAME_PLAY && multiplayer) { display ("Out of sync", LOG_ERROR); switch_menu (); } } if (game == GAME_PLAY) game_timer (dt); else if (game == GAME_INIT) init_timer (dt); else if (game == GAME_MENU) { if (!missionactive) game_timer (dt); menu_timer (dt); } else if (game == GAME_CREDITS) { if (!missionactive) game_timer (dt); credits_timer (dt); } else if (game == GAME_CREATE) create_timer (dt); else if (game == GAME_JOIN) join_timer (dt); else if (game == GAME_MISSION) { if (!missionactive) game_timer (dt); mission_timer (dt); } else if (game == GAME_STATS) stats_timer (dt); else if (game == GAME_FAME) { if (!missionactive) game_timer (dt); mission_timer (dt); } else if (game == GAME_FIGHTER) { if (!missionactive) game_timer (dt); mission_timer (dt); } else if (game == GAME_FINISH) finish_timer (dt); else if (game == GAME_QUIT) { if (!missionactive) game_timer (dt); mission_timer (dt); } #ifdef USE_GLUT glutTimerFunc (1, myTimerFunc, 0); // do as many timer calls as possible #endif } #ifndef USE_GLUT Uint32 nexttime = 0; int joystickbutton = -1; bool joystickfirebutton = false; // This loop emulates the glutMainLoop() of GLUT using SDL!!! void sdlMainLoop () { int sym = 0; SDL_Event event; while (true) { while (SDL_PollEvent (&event)) // process events { switch (event.type) { case SDL_MOUSEMOTION: myPassiveMotionFunc (event.motion.x, event.motion.y); if (game == GAME_PLAY && controls == CONTROLS_MOUSE && mouse_relative) { fplayer->rolleffect = 0; fplayer->elevatoreffect = 0; fplayer->ruddereffect = 0; } myPassiveRelMotionFunc (event.motion.xrel, event.motion.yrel); break; case SDL_MOUSEBUTTONDOWN: myMouseFunc (event.button.button, event.button.state, event.button.x, event.button.y); break; case SDL_KEYDOWN: if (!event.key.keysym.unicode) mySpecialFunc (event.key.keysym.sym, 0, 0); else myKeyboardFunc (event.key.keysym.sym, 0, 0); break; case SDL_KEYUP: sym = event.key.keysym.sym; if (sym == 8 || sym == 9 || sym == 13 || (sym >= 32 && sym <= 'z')) myKeyboardFuncUp (event.key.keysym.sym, 0, 0); else mySpecialFuncUp (event.key.keysym.sym, 0, 0); break; case SDL_JOYAXISMOTION: if (abs (event.jaxis.value) < 2000) { jaxis [event.jaxis.axis + event.jaxis.which * 10] = 0; } else { if (event.jaxis.value < 0) event.jaxis.value += 2500; else event.jaxis.value -= 2500; jaxis [event.jaxis.axis + event.jaxis.which * 10] = (int) event.jaxis.value * 32768 / 30268; } break; case SDL_JOYBUTTONDOWN: joystickbutton = event.jbutton.button + event.jbutton.which * 1000; if (joystickbutton == (int) joystick_firecannon) joystickfirebutton = true; myJoystickButtonFunc (joystickbutton); joystickbutton = -1; break; case SDL_JOYBUTTONUP: joystickbutton = event.jbutton.button + event.jbutton.which * 1000; if (joystickbutton == (int) joystick_firecannon) joystickfirebutton = false; joystickbutton = -1; break; case SDL_JOYHATMOTION: myJoystickHatFunc (event.jhat.value + event.jhat.which * 1000); break; case SDL_ACTIVEEVENT: sdlreshape = true; sdldisplay = true; break; } } if (controls == CONTROLS_JOYSTICK) { int x = jaxis [getJoystickAxisIndex (joystick_aileron)]; int y = jaxis [getJoystickAxisIndex (joystick_elevator)]; int rudder = jaxis [getJoystickAxisIndex (joystick_rudder)]; int throttle = jaxis [getJoystickAxisIndex (joystick_throttle)]; myJoystickAxisFunc (x, y, rudder, throttle); view_x = (float) jaxis [getJoystickAxisIndex (joystick_view_x)]/(-328.0); view_y = (float) jaxis [getJoystickAxisIndex (joystick_view_y)]/(-328.0); if (joystickfirebutton) myJoystickButtonFunc (joystick_firecannon); } if (sdldisplay) myDisplayFunc (); sdldisplay = false; if (sdlreshape) myReshapeFunc (width, height); sdlreshape = false; myTimerFunc (1); // dummy value } } #endif /**************************************************************************** STARTUP METHODS ****************************************************************************/ // common GLUT screen init code, return 0 on error int setGlutScreen (int w, int h, int b, int f) { char gamestr [256]; sprintf (gamestr, "%dx%d:%d", w, h, b); glutGameModeString (gamestr); if (f) { if (glutGameModeGet (GLUT_GAME_MODE_POSSIBLE)) { glutEnterGameMode (); } else { return 0; } } else { glutInitWindowPosition (0, 0); glutInitWindowSize (w, h); glutwindow = glutCreateWindow ("GL-117"); if (glutwindow == GL_FALSE) return 0; } return 1; } // set screen to (width, height, bpp, fullscreen), return 0 on error int setScreen (int w, int h, int b, int f) { #ifdef USE_GLUT if (!setGlutScreen (w, h, b, f)) { b = 16; if (!setGlutScreen (w, h, b, f)) { b = 8; if (!setGlutScreen (w, h, b, f)) { b = 2; if (!setGlutScreen (w, h, b, f)) { return 0; } } } } #else Uint32 video_flags; if (f) { video_flags = SDL_OPENGL | SDL_FULLSCREEN; } else { video_flags = SDL_OPENGL; } int rgb_size [3]; switch (b) { case 8: rgb_size [0] = 2; rgb_size [1] = 3; rgb_size [2] = 3; break; case 15: case 16: rgb_size [0] = 5; rgb_size [1] = 5; rgb_size [2] = 5; break; default: rgb_size [0] = 8; rgb_size [1] = 8; rgb_size [2] = 8; break; } SDL_GL_SetAttribute (SDL_GL_RED_SIZE, rgb_size [0]); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, rgb_size [1]); SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, rgb_size [2]); SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); if (SDL_SetVideoMode (w, h, b, video_flags) == NULL) { if ((b = SDL_VideoModeOK (w, h, b, video_flags)) != 0) { b = 16; SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5); SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); if (SDL_SetVideoMode (w, h, b, video_flags) == NULL) { b = 8; SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 2); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 3); SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 3); if (SDL_SetVideoMode (w, h, b, video_flags) == NULL) { return 0; } } } } #endif glViewport (0, 0, (GLint) w, (GLint) h); // take over results in global variables width = w; height = h; bpp = b; fullscreen = f; wantwidth = w; // requested values for next restart wantheight = h; wantfullscreen = f; return 1; } // get approximate speed by drawing polygons (obsolete) int speedTest () { int frames = 0, time2 = 0, time1 = 0; glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (visibleangle, 1.0, nearclippingplane, 20.0); // should be sqrt(2) or 1.5 glPolygonMode (GL_FRONT_AND_BACK, polygonMode); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); #ifndef USE_GLUT time1 = SDL_GetTicks (); #else time1 = glutGet (GLUT_ELAPSED_TIME); #endif while (time2 - time1 < 1000) { frames ++; #ifndef USE_GLUT time2 = SDL_GetTicks (); #else time2 = glutGet (GLUT_ELAPSED_TIME); #endif glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glRotatef (1, 0, 0, 1); for (float zf = -13; zf <= -3; zf += 0.05) { glBegin (GL_QUADS); glColor4d (255, 0, 0, 255); glVertex3f (-1, -1, zf); glVertex3f (-1, 1, zf); glVertex3f (1, 1, zf); glVertex3f (1, -1, zf); glEnd (); } #ifdef USE_GLUT glutSwapBuffers(); #else SDL_GL_SwapBuffers (); #endif } return frames; } bool configinit = false; // has GLUT/SDL already been inited? // test screen settings automatically void config_test (int argc, char **argv) { display ("No configuration file found. Testing...", LOG_MOST); int bppi [4]; #ifdef USE_GLUT // GLUT ONLY display ("Using GLUT only", LOG_MOST); glutInit (&argc, argv); glutInitDisplayMode (GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE); configinit = true; #else // SDL char buf [STDSIZE]; display ("Using SDL and GLUT", LOG_MOST); if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) { sprintf (buf, "Couldn't initialize SDL: %s", SDL_GetError ()); display (buf, LOG_FATAL); exit (EXIT_INIT); } configinit = true; #endif int valids = -1; // valid screen mode? (-1 = no mode) int n = 0; while (n < 4) { if (setScreen (resolution [n] [0], resolution [n] [1], resolution [n] [2], resolution [n] [3])) { bppi [n] = bpp; // store bpp setting valids = n; break; // first mode found => exit loop } else { bppi [n] = -1; } n ++; } if (valids == -1) { display ("No working display modes found! Try editing the file conf yourself. You may not be able to play this game.", LOG_FATAL); exit (EXIT_INIT); } // start with lowest quality/view settings quality = 0; view = 20; width = resolution [valids] [0]; height = resolution [valids] [1]; bpp = bppi [valids]; fullscreen = resolution [valids] [3]; wantwidth = width; // requested values for next restart wantheight = height; wantfullscreen = fullscreen; } // get startup help screen void viewParameters () { display (" ", LOG_NONE); display ("Usage: gl-117 [-h -v -dLEVEL]", LOG_NONE); display (" ", LOG_NONE); display ("-h: Display this help screen and quit", LOG_NONE); display ("-v: Display version string and quit", LOG_NONE); display ("-dLEVEL: Set debug LEVEL to 0=silent...5=log all", LOG_NONE); display (" ", LOG_NONE); } void checkargs (int argc, char **argv) { char buf [STDSIZE]; // temp buffer int i; // temp counter for (i = 1; i < argc; i ++) // for each arg (argument/parameter) { if (argv [i] [1] == 'd') // change log/debug level { char *ptr = &argv [i] [2]; debuglevel = atoi (ptr); if (debuglevel < LOG_NONE || debuglevel > LOG_ALL) // look at common.h for the constants { display ("Invalid debug level", LOG_FATAL); viewParameters (); exit (EXIT_COMMAND); } else { sprintf (buf, "Entering debug level %d", debuglevel); display (buf, LOG_MOST); } } else if (argv [i] [1] == 'v') // display version string { display (VERSIONSTRING, LOG_NONE); exit (EXIT_NORMAL); } else if (argv [i] [1] == 'h') // display startup help screen { viewParameters (); exit (EXIT_NORMAL); } else { display ("Invalid command line parameter", LOG_FATAL); viewParameters (); exit (EXIT_COMMAND); } } } void textMouseButton (char *buf, int button) { if (button == 0) strcpy (buf, "NONE"); else sprintf (buf, "BUTTON%d", button); } int campaignstartid; int trainingstartid; void callbackReturn (Component *comp, int key) { switch_game (); } void callbackStats (Component *comp, int key) { stats_key (27, 0, 0); } void callbackQuitNow (Component *comp, int key) { game_quit (); } void callbackSwitchMainMenu (Component *comp, int key) { switch_menu (); } void callbackQuit (Component *comp, int key) { switch_quit (); } void callbackCredits (Component *comp, int key) { switch_credits (); } void callbackPilots (Component *comp, int key) { switch_fame (); } int currentaxis = 0; #ifndef USE_GLUT void callbackJoystickAxis (Component *comp, int key) { int i; int buttonnum = -1; // get clicked button's number for (i = 0; i < 12; i ++) { if (comp == controlsmenu [2]->components [i]) { buttonnum = i; } } if (buttonnum == -1) return; // read text from label of button Label *la = (Label *) controlsmenu [2]->components [buttonnum + 1]; int joynum = 0; int joyaxis = 0; if (la->text [1] == '/') joynum = -1; else { joynum = la->text [0] - 'A'; joyaxis = la->text [2] - '0'; } if (key == MOUSE_BUTTON_LEFT) { if (joynum == -1) { joynum = 0; joyaxis = 0; } else if (joynum >= joysticks) joynum = -1; else { joyaxis ++; if (joyaxis >= sdljoystickaxes [joynum]) { joyaxis = 0; joynum ++; if (joynum >= joysticks) joynum = -1; } } } else { if (joynum == -1) { joynum = joysticks - 1; joyaxis = sdljoystickaxes [joynum] - 1; } else if (joynum >= joysticks) joynum = -1; else { joyaxis --; if (joyaxis < 0) { joynum --; if (joynum < 0) { joynum = -1; joyaxis = 0; } else joyaxis = sdljoystickaxes [joynum] - 1; } } } int *joysetting = NULL; if (buttonnum == 0) joysetting = &joystick_aileron; else if (buttonnum == 2) joysetting = &joystick_elevator; else if (buttonnum == 4) joysetting = &joystick_throttle; else if (buttonnum == 6) joysetting = &joystick_rudder; else if (buttonnum == 8) joysetting = &joystick_view_x; else if (buttonnum == 10) joysetting = &joystick_view_y; *joysetting = joynum * 1000 + joyaxis; char latext [4]; if (joynum >= 0) { latext [0] = 'A' + joynum; latext [1] = 32; latext [2] = '0' + joyaxis; latext [3] = 0; la->setText (latext); } else { la->setText ("N/A"); } } #endif void callbackSwitchStartMission (Component *comp, int key) { pleaseWait (); if (!game_levelInit ()) { switch_menu (); return; } switch_game (); missionactive = true; } void callbackFighterPrev (Component *comp, int key) { int maxfighter = 6; Pilot *p = pilots->pilot [pilots->aktpilot]; if (p->mission_state [MISSION_DEPOT] == 1) maxfighter ++; if (p->mission_state [MISSION_SHIP1] == 1) maxfighter ++; if (p->mission_state [MISSION_CANYON3] == 1) maxfighter ++; if (p->mission_state [MISSION_MOON1] == 1) maxfighter ++; if (key == MOUSE_BUTTON_LEFT) { aktfighter --; if (aktfighter < 0) aktfighter = maxfighter - 1; } } void callbackFighterNext (Component *comp, int key) { int maxfighter = 6; Pilot *p = pilots->pilot [pilots->aktpilot]; if (p->mission_state [MISSION_DEPOT] == 1) maxfighter ++; if (p->mission_state [MISSION_SHIP1] == 1) maxfighter ++; if (p->mission_state [MISSION_CANYON3] == 1) maxfighter ++; if (p->mission_state [MISSION_MOON1] == 1) maxfighter ++; if (key == MOUSE_BUTTON_LEFT) { aktfighter ++; if (aktfighter >= maxfighter) aktfighter = 0; } } void callbackFighter (Component *comp, int key) { switch_fighter (); } void setpilotstext () { char buf [64]; int i; sprintf (buf, " %s %s", pilots->pilot [pilots->aktpilot]->getShortRank (), pilots->pilot [pilots->aktpilot]->name); ((Label *) submenu [0]->components [1])->setText (buf); for (i = 0; i < pilots->aktpilots; i ++) { sprintf (buf, " %s %s", pilots->pilot [i]->getShortRank (), pilots->pilot [i]->name); ((Label *) submenu [0]->components [i + 2])->setText (buf); } for (; i < 5; i ++) { ((Label *) submenu [0]->components [i + 2])->setText ("N/A"); } } void callbackPilotsAdd (Component *comp, int key) { char buf [64]; if (key == MOUSE_BUTTON_LEFT) { strcpy (buf, ((EditField *) submenu [0]->components [9])->text); if (strlen (buf) > 0 && pilots->aktpilots < 5) { pilots->add (buf); ((EditField *) submenu [0]->components [9])->setText (""); setpilotstext (); } } } void callbackPilotsDelete (Component *comp, int key) { if (key == MOUSE_BUTTON_RIGHT) { pilots->rm (); setpilotstext (); } } void callbackPilotsList (Component *comp, int key) { int i; for (i = 0; i < 5; i ++) { if (comp == submenu [0]->components [i + 2]) { if (i < pilots->aktpilots) { pilots->aktpilot = i; setpilotstext (); } } } } void callbackJoystick (Component *comp, int key) { int i; for (i = 12; i < 23; i ++) if (comp == controlsmenu [0]->components [i]) { int z = 12; if (i == z ++) joystick_firecannon = key; else if (i == z ++) joystick_firemissile = key; else if (i == z ++) joystick_dropflare = key; else if (i == z ++) joystick_dropchaff = key; else if (i == z ++) joystick_selectmissile = key; else if (i == z ++) joystick_targetnearest = key; else if (i == z ++) joystick_targetlocking = key; else if (i == z ++) joystick_targetnext = key; else if (i == z ++) joystick_targetprevious = key; else if (i == z ++) joystick_thrustup = key; else if (i == z ++) joystick_thrustdown = key; } } void callbackMouseDefaults (Component *comp, int key) { char buf [256]; mouse_sensitivity = 100; mouse_reverse = false; mouse_relative = false; mouse_autorudder = 30; sprintf (buf, "%d%%", mouse_autorudder); ((Label *) controlsmenu [1]->components [7])->setText (buf); if (mouse_relative) sprintf (buf, "ON"); else sprintf (buf, "OFF"); ((Label *) controlsmenu [1]->components [5])->setText (buf); if (mouse_reverse) sprintf (buf, "ON"); else sprintf (buf, "OFF"); ((Label *) controlsmenu [1]->components [3])->setText (buf); sprintf (buf, "%d%%", mouse_sensitivity); ((Label *) controlsmenu [1]->components [1])->setText (buf); } void callbackMouseAutorudder (Component *comp, int key) { char buf [256]; if (key == MOUSE_BUTTON_LEFT) { mouse_autorudder += 10; if (mouse_autorudder > 100) mouse_autorudder = 0; } else { mouse_autorudder -= 10; if (mouse_autorudder < 0) mouse_autorudder = 100; } sprintf (buf, "%d%%", mouse_autorudder); ((Label *) controlsmenu [1]->components [7])->setText (buf); } void callbackMouseRelative (Component *comp, int key) { char buf [256]; mouse_relative = !mouse_relative; if (mouse_relative) sprintf (buf, "ON"); else sprintf (buf, "OFF"); ((Label *) controlsmenu [1]->components [5])->setText (buf); } void callbackMouseReverse (Component *comp, int key) { char buf [256]; mouse_reverse = !mouse_reverse; if (mouse_reverse) sprintf (buf, "ON"); else sprintf (buf, "OFF"); ((Label *) controlsmenu [1]->components [3])->setText (buf); } void callbackMouseSensitivity (Component *comp, int key) { char buf [256]; if (key == MOUSE_BUTTON_LEFT) { mouse_sensitivity += 10; if (mouse_sensitivity > 200) mouse_sensitivity = 70; } else { mouse_sensitivity -= 10; if (mouse_sensitivity < 70) mouse_sensitivity = 200; } sprintf (buf, "%d%%", mouse_sensitivity); ((Label *) controlsmenu [1]->components [1])->setText (buf); } void callbackDefaultsJoystick (Component *comp, int key) { joystick_aileron = 0; joystick_elevator = 1; joystick_throttle = 2; joystick_rudder = 3; joystick_view_x = 4; joystick_view_y = 5; int z = 1; ((Label *) controlsmenu [2]->components [z])->setText ("A 0"); z += 2; ((Label *) controlsmenu [2]->components [z])->setText ("A 1"); z += 2; ((Label *) controlsmenu [2]->components [z])->setText ("A 2"); z += 2; ((Label *) controlsmenu [2]->components [z])->setText ("A 3"); z += 2; ((Label *) controlsmenu [2]->components [z])->setText ("A 4"); z += 2; ((Label *) controlsmenu [2]->components [z])->setText ("A 5"); joystick_firecannon = 0; joystick_firemissile = 2; joystick_dropflare = 3; joystick_dropchaff = 3; joystick_selectmissile = 1; joystick_targetnearest = 101; joystick_targetlocking = 103; joystick_targetnext = 100; joystick_targetprevious = 102; joystick_thrustup = 4; joystick_thrustdown = 5; z = 12; ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_firecannon); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_firemissile); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_dropflare); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_dropchaff); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_selectmissile); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_targetnearest); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_targetlocking); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_targetnext); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_targetprevious); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_thrustup); ((EditJoystick *) controlsmenu [2]->components [z ++])->setButton (joystick_thrustdown); } void callbackDefaults (Component *comp, int key) { key_firecannon = 32; key_firemissile = 13; key_dropflare = 'F'; key_dropchaff = 'C'; key_selectmissile = 'M'; key_targetnearest = 'E'; key_targetlocking = 'L'; key_targetnext = 'N'; key_targetprevious = 'P'; key_thrustup = 'S'; key_thrustdown = 'X'; int z = 5; ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_firecannon); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_firemissile); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_dropflare); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_dropchaff); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_selectmissile); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_targetnearest); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_targetlocking); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_targetnext); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_targetprevious); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_thrustup); ((EditKey *) controlsmenu [0]->components [z ++])->setKey (key_thrustdown); } void callbackKeyboard (Component *comp, int key) { int i; for (i = 5; i < 16; i ++) if (comp == controlsmenu [0]->components [i]) { int z = 5; if (i == z ++) key_firecannon = key; else if (i == z ++) key_firemissile = key; else if (i == z ++) key_dropflare = key; else if (i == z ++) key_dropchaff = key; else if (i == z ++) key_selectmissile = key; else if (i == z ++) key_targetnearest = key; else if (i == z ++) key_targetlocking = key; else if (i == z ++) key_targetnext = key; else if (i == z ++) key_targetprevious = key; else if (i == z ++) key_thrustup = key; else if (i == z ++) key_thrustdown = key; } } void textControls (char *buf) { if (controls == CONTROLS_KEYBOARD) sprintf (buf, "%s", "KEYBOARD"); else if (controls == CONTROLS_MOUSE) sprintf (buf, "%s", "MOUSE"); else if (controls == CONTROLS_JOYSTICK) sprintf (buf, "%s", "JOYSTICK"); } void callbackControls (Component *comp, int key) { char buf [256]; if (key == MOUSE_BUTTON_LEFT) { fplayer->rolleffect = 0; fplayer->ruddereffect = 0; fplayer->elevatoreffect = 0; keyb_elev = 0; keyb_roll = 0; keyb_rudder = 0; controls ++; if (controls > 2) controls = 0; if (controls == CONTROLS_JOYSTICK && !joysticks) controls = CONTROLS_KEYBOARD; #ifdef USE_GLUT if (controls == CONTROLS_KEYBOARD) controls = CONTROLS_MOUSE; #endif } textControls (buf); ((Label *) optmenu [2]->components [5])->setText (buf); allmenus.components [11]->setVisible (false); allmenus.components [12]->setVisible (false); allmenus.components [13]->setVisible (false); if (controls == CONTROLS_KEYBOARD) allmenus.components [11]->setVisible (true); else if (controls == CONTROLS_JOYSTICK) allmenus.components [13]->setVisible (true); else allmenus.components [12]->setVisible (true); } void callbackPhysics (Component *comp, int key) { char buf [256]; physics = !physics; if (!physics) sprintf (buf, "%s", "ACTION"); else sprintf (buf, "%s", "SIMULATION"); ((Label *) optmenu [2]->components [3])->setText (buf); } void callbackDifficulty (Component *comp, int key) { char buf [256]; if (key == MOUSE_BUTTON_LEFT) { difficulty ++; if (difficulty > 2) difficulty = 0; } else { difficulty --; if (difficulty < 0) difficulty = 2; } if (difficulty == 0) sprintf (buf, "%s", "EASY"); else if (difficulty == 1) sprintf (buf, "%s", "NORMAL"); else if (difficulty == 2) sprintf (buf, "%s", "HARD"); ((Label *) optmenu [2]->components [1])->setText (buf); } void callbackSound (Component *comp, int key) { char buf [256]; if (sound->audio) { if (key == MOUSE_BUTTON_LEFT) { sound->volumesound += 10; if (sound->volumesound > 100) sound->volumesound = 0; volumesound = sound->volumesound; sound->setVolume (); setPlaneVolume (); sound->play (SOUND_CLICK1, false); menu_reshape (); } else { sound->volumesound -= 10; if (sound->volumesound < 0) sound->volumesound = 100; volumesound = sound->volumesound; sound->setVolume (); setPlaneVolume (); sound->play (SOUND_CLICK1, false); menu_reshape (); } sprintf (buf, "%d%%", volumesound); ((Label *) optmenu [1]->components [1])->setText (buf); } } void callbackMusic (Component *comp, int key) { char buf [256]; if (sound->audio) { if (key == MOUSE_BUTTON_LEFT) { sound->volumemusic += 10; if (sound->volumemusic > 100) { sound->volumemusic = 0; sound->haltMusic (); } volumemusic = sound->volumemusic; sound->setVolumeMusic (); menu_reshape (); } else { sound->volumemusic -= 10; if (sound->volumemusic < 0) sound->volumemusic = 100; volumemusic = sound->volumemusic; sound->setVolumeMusic (); menu_reshape (); } if (sound->volumemusic != 0 && !sound->musicplaying) playRandomMusic (); sprintf (buf, "%d%%", volumemusic); ((Label *) optmenu [1]->components [3])->setText (buf); } } void callbackBrightness (Component *comp, int key) { char buf [256]; if (key == MOUSE_BUTTON_LEFT) { brightness += 10; if (brightness > 50) brightness = -50; } else { brightness -= 10; if (brightness < -50) brightness = 50; } sprintf (buf, "%d%%", brightness); ((Label *) optmenu [0]->components [13])->setText (buf); } void callbackResolution (Component *comp, int key) { const int numres = 4; int resx [numres] = { 640, 800, 1024, 1280 }; int resy [numres] = { 480, 600, 800, 1024 }; int found = 0; char buf [256]; if (key == MOUSE_BUTTON_LEFT) { for (int i = 0; i < numres; i ++) if (wantwidth == resx [i]) { found = i + 1; } } else { for (int i = 0; i < numres; i ++) if (wantwidth == resx [i]) { found = i - 1; } } if (found < 0) found = numres - 1; else if (found >= numres) found = 0; wantwidth = resx [found]; wantheight = resy [found]; sprintf (buf, "%d*%d", wantwidth, wantheight); ((Label *) optmenu [0]->components [16])->setText (buf); } void callbackFullscreen (Component *comp, int key) { if (wantfullscreen) wantfullscreen = 0; else wantfullscreen = 1; if (wantfullscreen) ((Label *) optmenu [0]->components [18])->setText ("YES"); else ((Label *) optmenu [0]->components [18])->setText ("NO"); } void callbackDynamicLighting (Component *comp, int key) { char buf [256]; dynamiclighting = (dynamiclighting == 0 ? 1 : 0); if (dynamiclighting) strcpy (buf, "ON"); else strcpy (buf, "OFF"); ((Label *) optmenu [0]->components [11])->setText (buf); } void callbackSpecialEffects (Component *comp, int key) { char buf [256]; specialeffects = (specialeffects == 0 ? 1 : 0); if (specialeffects) strcpy (buf, "ON"); else strcpy (buf, "OFF"); ((Label *) optmenu [0]->components [9])->setText (buf); } void callbackAntialiasing (Component *comp, int key) { char buf [256]; antialiasing = (antialiasing == 0 ? 1 : 0); if (antialiasing) strcpy (buf, "ON"); else strcpy (buf, "OFF"); ((Label *) optmenu [0]->components [7])->setText (buf); event_setAntialiasing (); } void callbackDithering (Component *comp, int key) { char buf [256]; dithering = (dithering == 0 ? 1 : 0); if (dithering) strcpy (buf, "ON"); else strcpy (buf, "OFF"); ((Label *) optmenu [0]->components [5])->setText (buf); } void callbackView (Component *comp, int key) { char buf [256]; if (key == MOUSE_BUTTON_LEFT) { view += 10; if (view > VIEW_MAX) view = VIEW_MIN; menu_reshape (); } else { view -= 10; if (view < VIEW_MIN) view = VIEW_MAX; menu_reshape (); } sprintf (buf, "%d", (int) view); ((Label *) optmenu [0]->components [3])->setText (buf); // this is also set by autoconfig in menu_timer } void callbackQuality (Component *comp, int key) { char buf [256]; if (key == MOUSE_BUTTON_LEFT) { quality ++; if (quality > 5) quality = 0; } else { quality --; if (quality < 0) quality = 5; } sprintf (buf, "%d", quality); ((Label *) optmenu [0]->components [1])->setText (buf); // this is also set by autoconfig in menu_timer } void callbackTraining (Component *comp, int key) { allmenus.setVisible (false); switch_mission (getTrainingIdFromValue (comp->id - trainingstartid)); } void callbackCampaign (Component *comp, int key) { allmenus.setVisible (false); switch_mission (getCampaignIdFromValue (comp->id - campaignstartid)); } void callbackMainMenu (Component *comp, int key) { for (i = 0; i < 6; i ++) if (comp == mainbutton [i]) { allmenus.setVisible (false); allmenus.visible = true; allmenus.components [0]->setVisible (true); allmenus.components [i + 1]->setVisible (true); currentsubmenu = allmenus.components [i + 1]; if (missionactive) mainbutton [6]->setVisible (true); else mainbutton [6]->setVisible (false); if (i == 3) { if (currentoptmenu) currentoptmenu->setVisible (true); if (currentoptmenu == allmenus.components [10]) { if (controls == CONTROLS_KEYBOARD) allmenus.components [11]->setVisible (true); else if (controls == CONTROLS_JOYSTICK) allmenus.components [13]->setVisible (true); else allmenus.components [12]->setVisible (true); } } return; } for (i = 0; i < 3; i ++) if (comp == optbutton [i]) { allmenus.components [8]->setVisible (false); allmenus.components [9]->setVisible (false); allmenus.components [10]->setVisible (false); allmenus.components [i + 1 + 7]->setVisible (true); if (i + 1 + 7 == 10) { if (controls == CONTROLS_KEYBOARD) allmenus.components [11]->setVisible (true); else if (controls == CONTROLS_JOYSTICK) allmenus.components [13]->setVisible (true); else allmenus.components [12]->setVisible (true); } else { allmenus.components [11]->setVisible (false); allmenus.components [12]->setVisible (false); allmenus.components [13]->setVisible (false); } currentoptmenu = allmenus.components [i + 1 + 7]; return; } } void setJoystickAxisString (int joysetting, char *joystr) { joystr [3] = 0; if (joysetting < 0) { strcpy (joystr, "N/A"); } else { joystr [0] = 'A' + (joysetting / 1000); joystr [1] = 32; joystr [2] = '0' + (joysetting % 1000); } } char mainmenunames [10] [25]; char submenu1names [20] [25]; char submenu2names [30] [25]; char optmenunames [5] [25]; char controlsmenu0names [15] [25]; void createMenu () { char buf [256]; char buf2 [256]; int i; int z = 0; float xf = -2; float xfstep = 4; float yf = 12; float yfstep = 1.0; float xsubmenu = -1; float ysubmenu = 12; Button *button; Label *label; TextField *textfield; EditKey *editkey; EditField *editfield; #ifndef USE_GLUT EditJoystick *editjoystick; #endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register main menu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ strcpy (mainmenunames [0], "PILOTS"); strcpy (mainmenunames [1], "TRAINING"); strcpy (mainmenunames [2], "CAMPAIGN"); strcpy (mainmenunames [3], "OPTIONS"); #ifdef SHOW_SOFTWARE_PATENTS strcpy (mainmenunames [4], "SOFTWARE PATENTS"); #else strcpy (mainmenunames [4], "CREDITS"); #endif strcpy (mainmenunames [5], "QUIT"); strcpy (mainmenunames [6], "RETURN"); mainmenu = new Container (); // mainmenu->setBounds (-14.3, 12.2, 10.6, 7.4); allmenus.add (mainmenu); for (i = 0; i < 7; i ++) { submenu [i] = new Container (); allmenus.add (submenu [i]); } /* submenu [0]->setBounds (-1.3, 12.2, 14.1, 12.4); submenu [1]->setBounds (-1.3, 12.2, 12.6, 7.4); submenu [2]->setBounds (-1.3, 12.2, 12.6, 1.4); submenu [3]->setBounds (-1.3, 12.2, 14.1, 1.4);*/ for (i = 0; i < 7; i ++) { mainbutton [i] = new Button (mainmenunames [i]); mainbutton [i]->setBounds (-14, yf, 10, yfstep - 0.1); yf -= yfstep; mainbutton [i]->setFunction (callbackMainMenu); mainmenu->add (mainbutton [i]); } currentsubmenu = submenu [0]; mainbutton [4]->setFunction (callbackCredits); mainbutton [5]->setFunction (callbackQuit); mainbutton [6]->setVisible (false); mainbutton [6]->setFunction (callbackReturn); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register pilots submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = xsubmenu; yf = ysubmenu; xfstep = 13.5; yfstep = 1; sprintf (buf, "ACTIVE:"); label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); submenu [0]->add (label); yf -= yfstep; sprintf (buf, " %s %s", pilots->pilot [pilots->aktpilot]->getShortRank (), pilots->pilot [pilots->aktpilot]->name); label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); submenu [0]->add (label); yf -= 2; for (i = 0; i < 5; i ++) { if (i < pilots->aktpilots) sprintf (buf, " %s %s", pilots->pilot [i]->getShortRank (), pilots->pilot [i]->name); else sprintf (buf, "N/A"); button = new Button (buf); button->setFunction (callbackPilotsList); button->setBounds (xf, yf, xfstep, yfstep - 0.1); submenu [0]->add (button); yf -= yfstep; } yf -= 0.5; button = new Button ("DELETE (RIGHT MB)"); button->setFunction (callbackPilotsDelete); button->setBounds (xf, yf, xfstep, yfstep - 0.1); submenu [0]->add (button); yf -= yfstep; yf -= 0.5; button = new Button ("ADD"); button->setFunction (callbackPilotsAdd); button->setBounds (xf, yf, xfstep, yfstep - 0.1); submenu [0]->add (button); yf -= yfstep; editfield = new EditField (15); editfield->setBounds (xf, yf, xfstep, yfstep - 0.1); submenu [0]->add (editfield); yf -= yfstep; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register training submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ z = 0; strcpy (submenu1names [z ++], "TUTORIAL: PILOTING"); strcpy (submenu1names [z ++], "TUTORIAL: BOMBER"); strcpy (submenu1names [z ++], "TUTORIAL: FIGHTER"); strcpy (submenu1names [z ++], "TUTORIAL: AERODYNAMICS"); strcpy (submenu1names [z ++], "FREE FLIGHT"); strcpy (submenu1names [z ++], "DEATHMATCH"); strcpy (submenu1names [z ++], "TEAM DEATHMATCH"); strcpy (submenu1names [z ++], "CANNON DEATHMATCH"); strcpy (submenu1names [z ++], "TEAM BASE"); strcpy (submenu1names [z ++], "WAVES"); xf = xsubmenu; yf = ysubmenu - 2; xfstep = 12; yfstep = 0.8; for (i = 0; i < 10; i ++) { button = new Button (submenu1names [i]); button->setBounds (xf, yf, xfstep, yfstep - 0.1); button->setFunction (callbackTraining); yf -= yfstep; if (i == 3) yf -= yfstep; submenu [1]->add (button); } trainingstartid = submenu [1]->components [0]->id; yf -= yfstep; for (i = 0; i < maploader->getMapNumber (); i ++) { char str [256]; strcpy (str, maploader->getNextMap ()); maploader->toUpper (str); button = new Button (str); button->setBounds (xf, yf, xfstep, yfstep - 0.1); button->setFunction (callbackTraining); yf -= yfstep; submenu [1]->add (button); } xf = xsubmenu; yf = ysubmenu; yfstep = 1; button = new Button ("FIGHTER INFO"); button->setFunction (callbackFighter); button->setBounds (xf, yf, xfstep - 0.2, yfstep - 0.1); submenu [1]->add (button); xf += xfstep; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register campaign submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ z = 0; strcpy (submenu2names [z ++], "FIRST TEST"); strcpy (submenu2names [z ++], "SECOND TEST"); strcpy (submenu2names [z ++], "TRANSPORT"); strcpy (submenu2names [z ++], "CONVOY"); strcpy (submenu2names [z ++], "DOGFIGHT"); strcpy (submenu2names [z ++], "AIR BATTLE"); strcpy (submenu2names [z ++], "SURFACE-AIR DEFENSE"); strcpy (submenu2names [z ++], "VETERAN DOGFIGHT"); strcpy (submenu2names [z ++], "BASE ATTACK"); strcpy (submenu2names [z ++], "DEPOTS"); strcpy (submenu2names [z ++], "DEFEND SAM"); strcpy (submenu2names [z ++], "DESERT DOGFIGHT"); strcpy (submenu2names [z ++], "TANK ASSAUT"); strcpy (submenu2names [z ++], "SAM CONVOY"); strcpy (submenu2names [z ++], "DESTROYERS"); strcpy (submenu2names [z ++], "OILRIG"); strcpy (submenu2names [z ++], "CRUISER"); strcpy (submenu2names [z ++], "RADAR BASE"); strcpy (submenu2names [z ++], "CANYON BATTLE"); strcpy (submenu2names [z ++], "TUNNEL"); strcpy (submenu2names [z ++], "MAIN BASE"); strcpy (submenu2names [z ++], "TURRETS"); strcpy (submenu2names [z ++], "MOON BATTLE"); strcpy (submenu2names [z ++], "ELITE DOGFIGHT"); strcpy (submenu2names [z ++], "SNEAKING"); xf = xsubmenu; yf = ysubmenu - 2; xfstep = 12; yfstep = 0.8; for (i = 0; i < z; i ++) { button = new Button (submenu2names [i]); button->setFunction (callbackCampaign); button->setBounds (xf, yf, xfstep, yfstep - 0.1); yf -= yfstep; submenu [2]->add (button); } campaignstartid = submenu [2]->components [0]->id; xf = xsubmenu; yf = ysubmenu; yfstep = 1; button = new Button ("PILOTS RANKING"); button->setFunction (callbackPilots); button->setBounds (xf, yf, xfstep - 0.2, yfstep - 0.1); submenu [2]->add (button); xf += xfstep; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register options submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = xsubmenu; yf = 12; xfstep = 4.6; strcpy (optmenunames [0], "VIDEO"); strcpy (optmenunames [1], "AUDIO"); strcpy (optmenunames [2], "GAME"); for (i = 0; i < 3; i ++) { optmenu [i] = new Container (); allmenus.add (optmenu [i]); } for (i = 0; i < 3; i ++) { optbutton [i] = new Button (optmenunames [i]); optbutton [i]->setBounds (xf, yf, xfstep - 0.2, 1); xf += xfstep; optbutton [i]->setFunction (callbackMainMenu); submenu [3]->add (optbutton [i]); } currentoptmenu = optmenu [0]; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register video options submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ float xftab = 3; xf = xsubmenu; yf = 10; xfstep = 13.6; yfstep = 1; button = new Button ("QUALITY"); button->setFunction (callbackQuality); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); sprintf (buf, "%d", quality); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; button = new Button ("VIEW"); button->setFunction (callbackView); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); sprintf (buf, "%d", (int) view); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; button = new Button ("DITHERING"); button->setFunction (callbackDithering); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); if (dithering) strcpy (buf, "ON"); else strcpy (buf, "OFF"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; button = new Button ("ANTIALIASING"); button->setFunction (callbackAntialiasing); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); if (antialiasing) strcpy (buf, "ON"); else strcpy (buf, "OFF"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; button = new Button ("SPECIAL EFFECTS"); button->setFunction (callbackSpecialEffects); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); if (specialeffects) strcpy (buf, "ON"); else strcpy (buf, "OFF"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; button = new Button ("DYN LIGHTING"); button->setFunction (callbackDynamicLighting); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); if (dynamiclighting) strcpy (buf, "ON"); else strcpy (buf, "OFF"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; button = new Button ("BRIGHTNESS"); button->setFunction (callbackBrightness); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); sprintf (buf, "%d%%", brightness); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; yf -= yfstep / 2; sprintf (buf, "NEED RESTART:"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf, yf, 2, yfstep - 0.3); optmenu [0]->add (label); yf -= yfstep; button = new Button ("RESOLUTION"); button->setFunction (callbackResolution); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); sprintf (buf, "%d*%d", wantwidth, wantheight); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab * 2, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; button = new Button ("FULLSCREEN"); button->setFunction (callbackFullscreen); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [0]->add (button); if (wantfullscreen) sprintf (buf, "YES"); else sprintf (buf, "NO"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [0]->add (label); yf -= yfstep; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register sound options submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ yf = 10; xfstep = 13.6; yfstep = 1; #ifdef USE_GLUT textfield = new TextField ("PLEASE INSTALL SDL AND\nSDLMIXER AND RECOMIPLE\nGL-117 TO ENABLE SOUND\nAND MUSIC", 0.6); textfield->setBounds (xf, yf, xfstep, 0.6 * 4); optmenu [1]->add (textfield); yf -= 0.6 * 4; #else button = new Button ("SOUND VOLUME"); button->setFunction (callbackSound); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [1]->add (button); if (sound->audio) sprintf (buf, "%d%%", volumesound); else sprintf (buf, "N/A"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [1]->add (label); yf -= yfstep; button = new Button ("MUSIC VOLUME"); button->setFunction (callbackMusic); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [1]->add (button); if (sound->audio) sprintf (buf, "%d%%", volumemusic); else sprintf (buf, "N/A"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [1]->add (label); yf -= yfstep; if (!sound->audio) { optmenu [1]->components [0]->setActive (false); optmenu [1]->components [1]->setActive (false); optmenu [1]->components [2]->setActive (false); optmenu [1]->components [3]->setActive (false); } #endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register controls options submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xftab = 6.8; xf = xsubmenu; yf = 10; xfstep = 13.5; yfstep = 1; button = new Button ("DIFFICULTY"); button->setFunction (callbackDifficulty); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [2]->add (button); if (difficulty == 0) sprintf (buf, "%s", "EASY"); else if (difficulty == 1) sprintf (buf, "%s", "NORMAL"); else if (difficulty == 2) sprintf (buf, "%s", "HARD"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [2]->add (label); yf -= yfstep; button = new Button ("PHYSICS"); button->setFunction (callbackPhysics); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [2]->add (button); if (!physics) sprintf (buf, "%s", "ACTION"); else sprintf (buf, "%s", "SIMULATION"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [2]->add (label); yf -= yfstep; button = new Button ("CONTROLS"); button->setFunction (callbackControls); button->setBounds (xf, yf, xfstep, yfstep - 0.1); optmenu [2]->add (button); textControls (buf); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); optmenu [2]->add (label); yf -= yfstep; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register keyboard control submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = xsubmenu + 1; yf = ysubmenu - 6; xfstep = 12.5; yfstep = 0.8; for (i = 0; i < 3; i ++) { controlsmenu [i] = new Container (); allmenus.add (controlsmenu [i]); } label = new Label ("ROLL: \t LEFT, RIGHT"); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [0]->add (label); yf -= yfstep; label = new Label ("ELEVATOR: \t UP, DOWN"); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [0]->add (label); yf -= yfstep; label = new Label ("RUDDER: \t LSHIFT+ROLL"); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [0]->add (label); yf -= yfstep; label = new Label ("THROTTLE: \t 1...9"); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [0]->add (label); yf -= yfstep; label = new Label ("CAMERA: \t F1...F8"); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [0]->add (label); yf -= yfstep; z = 0; strcpy (controlsmenu0names [z ++], "FIRE CANNON"); strcpy (controlsmenu0names [z ++], "FIRE MISSILE"); strcpy (controlsmenu0names [z ++], "DROP FLARE"); strcpy (controlsmenu0names [z ++], "DROP CHAFF"); strcpy (controlsmenu0names [z ++], "SELECT MISSILE"); strcpy (controlsmenu0names [z ++], "TARGET NEAREST"); strcpy (controlsmenu0names [z ++], "TARGET LOCKING"); strcpy (controlsmenu0names [z ++], "TARGET NEXT"); strcpy (controlsmenu0names [z ++], "TARGET PREVIOUS"); strcpy (controlsmenu0names [z ++], "INC THRUST"); strcpy (controlsmenu0names [z ++], "DEC THRUST"); int keys [11]; keys [0] = key_firecannon; keys [1] = key_firemissile; keys [2] = key_dropflare; keys [3] = key_dropchaff; keys [4] = key_selectmissile; keys [5] = key_targetnearest; keys [6] = key_targetlocking; keys [7] = key_targetnext; keys [8] = key_targetprevious; keys [9] = key_thrustup; keys [10] = key_thrustdown; yf -= 0.5; for (i = 0; i < 11; i ++) { editkey = new EditKey (controlsmenu0names [i]); editkey->setKey (keys [i]); editkey->setFunction (callbackKeyboard); editkey->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [0]->add (editkey); yf -= yfstep; } yf -= 1; yfstep = 1.0; button = new Button ("LOAD DEFAULTS"); button->setFunction (callbackDefaults); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [0]->add (button); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register mouse control submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xftab = 3.5; xf = xsubmenu + 1; yf = ysubmenu - 6; xfstep = 12.5; yfstep = 0.8; button = new Button ("SENSITIVITY"); button->setFunction (callbackMouseSensitivity); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (button); sprintf (buf, "%d%%", (int) mouse_sensitivity); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); controlsmenu [1]->add (label); yf -= yfstep; button = new Button ("REVERSE"); button->setFunction (callbackMouseReverse); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (button); if (mouse_reverse) sprintf (buf, "ON"); else sprintf (buf, "OFF"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); controlsmenu [1]->add (label); yf -= yfstep; button = new Button ("RELATIVE"); button->setFunction (callbackMouseRelative); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (button); if (mouse_relative) sprintf (buf, "ON"); else sprintf (buf, "OFF"); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); controlsmenu [1]->add (label); yf -= yfstep; button = new Button ("AUTORUDDER"); button->setFunction (callbackMouseAutorudder); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (button); sprintf (buf, "%d%%", mouse_autorudder); label = new Label (buf); label->setTransparent (true); label->setBounds (xf + xfstep - xftab, yf, 2, yfstep - 0.1); controlsmenu [1]->add (label); yf -= yfstep; yf -= 0.5; textMouseButton (buf2, mouse_firecannon); sprintf (buf, "FIRE CANNON: \t %s", buf2); label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (label); yf -= yfstep; textMouseButton (buf2, mouse_firemissile); sprintf (buf, "FIRE MISSILE: \t %s", buf2); label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (label); yf -= yfstep; textMouseButton (buf2, mouse_selectmissile); sprintf (buf, "SELECT MISSILE: \t %s", buf2); label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (label); yf -= yfstep; yf -= 1; yfstep = 1.0; button = new Button ("LOAD DEFAULTS"); button->setFunction (callbackMouseDefaults); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [1]->add (button); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register joystick control submenu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #ifndef USE_GLUT char joystr [4]; xf = xsubmenu + 1; yf = ysubmenu - 6; xfstep = 12.5; yfstep = 0.8; button = new Button ("AILERON"); button->setFunction (callbackJoystickAxis); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (button); setJoystickAxisString (joystick_aileron, joystr); label = new Label (joystr); label->setBounds (xf + xfstep - xftab, yf, xftab, yfstep - 0.1); label->setTransparent (true); controlsmenu [2]->add (label); yf -= yfstep; button = new Button ("ELEVATOR"); button->setFunction (callbackJoystickAxis); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (button); setJoystickAxisString (joystick_elevator, joystr); label = new Label (joystr); label->setBounds (xf + xfstep - xftab, yf, xftab, yfstep - 0.1); label->setTransparent (true); controlsmenu [2]->add (label); yf -= yfstep; button = new Button ("THROTTLE"); button->setFunction (callbackJoystickAxis); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (button); setJoystickAxisString (joystick_throttle, joystr); label = new Label (joystr); label->setBounds (xf + xfstep - xftab, yf, xftab, yfstep - 0.1); label->setTransparent (true); controlsmenu [2]->add (label); yf -= yfstep; button = new Button ("RUDDER"); button->setFunction (callbackJoystickAxis); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (button); setJoystickAxisString (joystick_rudder, joystr); label = new Label (joystr); label->setBounds (xf + xfstep - xftab, yf, xftab, yfstep - 0.1); label->setTransparent (true); controlsmenu [2]->add (label); yf -= yfstep; button = new Button ("VIEW X"); button->setFunction (callbackJoystickAxis); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (button); setJoystickAxisString (joystick_view_x, joystr); label = new Label (joystr); label->setBounds (xf + xfstep - xftab, yf, xftab, yfstep - 0.1); label->setTransparent (true); controlsmenu [2]->add (label); yf -= yfstep; button = new Button ("VIEW Y"); button->setFunction (callbackJoystickAxis); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (button); setJoystickAxisString (joystick_view_y, joystr); label = new Label (joystr); label->setBounds (xf + xfstep - xftab, yf, xftab, yfstep - 0.1); label->setTransparent (true); controlsmenu [2]->add (label); yf -= yfstep; int buttons [11]; buttons [0] = joystick_firecannon; buttons [1] = joystick_firemissile; buttons [2] = joystick_dropflare; buttons [3] = joystick_dropchaff; buttons [4] = joystick_selectmissile; buttons [5] = joystick_targetnearest; buttons [6] = joystick_targetlocking; buttons [7] = joystick_targetnext; buttons [8] = joystick_targetprevious; buttons [9] = joystick_thrustup; buttons [10] = joystick_thrustdown; yf -= 0.5; for (i = 0; i < 11; i ++) { editjoystick = new EditJoystick (controlsmenu0names [i]); editjoystick->setButton (buttons [i]); editjoystick->setFunction (callbackJoystick); editjoystick->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (editjoystick); yf -= yfstep; } yf -= 1; yfstep = 1.0; button = new Button ("LOAD DEFAULTS"); button->setFunction (callbackDefaultsJoystick); button->setBounds (xf, yf, xfstep, yfstep - 0.1); controlsmenu [2]->add (button); #endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register top pilots menu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = -10; yf = 9; xfstep = 20; yfstep = 1.2; sprintf (buf, " PILOTS RANKING"); label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); famemenu.add (label); yf -= yfstep + 0.25; yfstep = 1.0; textfield = new TextField ("", yfstep - 0.1); textfield->setBounds (xf, yf, xfstep, (yfstep - 0.1) * 13); famemenu.add (textfield); yf -= yfstep * 13; yfstep = 1.1; sprintf (buf, " BACK TO MAIN MENU"); button = new Button (buf); button->setBounds (xf, yf, xfstep, yfstep - 0.1); button->setFunction (callbackSwitchMainMenu); famemenu.add (button); yf -= yfstep + 0.25; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register fighter menu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = -10; yf = 12; xfstep = 20; yfstep = 1.2; sprintf (buf, " FIGHTER INFO"); label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); fightermenu.add (label); yf -= yfstep + 0.25; yfstep = 1.0; buf [0] = 0; label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); fightermenu.add (label); yf -= yfstep + 0.25; yfstep = 1.1; textfield = new TextField ("", yfstep - 0.1); textfield->setBounds (xf, yf, xfstep, (yfstep - 0.1) * 5 + 0.15); fightermenu.add (textfield); yf -= yfstep * 5 + 0.05; button = new Button ("<"); button->setBounds (xf, yf, 1.5, 1.5); button->setFunction (callbackFighterPrev); fightermenu.add (button); button = new Button (">"); button->setBounds (-xf -1.5, yf, 1.5, 1.5); button->setFunction (callbackFighterNext); fightermenu.add (button); textfield = new TextField ("", yfstep - 0.1); textfield->setBounds (xf + 1.5, yf, 17, 12.5); fightermenu.add (textfield); yf -= 13; sprintf (buf, " BACK TO MAIN MENU"); button = new Button (buf); button->setBounds (xf, yf, xfstep, yfstep - 0.1); button->setFunction (callbackSwitchMainMenu); fightermenu.add (button); yf -= yfstep + 0.25; /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register mission menu +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = -12.5; yf = 11; xfstep = 25; yfstep = 1.3; buf [0] = 0; label = new Label (buf); label->setBounds (xf, yf, xfstep, yfstep - 0.1); missionmenu.add (label); yf -= yfstep + 0.15; yfstep = 1.0; buf [0] = 0; label = new Label (buf); label->setBounds (xf, yf, xfstep, 3.5); missionmenu.add (label); yf -= 3.75; buf [0] = 0; label = new Label (buf); label->setBounds (xf, yf, xfstep / 2 - 0.1, 5.7); missionmenu.add (label); buf [0] = 0; label = new Label (buf); label->setBounds (xf + xfstep / 2 + 0.1, yf, xfstep / 2 - 0.1, 5.7); missionmenu.add (label); yf -= 5.95; buf [0] = 0; label = new Label (buf); label->setBounds (xf, yf, xfstep / 2 - 0.1, 6.8); missionmenu.add (label); buf [0] = 0; label = new Label (buf); label->setBounds (xf + xfstep / 2 + 0.1, yf, xfstep / 2 - 0.1, 6.8); missionmenu.add (label); yf -= 7.15; yfstep = 1.0; button = new Button (" BACK TO MAIN MENU"); button->setBounds (xf, yf, xfstep / 2 - 0.1, yfstep - 0.1); button->setFunction (callbackSwitchMainMenu); missionmenu.add (button); button = new Button (" START MISSION"); button->setBounds (xf + xfstep / 2 + 0.1, yf, xfstep / 2 - 0.1, yfstep - 0.1); button->setFunction (callbackSwitchStartMission); missionmenu.add (button); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register quit dialog +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = -6; yf = 2; xfstep = 12; yfstep = 1.2; buf [0] = 0; label = new Label (buf); label->setBounds (xf, yf, xfstep, 3); quitmenu.add (label); yf -= 3.25; yfstep = 1.0; xfstep = 12; button = new Button (" YES"); button->setBounds (xf, yf, xfstep / 2 - 0.1, yfstep - 0.1); button->setFunction (callbackQuitNow); quitmenu.add (button); button = new Button (" NO"); button->setBounds (xf + xfstep / 2 + 0.1, yf, xfstep / 2 - 0.1, yfstep - 0.1); button->setFunction (callbackSwitchMainMenu); quitmenu.add (button); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Register stats dialog +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ xf = -10; yf = 9; xfstep = 20; yfstep = 1.2; buf [0] = 0; textfield = new TextField (buf, 1); textfield->setBounds (xf, yf, xfstep, 15.8); statsmenu.add (textfield); yf -= 16; yfstep = 1.0; xfstep = 20; button = new Button (" CONTINUE"); button->setBounds (xf, yf, xfstep, yfstep - 0.1); button->setFunction (callbackStats); statsmenu.add (button); famemenu.setVisible (false); fightermenu.setVisible (false); missionmenu.setVisible (false); quitmenu.setVisible (false); statsmenu.setVisible (false); allmenus.setVisible (false); allmenus.visible = true; allmenus.components [0]->setVisible (true); } /**************************************************************************** GL-117 ENTRY POINT ****************************************************************************/ int main (int argc, char **argv) { char buf [STDSIZE]; // temp buffer checkargs (argc, argv); // process command line parameters dirs = new Dirs (argv [0]); // get data directory (DATADIR, defined via autoconf) sprintf (buf, "Startup %s, %s ... ", argv [0], VERSIONSTRING); display (buf, LOG_MOST); #ifdef _MSC_VER display ("Windows detected ", LOG_MOST); #endif display ("Getting directory locations", LOG_ALL); if (!load_config ()) // try to load conf file (conf.cpp) and validate settings { // no conf file found => create new one display ("Creating new configuration", LOG_ALL); config_test (argc, argv); // do screen test firststart = true; // enable adjusting quality/view/graphics automatically by the game } save_config (); // save conf file (validated) load_configInterface (); // load interface settings from conf.interface and validate save_configInterface (); // save interface settings maploader = new MapLoader (); // here srand should be called to initialize the random number generator // this is currently done by grabbing random numbers via the init methods (not very elegant) server = NULL; client = NULL; display ("Creating/Loading pilots list", LOG_ALL); pilots = new PilotList (dirs->getSaves ("pilots")); // look at pilots.h // NO SDL FOUND => USE GLUT ONLY #ifdef USE_GLUT display ("Using GLUT only", LOG_MOST); if (!configinit) { glutInit (&argc, argv); glutInitDisplayMode (GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE); if (!setScreen (width, height, bpp, fullscreen)) { load_saveconfig (); if (!setScreen (width, height, bpp, fullscreen)) { sprintf (buf, "No working display mode %dx%d found", width, height); display (buf, LOG_FATAL); exit (EXIT_INIT); } } } display ("Calling main initialization method", LOG_ALL); myFirstInit (); display ("Creating dummy sound system, install SDL to enable sound", LOG_ALL); sound = new SoundSystem (); createMenu (); display ("Registering GLUT callbacks", LOG_ALL); glutReshapeFunc (myReshapeFunc); glutDisplayFunc (myDisplayFunc); glutKeyboardFunc (myKeyboardFunc); glutSpecialFunc (mySpecialFunc); glutPassiveMotionFunc (myPassiveMotionFunc); glutMouseFunc (myMouseFunc); glutIdleFunc (myIdleFunc); glutTimerFunc (20, myTimerFunc, 0); // parameters: visible angle, aspectracio, z-nearclip, z-farclip gluPerspective (visibleangle, (float) width / height, nearclippingplane * GLOBALSCALE, 50.0 * GLOBALSCALE); // no keyboard available with GLUT, as there are no KEY_DOWN/UP events if (controls <= 0) controls = CONTROLS_MOUSE; display ("Entering GLUT main loop", LOG_ALL); glutMainLoop(); // give controls to GLUT // SDL FOUND #else display ("Using SDL and GLUT", LOG_MOST); if (!configinit) if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) { sprintf (buf, "Couldn't initialize SDL: %s", SDL_GetError ()); display (buf, LOG_FATAL); exit (EXIT_INIT); } atexit (SDL_Quit); // SDL_NET INSTALLED? #ifdef HAVE_SDL_NET if (SDLNet_Init () == -1) // initialize SDL_net { sprintf (buf, "SDLNet_Init: %s", SDLNet_GetError ()); display (buf, LOG_FATAL); exit (EXIT_INIT); } display ("Using SDL_net", LOG_MOST); #endif if (!configinit) { if (!setScreen (width, height, bpp, fullscreen)) { load_saveconfig (); if (!setScreen (width, height, bpp, fullscreen)) { sprintf (buf, "No working display mode %dx%d found.", width, height); display (buf, LOG_FATAL); exit (EXIT_INIT); } } } display ("Setting SDL caption", LOG_ALL); SDL_WM_SetCaption ("GL-117", "GL-117"); // window name SDL_ShowCursor (0); display ("Creating sound system", LOG_ALL); sound = new SoundSystem (); // look at audio.cpp sound->volumesound = volumesound; sound->volumemusic = volumemusic; sound->setVolume (); // set all sound volumes sound->setVolumeMusic (); // set all music volumes display ("Playing startup music", LOG_ALL); sound->playMusic (1); #ifdef HAVE_SDL_MIXER Mix_HookMusicFinished (playRandomMusic); #endif display ("Calling main initialization method", LOG_ALL); myFirstInit (); myReshapeFunc (width, height); display ("Querying joystick", LOG_ALL); joysticks = SDL_NumJoysticks (); memset (jaxis, 0, maxjaxis * maxjoysticks * sizeof (int)); if (joysticks > 0) { for (i = 0; i < joysticks; i ++) { SDL_JoystickEventState (SDL_ENABLE); sdljoystick [i] = SDL_JoystickOpen (i); sdljoystickaxes [i] = SDL_JoystickNumAxes (sdljoystick [i]); sprintf (buf, "Joystick \"%s\" detected", SDL_JoystickName (i)); display (buf, LOG_MOST); } } else { display ("No joystick found", LOG_MOST); // sdljoystick [0] = NULL; if (controls == CONTROLS_JOYSTICK) // no joystick available, so switch to mouse controls controls = CONTROLS_MOUSE; } // disable joystick manually // joysticks = 0; /* joysticks = 2; sdljoystickaxes [0] = 4; sdljoystickaxes [1] = 2;*/ SDL_EnableUNICODE (1); SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); // Restrict mouse to SDL window // SDL_WM_GrabInput (SDL_GRAB_ON); createMenu (); display ("Entering SDL main loop (GLUT emulation)", LOG_ALL); sdlMainLoop (); // simulate GLUT's main loop (above) #endif return 0; // exit without signaling errors } #endif