// 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 <https://www.gnu.org/licenses/>.
#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();
game->Tick();
game->DrawGLScene();
do multiplier = glfwGetTime() - start;
while (multiplier < 1.0f / 69);
if (visions == 1 && !game->mainmenu)
multiplier /= 3;
if (slomo)
multiplier /= 5;
if (game->paused)
multiplier = 0;
}