+ static int oldmainmenu = mainmenu;
+
+ if (Input::MouseClicked() && (selected >= 0)) { // handling of the left mouse clic in menus
+ set<pair<int,int>>::iterator newscreenresolution;
+ switch (mainmenu) {
+ case 1:
+ case 2:
+ switch (selected) {
+ case 1:
+ if (gameon) { //resume
+ mainmenu = 0;
+ pause_sound(stream_menutheme);
+ resume_stream(leveltheme);
+ } else { //new game
+ fireSound(firestartsound);
+ flash();
+ mainmenu = (accountactive ? 5 : 7);
+ selected = -1;
+ }
+ break;
+ case 2: //options
+ fireSound();
+ flash();
+ mainmenu = 3;
+ if (newdetail > 2)
+ newdetail = detail;
+ if (newdetail < 0)
+ newdetail = detail;
+ if (newscreenwidth > 3000)
+ newscreenwidth = screenwidth;
+ if (newscreenwidth < 0)
+ newscreenwidth = screenwidth;
+ if (newscreenheight > 3000)
+ newscreenheight = screenheight;
+ if (newscreenheight < 0)
+ newscreenheight = screenheight;
+ break;
+ case 3:
+ fireSound();
+ flash();
+ if (gameon) { //end game
+ gameon = 0;
+ mainmenu = 1;
+ } else { //quit
+ tryquit = 1;
+ pause_sound(stream_menutheme);
+ }
+ break;
+ }
+ break;
+ case 3:
+ fireSound();
+ switch (selected) {
+ case 0:
+ newscreenresolution = resolutions.find(make_pair(newscreenwidth, newscreenheight));
+ /* Next one (end() + 1 is also end() so the ++ is safe even if it was not found) */
+ newscreenresolution++;
+ if (newscreenresolution == resolutions.end()) {
+ /* It was the last one (or not found), go back to the beginning */
+ newscreenresolution = resolutions.begin();
+ }
+ newscreenwidth = newscreenresolution->first;
+ newscreenheight = newscreenresolution->second;
+ break;
+ case 1:
+ newdetail++;
+ if (newdetail > 2)
+ newdetail = 0;
+ break;
+ case 2:
+ bloodtoggle++;
+ if (bloodtoggle > 2)
+ bloodtoggle = 0;
+ break;
+ case 3:
+ difficulty++;
+ if (difficulty > 2)
+ difficulty = 0;
+ break;
+ case 4:
+ ismotionblur = !ismotionblur;
+ break;
+ case 5:
+ decals = !decals;
+ break;
+ case 6:
+ musictoggle = !musictoggle;
+ if (musictoggle) {
+ emit_stream_np(stream_menutheme);
+ } else {
+ pause_sound(leveltheme);
+ pause_sound(stream_fighttheme);
+ pause_sound(stream_menutheme);
+
+ for (int i = 0; i < 4; i++) {
+ oldmusicvolume[i] = 0;
+ musicvolume[i] = 0;
+ }
+ }
+ break;
+ case 7: // controls
+ flash();
+ mainmenu = 4;
+ selected = -1;
+ keyselect = -1;
+ break;
+ case 8:
+ flash();
+ SaveSettings();
+ mainmenu = gameon ? 2 : 1;
+ break;
+ case 9:
+ invertmouse = !invertmouse;
+ break;
+ case 10:
+ usermousesensitivity += .2;
+ if (usermousesensitivity > 2)
+ usermousesensitivity = .2;
+ break;
+ case 11:
+ volume += .1f;
+ if (volume > 1.0001f)
+ volume = 0;
+ OPENAL_SetSFXMasterVolume((int)(volume * 255));
+ break;
+ case 12:
+ flash();
+ newstereomode = stereomode;
+ mainmenu = 18;
+ keyselect = -1;
+ break;
+ case 13:
+ showdamagebar = !showdamagebar;
+ break;
+ case 14:
+ toggleFullscreen();
+ break;
+ }
+ updateSettingsMenu();
+ break;
+ case 4:
+ if (!waiting) {
+ fireSound();
+ if (selected < (debugmode ? 10 : 9) && keyselect == -1)
+ keyselect = selected;
+ if (keyselect != -1)
+ setKeySelected();
+ if (selected == (debugmode ? 10 : 9)) {
+ flash();
+ mainmenu = 3;
+ }
+ }
+ updateControlsMenu();
+ break;
+ case 5:
+ fireSound();
+ flash();
+ if ((selected - NB_CAMPAIGN_MENU_ITEM >= accountactive->getCampaignChoicesMade())) {
+ startbonustotal = 0;
+
+ loading = 2;
+ loadtime = 0;
+ targetlevel = 7;
+ if (firstload)
+ TickOnceAfter();
+ else
+ LoadStuff();
+ whichchoice = selected - NB_CAMPAIGN_MENU_ITEM - accountactive->getCampaignChoicesMade();
+ actuallevel = (accountactive->getCampaignChoicesMade() > 0 ? campaignlevels[accountactive->getCampaignChoicesMade() - 1].nextlevel[whichchoice] : 0);
+ visibleloading = 1;
+ stillloading = 1;
+ Loadlevel(campaignlevels[actuallevel].mapname.c_str());
+ campaign = 1;
+ mainmenu = 0;
+ gameon = 1;
+ pause_sound(stream_menutheme);
+ }
+ switch (selected) {
+ case 1:
+ startbonustotal = 0;
+
+ loading = 2;
+ loadtime = 0;
+ targetlevel = -1;
+ if (firstload) {
+ TickOnceAfter();
+ } else
+ LoadStuff();
+ Loadlevel(-1);
+
+ mainmenu = 0;
+ gameon = 1;
+ pause_sound(stream_menutheme);
+ break;
+ case 2:
+ mainmenu = 9;
+ break;
+ case 3:
+ mainmenu = 6;
+ break;
+ case 4:
+ mainmenu = (gameon ? 2 : 1);
+ break;
+ case 5:
+ mainmenu = 7;
+ break;
+ case 6:
+ vector<string> campaigns = ListCampaigns();
+ vector<string>::iterator c;
+ if ((c = find(campaigns.begin(), campaigns.end(), accountactive->getCurrentCampaign())) == campaigns.end()) {
+ if (!campaigns.empty())
+ accountactive->setCurrentCampaign(campaigns.front());
+ } else {
+ c++;
+ if (c == campaigns.end())
+ c = campaigns.begin();
+ accountactive->setCurrentCampaign(*c);
+ }
+ LoadMenu();
+ break;
+ }
+ break;
+ case 6:
+ fireSound();
+ if (selected == 1) {
+ flash();
+ accountactive = Account::destroy(accountactive);
+ mainmenu = 7;
+ } else if (selected == 2) {
+ flash();
+ mainmenu = 5;
+ }
+ break;
+ case 7:
+ fireSound();
+ if (selected == 0 && Account::getNbAccounts() < 8) {
+ entername = 1;
+ } else if (selected < Account::getNbAccounts() + 1) {
+ flash();
+ mainmenu = 5;
+ accountactive = Account::get(selected - 1);
+ } else if (selected == Account::getNbAccounts() + 1) {
+ flash();
+ if (accountactive)
+ mainmenu = 5;
+ else
+ mainmenu = 1;
+ displaytext[0].clear();
+ displayselected = 0;
+ entername = 0;
+ }
+ break;
+ case 8:
+ fireSound();
+ flash();
+ if (selected <= 2)
+ accountactive->setDifficulty(selected);
+ mainmenu = 5;
+ break;
+ case 9:
+ if (selected < numchallengelevels && selected <= accountactive->getProgress()) {
+ fireSound();
+ flash();
+
+ startbonustotal = 0;
+
+ loading = 2;
+ loadtime = 0;
+ targetlevel = selected;
+ if (firstload)
+ TickOnceAfter();
+ else
+ LoadStuff();
+ Loadlevel(selected);
+ campaign = 0;
+
+ mainmenu = 0;
+ gameon = 1;
+ pause_sound(stream_menutheme);
+ }
+ if (selected == numchallengelevels) {
+ fireSound();
+ flash();
+ mainmenu = 5;
+ }
+ break;
+ case 10:
+ if (selected == 3) {
+ fireSound();
+ flash();
+ mainmenu = 5;
+ }
+ break;
+ case 18:
+ if (selected == 1)
+ stereoseparation += 0.001;
+ else {
+ fireSound();
+ if (selected == 0) {
+ newstereomode = (StereoMode)(newstereomode + 1);
+ while (!CanInitStereo(newstereomode)) {
+ printf("Failed to initialize mode %s (%i)\n", StereoModeName(newstereomode), newstereomode);
+ newstereomode = (StereoMode)(newstereomode + 1);
+ if (newstereomode >= stereoCount)
+ newstereomode = stereoNone;
+ }
+ } else if (selected == 2) {
+ stereoreverse = !stereoreverse;
+ } else if (selected == 3) {
+ flash();
+ mainmenu = 3;
+
+ stereomode = newstereomode;
+ InitStereo(stereomode);
+ }
+ }
+ updateStereoConfigMenu();
+ break;
+ }
+ }
+
+ if (Input::isKeyDown(SDL_SCANCODE_Q) && Input::isKeyDown(SDL_SCANCODE_LGUI)) {
+ tryquit = 1;
+ if (mainmenu == 3) {
+ SaveSettings();
+ }
+ }
+
+ OPENAL_SetFrequency(channels[stream_menutheme], 22050);
+
+ if (entername) {
+ inputText(displaytext[0], &displayselected);
+ if (!waiting) { // the input as finished
+ if (!displaytext[0].empty()) { // with enter
+ accountactive = Account::add(string(displaytext[0]));
+
+ mainmenu = 8;
+
+ flash();
+
+ fireSound(firestartsound);
+
+ displaytext[0].clear();
+
+ displayselected = 0;
+ }
+ entername = 0;
+ LoadMenu();
+ }
+
+ displayblinkdelay -= multiplier;
+ if (displayblinkdelay <= 0) {
+ displayblinkdelay = .3;
+ displayblink = 1 - displayblink;
+ }
+ }
+
+ if (entername) {
+ Menu::setText(0, displaytext[0], 20, 400, -1, -1);
+ Menu::setText(-2, displayblink ? "_" : "", 20 + displayselected * 10, 400, -1, -1);
+ }
+
+ if (oldmainmenu != mainmenu)
+ LoadMenu();
+ oldmainmenu = mainmenu;
+
+}
+
+void Game::Tick()
+{
+ static XYZ facing, flatfacing;
+ static int target;
+
+ for (int i = 0; i < 15; i++) {
+ displaytime[i] += multiplier;
+ }
+
+ keyboardfrozen = false;
+ Input::Tick();
+
+ if (Input::isKeyPressed(SDL_SCANCODE_F6)) {
+ if (Input::isKeyDown(SDL_SCANCODE_LSHIFT))
+ stereoreverse = true;
+ else
+ stereoreverse = false;
+
+ if (stereoreverse)
+ printf("Stereo reversed\n");
+ else
+ printf("Stereo unreversed\n");
+ }
+
+ if (Input::isKeyDown(SDL_SCANCODE_F7)) {
+ if (Input::isKeyDown(SDL_SCANCODE_LSHIFT))
+ stereoseparation -= 0.001;
+ else
+ stereoseparation -= 0.010;
+ printf("Stereo decreased increased to %f\n", stereoseparation);
+ }
+
+ if (Input::isKeyDown(SDL_SCANCODE_F8)) {
+ if (Input::isKeyDown(SDL_SCANCODE_LSHIFT))
+ stereoseparation += 0.001;
+ else
+ stereoseparation += 0.010;
+ printf("Stereo separation increased to %f\n", stereoseparation);
+ }
+
+
+ if (Input::isKeyPressed(SDL_SCANCODE_TAB) && tutoriallevel) {
+ if (tutorialstage != 51)
+ tutorialstagetime = tutorialmaxtime;
+ emit_sound_np(consolefailsound, 128.);
+ }
+
+ /*
+ Values of mainmenu :
+ 1 Main menu
+ 2 Menu pause (resume/end game)
+ 3 Option menu
+ 4 Controls configuration menu
+ 5 Main game menu (choose level or challenge)
+ 6 Deleting user menu
+ 7 User managment menu (select/add)
+ 8 Choose difficulty menu
+ 9 Challenge level selection menu
+ 10 End of the campaign congratulation (is that really a menu?)
+ 11 Same that 9 ??? => unused
+ 18 stereo configuration
+ */
+
+ if (!console) {
+ //campaign over?
+ if (mainmenu && endgame == 1)
+ mainmenu = 10;
+ //go to level select after completing a campaign level
+ if (campaign && winfreeze && mainmenu == 0 && campaignlevels[actuallevel].choosenext == 1) {
+ mainmenu = 5;
+ gameon = 0;
+ winfreeze = 0;
+ fireSound();
+ flash();
+ if (musictoggle) {
+ OPENAL_SetFrequency(OPENAL_ALL, 0.001);
+ emit_stream_np(stream_menutheme);
+ pause_sound(leveltheme);
+ }
+ LoadMenu();
+ }
+ //escape key pressed
+ if (Input::isKeyPressed(SDL_SCANCODE_ESCAPE) &&
+ (gameon || mainmenu == 0 || (mainmenu >= 3 && mainmenu != 8 && !(mainmenu == 7 && entername)))) {
+ selected = -1;
+ if (mainmenu == 0 && !winfreeze)
+ mainmenu = 2; //pause
+ else if (mainmenu == 1 || mainmenu == 2) {
+ mainmenu = 0; //unpause
+ }
+ //play menu theme
+ if (musictoggle && (mainmenu == 1 || mainmenu == 2)) {
+ OPENAL_SetFrequency(OPENAL_ALL, 0.001);
+ emit_stream_np(stream_menutheme);
+ pause_sound(leveltheme);
+ }
+ //on resume, play level music
+ if (!mainmenu) {
+ pause_sound(stream_menutheme);
+ resume_stream(leveltheme);
+ }
+ //finished with settings menu
+ if (mainmenu == 3) {
+ SaveSettings();
+ }
+ //effects
+ if (mainmenu >= 3 && mainmenu != 8) {
+ fireSound();
+ flash();
+ }
+ //go back
+ switch (mainmenu) {
+ case 3:
+ case 5:
+ mainmenu = gameon ? 2 : 1;
+ break;
+ case 4:
+ case 18:
+ mainmenu = 3;
+ break;
+ case 6:
+ case 7:
+ case 9:
+ case 10:
+ mainmenu = 5;
+ break;
+ }
+ }
+ }
+
+ if (mainmenu) {
+ MenuTick();
+ }
+
+ if (!mainmenu) {
+ if (hostile == 1)
+ hostiletime += multiplier;
+ else
+ hostiletime = 0;
+ if (!winfreeze)
+ leveltime += multiplier;
+
+ //keys
+ if (Input::isKeyPressed(SDL_SCANCODE_V) && debugmode) {
+ freeze = 1 - freeze;
+ if (freeze) {
+ OPENAL_SetFrequency(OPENAL_ALL, 0.001);
+ }
+ }
+
+ if (Input::isKeyPressed(consolekey) && debugmode) {
+ console = !console;
+ if (console) {
+ OPENAL_SetFrequency(OPENAL_ALL, 0.001);
+ } else {
+ freeze = 0;
+ waiting = false;
+ }
+ }
+
+ if (console)
+ freeze = 1;
+ if (console && !Input::isKeyDown(SDL_SCANCODE_LGUI)) {
+ inputText(consoletext[0], &consoleselected);
+ if (!waiting) {
+ if (!consoletext[0].empty()) {
+ cmd_dispatch(consoletext[0]);
+ for (int k = 14; k >= 1; k--) {
+ consoletext[k] = consoletext[k - 1];
+ }
+ consoletext[0].clear();
+ consoleselected = 0;
+ }
+ }
+
+ consoleblinkdelay -= multiplier;
+ if (consoleblinkdelay <= 0) {
+ consoleblinkdelay = .3;
+ consoleblink = 1 - consoleblink;
+ }
+ }
+
+
+
+ if (Input::isKeyDown(SDL_SCANCODE_Q) && Input::isKeyDown(SDL_SCANCODE_LGUI)) {
+ tryquit = 1;
+ if (mainmenu == 3) {
+ SaveSettings();
+ }
+ }
+
+ static int oldwinfreeze;
+ if (winfreeze && !oldwinfreeze) {
+ OPENAL_SetFrequency(OPENAL_ALL, 0.001);
+ emit_sound_np(consolesuccesssound);
+ }
+ if (winfreeze == 0)
+ oldwinfreeze = winfreeze;
+ else
+ oldwinfreeze++;
+
+ if ((Input::isKeyPressed(jumpkey) || Input::isKeyPressed(SDL_SCANCODE_SPACE)) && !campaign)
+ if (winfreeze)
+ winfreeze = 0;
+ if ((Input::isKeyDown(SDL_SCANCODE_ESCAPE)) && !campaign && gameon) {
+ if (console) {
+ console = false;
+ freeze = 0;
+ } else if (winfreeze) {
+ mainmenu = 9;
+ gameon = 0;
+ }
+ }
+
+
+
+ if (!freeze && !winfreeze && !(mainmenu && gameon) && (gameon || !gamestarted)) {
+
+ //dialogues
+ static float talkdelay = 0;
+
+ if (indialogue != -1)
+ talkdelay = 1;
+ talkdelay -= multiplier;
+
+ if (talkdelay <= 0 && indialogue == -1 && animation[Person::players[0]->animTarget].height != highheight)
+ for (int i = 0; i < numdialogues; i++) {
+ unsigned realdialoguetype;
+ bool special;
+ /* FIXME - Seems like modulo done with ifs */
+ if (dialoguetype[i] > 49) {
+ realdialoguetype = dialoguetype[i] - 50;
+ special = 1;
+ } else if (dialoguetype[i] > 39) {
+ realdialoguetype = dialoguetype[i] - 40;
+ special = 1;
+ } else if (dialoguetype[i] > 29) {
+ realdialoguetype = dialoguetype[i] - 30;
+ special = 1;
+ } else if (dialoguetype[i] > 19) {
+ realdialoguetype = dialoguetype[i] - 20;
+ special = 1;
+ } else if (dialoguetype[i] > 9) {
+ realdialoguetype = dialoguetype[i] - 10;
+ special = 1;
+ } else {
+ realdialoguetype = dialoguetype[i];
+ special = 0;
+ }
+ if ((!hostile || dialoguetype[i] > 40 && dialoguetype[i] < 50) &&
+ realdialoguetype < Person::players.size() &&
+ realdialoguetype > 0 &&
+ (dialoguegonethrough[i] == 0 || !special) &&
+ (special || Input::isKeyPressed(attackkey))) {
+ if (distsq(&Person::players[0]->coords, &Person::players[realdialoguetype]->coords) < 6 ||
+ Person::players[realdialoguetype]->howactive >= typedead1 ||
+ dialoguetype[i] > 40 && dialoguetype[i] < 50) {
+ whichdialogue = i;
+ for (int j = 0; j < numdialogueboxes[whichdialogue]; j++) {
+ Person::players[participantfocus[whichdialogue][j]]->coords = participantlocation[whichdialogue][participantfocus[whichdialogue][j]];
+ Person::players[participantfocus[whichdialogue][j]]->yaw = participantyaw[whichdialogue][participantfocus[whichdialogue][j]];
+ Person::players[participantfocus[whichdialogue][j]]->targetyaw = participantyaw[whichdialogue][participantfocus[whichdialogue][j]];
+ Person::players[participantfocus[whichdialogue][j]]->velocity = 0;
+ Person::players[participantfocus[whichdialogue][j]]->animTarget = Person::players[participantfocus[whichdialogue][j]]->getIdle();
+ Person::players[participantfocus[whichdialogue][j]]->frameTarget = 0;