// 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 #include "Game.h" #include "misc.h" extern float multiplier; extern int thirdperson; extern bool visions; extern float soundscalefactor; extern unsigned int gSourceID[37]; extern Camera camera; extern float rad2deg; extern int environment; extern int slomo; extern struct Key keymap; void handleKey(Game* game, int key, int action, int mods) { if (action != GLFW_PRESS) return; auto& player = game->person[0]; if (key == GLFW_KEY_ESCAPE) { alSourceStop(gSourceID[rainsound]); alSourceStop(gSourceID[visionsound]); if (game->musictoggle) { alSourceStop(gSourceID[game->whichsong]); game->whichsong = mainmenusong; alSourcef(gSourceID[game->whichsong], AL_PITCH, 1); alSourcePlay(gSourceID[game->whichsong]); } alSourcePlay(gSourceID[souloutsound]); setMenu(game, true); game->flashamount = 1.0f; game->flashr = game->flashg = game->flashb = 1.0f; } else if (key == keymap.dive) { 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 == keymap.reload) { if (player.whichgun != grenade && player.reloads[player.whichgun] > 0 && player.reloading <= 0) player.ammo = -1; } else if (key == keymap.aim) { player.aiming ^= 1; } else if (key == keymap.psychic_aim) { // Picking up gun from rag doll if (player.currentanimation == crouchanim && (!player.aiming || player.whichgun == nogun || player.whichgun == knife || player.whichgun == grenade)) { for (int i = 1; i < game->numpeople; ++i) { auto& person = game->person[i]; if (!person.skeleton.free || sqrlen(player.playercoords - person.averageloc) > 200) continue; auto soundpos = player.playercoords - camera.position; playSound(gSourceID[clicksound], soundpos.x, soundpos.y, soundpos.z); auto tmp_gun = player.whichgun; player.whichgun = person.whichgun; person.whichgun = tmp_gun; auto tmp_ammo = player.ammo; player.ammo = person.ammo; person.ammo = tmp_ammo; player.aiming = 1; player.aimamount = 0; break; } } else { game->flashamount = 0.5; game->flashr = 1; game->flashg = game->flashb = 0; alSourcePlay(gSourceID[souloutsound]); if (game->musictoggle) alSourcef(gSourceID[game->whichsong], AL_PITCH, 0.5f); slomo = 2; game->score -= 20; } } else if (key == keymap.psychic) { if (visions ^= 1) { game->flashamount = game->flashr = 1; game->flashg = game->flashb = 0; alSourceStop(gSourceID[visionsound]); alSourcePlay(gSourceID[souloutsound]); if (game->musictoggle) alSourcef(gSourceID[game->whichsong], AL_PITCH, 0.5f); alSourcePlay(gSourceID[visionsound]); player.oldplayercoords = player.playercoords; } else { game->flashamount = 1; game->flashr = game->flashg = game->flashb = 1; alSourceStop(gSourceID[visionsound]); alSourcePlay(gSourceID[soulinsound]); if (game->musictoggle) alSourcef(gSourceID[game->whichsong], AL_PITCH, 1.0f); XYZ towards = player.playercoords - player.oldplayercoords; if (towards.x || towards.z) { towards = normalize(towards); camera.rotation = asin(towards.x) * 180.0f / M_PI; if (towards.z > 0) camera.rotation = 180 - camera.rotation; camera.visrotation = camera.rotation; camera.oldrotation = camera.rotation; } player.playercoords = player.oldplayercoords; player.velocity = {}; } } else if (key == keymap.switch_view) { thirdperson = (thirdperson == 2) ? 0 : (thirdperson + 1); } if (!game->debug) return; if (key == keymap.skip) { game->timeremaining = 0; } else if (key == keymap.pause) { alSourcePlay(gSourceID[soulinsound]); game->paused = 1 - game->paused; } else if (key == keymap.slomo) { alSourcePlay(gSourceID[soulinsound]); if (game->musictoggle) alSourcef(gSourceID[game->whichsong], AL_PITCH, (slomo ^= 1) ? 0.5f : 1.0f); } else if (key == keymap.force) { auto facing = rotate({0, 0, -1}, -camera.rotation2, 0, 0); facing = rotate(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 || sqrlen(person.playercoords - player.playercoords) > 1000) continue; person.skeleton.free = 1; person.longdead = 1; for (auto& joint : person.skeleton.joints) { joint.position = rotate(joint.position, 0, person.playerrotation, 0); joint.position += person.playercoords; joint.realoldposition = joint.position; joint.velocity = rotate(joint.velocity, 0, person.playerrotation, 0); joint.velocity += person.velocity; joint.velocity += facing * 50; joint.velocity.x += randInt(-9, 9); joint.velocity.y += randInt(-9, 9); joint.velocity.z += randInt(-9, 9); } } } else if (key == keymap.switch_weapon) { if (player.grenphase) return; player.grenphase = 0; player.ammo = -1; player.whichgun++; if (player.whichgun > 7) player.whichgun = 0; player.reloads[player.whichgun] = 3; } } void setMenu(Game* game, bool val) { glfwSetInputMode(glfwGetCurrentContext(), GLFW_CURSOR, (game->menu = val) ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_DISABLED); } void eventLoop(Game* game) { auto start = glfwGetTime(); game->Tick(); game->DrawGLScene(); do multiplier = glfwGetTime() - start; while (multiplier < 1.0f / 69); if (visions && !game->menu) multiplier /= 3; if (slomo) multiplier /= 5; if (game->paused) multiplier = 0; }