// Event loop handler // Copyright (C) 2002 David Rosen // Copyright (C) 2003 Zachary Jack Slater // Copyright (C) 2003 Steven Fuller // Copyright (C) 2021 Nguyễn Gia Phong // // This file is part of Black Shades. // // Black Shades 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 3 of the License, or // (at your option) any later version. // // Black Shades 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 Black Shades. If not, see . #include "Game.h" extern float multiplier; extern int thirdperson; extern int visions; extern unsigned int gSourceID[100]; extern unsigned int gSampleSet[100]; extern Camera camera; extern float rad2deg; extern Fog fog; extern int environment; extern int slomo; extern int aimkey; extern int psychicaimkey; extern int psychickey; void handleKey(Game* game, int key, int action, int mods) { if (action != GLFW_PRESS) return; if (game->mainmenu) { if (key == GLFW_KEY_SPACE) game->mainmenu = 0; return; } auto& player = game->person[0]; if (key == GLFW_KEY_ESCAPE) { alSourcePause(gSourceID[rainsound]); game->mainmenu = 1; alSourcePlay(gSourceID[souloutsound]); game->flashamount = 1.0f; game->flashr = game->flashg = game->flashb = 1.0f; alSourceStop(gSourceID[visionsound]); game->whichsong = mainmenusong; alSourceStop(gSourceID[knifesong]); alSourceStop(gSourceID[shootsong]); alSourceStop(gSourceID[zombiesong]); alSourceStop(gSourceID[mainmenusong]); alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 0); alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 0); alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 0); alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 0); alSourcePlay(gSourceID[game->whichsong]); alSourcef(gSourceID[game->whichsong], AL_MIN_GAIN, 1); } else if (key == GLFW_KEY_L) { game->lasersight ^= 1; } else if (key == GLFW_KEY_SPACE) { if (player.playerrotation == player.playerlowrotation && player.targetanimation == joganim && player.currentanimation == joganim && !player.backwardsanim && !visions) { player.targetanimation = diveanim; player.targetframe = player.target = 0; player.aimamount = 0; } } else if (key == GLFW_KEY_R) { if (player.reloads[player.whichgun] > 0 && player.reloading <= 0) player.ammo = -1; } else if (key == aimkey) { player.aiming ^= 1; } else if (key == psychicaimkey) { game->flashamount = 0.5; game->flashr = 1; game->flashg = game->flashb = 0; alSourcePlay(gSourceID[souloutsound]); slomo = 2; game->score -= 20; alSourcef(gSourceID[knifesong], AL_PITCH, 0.5f); alSourcef(gSourceID[shootsong], AL_PITCH, 0.5f); alSourcef(gSourceID[zombiesong], AL_PITCH, 0.5f); } else if (key == psychickey) { if (visions ^= 1) { game->flashamount = game->flashr = 1; game->flashg = game->flashb = 0; alSourceStop(gSourceID[visionsound]); alSourcePlay(gSourceID[souloutsound]); alSourcef(gSourceID[knifesong], AL_PITCH, 0.5f); alSourcef(gSourceID[shootsong], AL_PITCH, 0.5f); alSourcef(gSourceID[zombiesong], AL_PITCH, 0.5f); alSourcePlay(gSourceID[visionsound]); game->bodycoords = player.oldplayercoords; } else { game->flashamount = 1; game->flashr = game->flashg = game->flashb = 1; alSourceStop(gSourceID[visionsound]); alSourcePlay(gSourceID[soulinsound]); alSourcef(gSourceID[knifesong], AL_PITCH, 1.0f); alSourcef(gSourceID[shootsong], AL_PITCH, 1.0f); alSourcef(gSourceID[zombiesong], AL_PITCH, 1.0f); XYZ towards = player.playercoords - game->bodycoords; if (towards.x || towards.z) { Normalise(&towards); camera.rotation = RadiansToDegrees(asin(towards.x)); if (towards.z > 0) camera.rotation = 180 - camera.rotation; camera.visrotation = camera.rotation; camera.oldrotation = camera.rotation; } player.playercoords = game->bodycoords; player.oldplayercoords = game->bodycoords; player.velocity = 0; } } if (!game->debug) return; const auto shift = mods & GLFW_MOD_SHIFT; XYZ facing; switch(key) { case GLFW_KEY_TAB: thirdperson = (thirdperson == 2) ? 0 : (thirdperson + 1); break; case GLFW_KEY_K: game->timeremaining = 0; break; case GLFW_KEY_B: alSourcePlay(gSourceID[soulinsound]); if (shift) { game->paused = 1 - game->paused; } else { auto pitch = (slomo ^= 1) ? 0.5f : 1.0f; alSourcef(gSourceID[knifesong], AL_PITCH, pitch); alSourcef(gSourceID[shootsong], AL_PITCH, pitch); alSourcef(gSourceID[zombiesong], AL_PITCH, pitch); } break; case GLFW_KEY_F: facing = {0, 0, -1}; facing = DoRotation(facing, -camera.rotation2, 0, 0); facing = DoRotation(facing, 0, 0 - camera.rotation, 0); alSourcePlay(gSourceID[souloutsound]); for (int i = 1; i < game->numpeople; i++) { auto& person = game->person[i]; if (person.skeleton.free == 1 || findDistancefast(person.playercoords, player.playercoords) > 1000) continue; person.skeleton.free = 1; person.longdead = 1; for (auto& joint : person.skeleton.joints) { joint.position = DoRotation(joint.position, 0, person.playerrotation, 0); joint.position += person.playercoords; joint.realoldposition = joint.position; joint.velocity = DoRotation(joint.velocity, 0, person.playerrotation, 0); joint.velocity += person.velocity; joint.velocity += facing * 50; joint.velocity.x += abs(Random() % 20) - 10; joint.velocity.y += abs(Random() % 20) - 10; joint.velocity.z += abs(Random() % 20) - 10; } } break; case GLFW_KEY_X: if (!shift || player.grenphase) break; player.ammo = -1; player.whichgun++; player.grenphase = 0; player.reloads[player.whichgun] = 3; if (player.whichgun > 7) player.whichgun = 0; break; } } void eventLoop(Game* game) { auto start = glfwGetTime(); GLfloat oldmult = multiplier; int colaccuracy = min(game->sps, game->sps / game->framespersecond + 1.0f); multiplier /= colaccuracy; for (int i = 0; i < (int) (colaccuracy + 0.5f); i++) game->Tick(); auto window = glfwGetCurrentContext(); if (game->DrawGLScene()) glfwSwapBuffers(window); else glfwSetWindowShouldClose(window, GLFW_TRUE); multiplier = oldmult; do game->framespersecond = 1.0 / (glfwGetTime() - start); while (game->framespersecond > game->maxfps); game->multiplier5 = game->multiplier4; game->multiplier4 = game->multiplier3; game->multiplier3 = game->multiplier2; game->multiplier2 = 1 / game->framespersecond; multiplier = (game->multiplier2 + game->multiplier3 + game->multiplier4 + game->multiplier5) / 4.0f; multiplier = min(max(multiplier, 0.00001f), 1.0f); if (visions == 1 && !game->mainmenu) multiplier /= 3; if (slomo) multiplier /= 5; if (game->paused) multiplier = 0; }