aboutsummaryrefslogblamecommitdiff
path: root/src/GameLoop.cpp
blob: 1691157299608703f4e048793650d92ae060a4b7 (plain) (tree)
1
2
3
4
5



                                          
                                         















                                                                         
                 
 
                        
                       
                   
                                   
                                    
                     
                     
               
                       
                 


                         
 
                                                         
 
                                 
                       



























































































                                                                                    
 


                                                 
                   
 
                     

                                                                         
                      
                        
                                        
                      
                        
                                                     







                                                                          
                      
                        
                                    

                                                                       
                                                      
 




                                                                            
                                         

                                                 
 



                                                                           
                                                                       


                                                                           






                                                                            
                        
                                               
                              





                                                    
                      
         

 
                          
 
                                   




                                              





                                            
 
// 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;
}