aboutsummaryrefslogblamecommitdiff
path: root/src/GameLoop.cpp
blob: ab8d545ec240c3bcb39ab23a4803be2c25a12888 (plain) (tree)



















                                                                         
                 

                         
                   
                                   
                                    
                     
                     
               
                       

                 
                                  
 

                       
 

                      
 









                                          
                              







                                                                  
                              




                                                     
                              





























                                                                                                            
                              






                                                          
         

 

                                



                                 
              
                                       
                                  
 

                                      

















                                               
                                      

                                      
                                      













                                      
                                      


                                      
                                      














                                          

                                                 
                                          
                                              
                                                   
                                                

                                                


                                                     

                                              











                                                             
 










                                               
                         
                                 
 
                                                      
                           

                                             
 
                                               
                                               
                    
                                                
         
 

                                                     

                                                            

 
                                     

                        















                                                                               
                                 
                                      
                         





                                            
         
 
 
                      
 
                                    
                      
                             

                        
                                       
                                                
 



                                                                              
                               
                                  
                                             
                    
                                     
                                     
 






















                                                                
                                     
                                                
                                                

                                                                    
                                                      
                                                 
                                                     
                                                 
                         

                 
                                                           
                                                            
                                     
                                                              
                                                                   
                                                             
                                                 
                                                           
                                                           
                                                            
                                                              
                                                                        
                                                                        
                                                                         
                                                                           
                                                           
                                                                        
                 
         
 
// Event loop handler
// Copyright (C) 2002  David Rosen
// Copyright (C) 2003  Zachary Jack Slater
// Copyright (C) 2003  Steven Fuller
//
// 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 double multiplier;
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;

void Game::HandleKeyDown(char key)
{
	if (mainmenu)
		return;

	ALfloat pitch;
	XYZ facing;

	switch(key) {
	case 'l':
		lasersight ^= 1;
		break;
	case 'k':
		if (debug)
			timeremaining = 0;
		break;
	case 'b':
		if (!debug)
			break;
		alSourcePlay(gSourceID[soulinsound]);
		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 'B':
		if (!debug)
			break;
		alSourcePlay(gSourceID[soulinsound]);
		paused = 1 - paused;
		break;
	case 'f':
		if (!debug)
			break;
		alSourcePlay(gSourceID[souloutsound]);

		facing = 0;
		facing.z = -1;
		facing = DoRotation(facing, -camera.rotation2, 0, 0);
		facing = DoRotation(facing, 0, 0 - camera.rotation, 0);

		for(int i = 1; i < numpeople; i++) {
			if (person[i].skeleton.free == 1
			    || findDistancefast(person[i].playercoords,
			                        person[0].playercoords) > 1000)
				continue;
			person[i].skeleton.free = 1;
			person[i].longdead = 1;

			for (auto& joint : person[i].skeleton.joints) {
				joint.position = DoRotation(joint.position, 0, person[i].playerrotation, 0);
				joint.position += person[i].playercoords;
				joint.realoldposition = joint.position;
				joint.velocity = DoRotation(joint.velocity, 0, person[i].playerrotation, 0);
				joint.velocity += person[i].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 'X':
		if (!debug || person[0].grenphase)
			break;
		person[0].ammo = -1;
		person[0].whichgun++;
		person[0].grenphase = 0;
		person[0].reloads[person[0].whichgun] = 3;
		if (person[0].whichgun > 7)
			person[0].whichgun = 0;
		break;
	}
}

static int mapinit = 0;
static int sdlkeymap[SDLK_LAST];
static unsigned char ourkeys[16];

static void init_sdlkeymap()
{
	int i;
	for (i = 0; i < SDLK_LAST; i++)
		sdlkeymap[i] = -1;

	sdlkeymap[SDLK_1] = MAC_1_KEY;
	sdlkeymap[SDLK_2] = MAC_2_KEY;
	sdlkeymap[SDLK_3] = MAC_3_KEY;
	sdlkeymap[SDLK_4] = MAC_4_KEY;
	sdlkeymap[SDLK_5] = MAC_5_KEY;
	sdlkeymap[SDLK_6] = MAC_6_KEY;
	sdlkeymap[SDLK_7] = MAC_7_KEY;
	sdlkeymap[SDLK_8] = MAC_8_KEY;
	sdlkeymap[SDLK_9] = MAC_9_KEY;
	sdlkeymap[SDLK_0] = MAC_0_KEY;
	sdlkeymap[SDLK_KP1] = MAC_NUMPAD_1_KEY;
	sdlkeymap[SDLK_KP2] = MAC_NUMPAD_2_KEY;
	sdlkeymap[SDLK_KP3] = MAC_NUMPAD_3_KEY;
	sdlkeymap[SDLK_KP4] = MAC_NUMPAD_4_KEY;
	sdlkeymap[SDLK_KP5] = MAC_NUMPAD_5_KEY;
	sdlkeymap[SDLK_KP6] = MAC_NUMPAD_6_KEY;
	sdlkeymap[SDLK_KP7] = MAC_NUMPAD_7_KEY;
	sdlkeymap[SDLK_KP8] = MAC_NUMPAD_8_KEY;
	sdlkeymap[SDLK_KP9] = MAC_NUMPAD_9_KEY;
	sdlkeymap[SDLK_KP0] = MAC_NUMPAD_0_KEY;
	sdlkeymap[SDLK_a] = MAC_A_KEY;
	sdlkeymap[SDLK_b] = MAC_B_KEY;
	sdlkeymap[SDLK_c] = MAC_C_KEY;
	sdlkeymap[SDLK_d] = MAC_D_KEY;
	sdlkeymap[SDLK_e] = MAC_E_KEY;
	sdlkeymap[SDLK_f] = MAC_F_KEY;
	sdlkeymap[SDLK_g] = MAC_G_KEY;
	sdlkeymap[SDLK_h] = MAC_H_KEY;
	sdlkeymap[SDLK_i] = MAC_I_KEY;
	sdlkeymap[SDLK_j] = MAC_J_KEY;
	sdlkeymap[SDLK_k] = MAC_K_KEY;
	sdlkeymap[SDLK_l] = MAC_L_KEY;
	sdlkeymap[SDLK_m] = MAC_M_KEY;
	sdlkeymap[SDLK_n] = MAC_N_KEY;
	sdlkeymap[SDLK_o] = MAC_O_KEY;
	sdlkeymap[SDLK_p] = MAC_P_KEY;
	sdlkeymap[SDLK_q] = MAC_Q_KEY;
	sdlkeymap[SDLK_r] = MAC_R_KEY;
	sdlkeymap[SDLK_s] = MAC_S_KEY;
	sdlkeymap[SDLK_t] = MAC_T_KEY;
	sdlkeymap[SDLK_u] = MAC_U_KEY;
	sdlkeymap[SDLK_v] = MAC_V_KEY;
	sdlkeymap[SDLK_w] = MAC_W_KEY;
	sdlkeymap[SDLK_x] = MAC_X_KEY;
	sdlkeymap[SDLK_y] = MAC_Y_KEY;
	sdlkeymap[SDLK_z] = MAC_Z_KEY;
	sdlkeymap[SDLK_F1] = MAC_F1_KEY;
	sdlkeymap[SDLK_F2] = MAC_F2_KEY;
	sdlkeymap[SDLK_F3] = MAC_F3_KEY;
	sdlkeymap[SDLK_F4] = MAC_F4_KEY;
	sdlkeymap[SDLK_F5] = MAC_F5_KEY;
	sdlkeymap[SDLK_F6] = MAC_F6_KEY;
	sdlkeymap[SDLK_F7] = MAC_F7_KEY;
	sdlkeymap[SDLK_F8] = MAC_F8_KEY;
	sdlkeymap[SDLK_F9] = MAC_F9_KEY;
	sdlkeymap[SDLK_F10] = MAC_F10_KEY;
	sdlkeymap[SDLK_F11] = MAC_F11_KEY;
	sdlkeymap[SDLK_F12] = MAC_F12_KEY;
	sdlkeymap[SDLK_RETURN] = MAC_RETURN_KEY;
	sdlkeymap[SDLK_KP_ENTER] = MAC_ENTER_KEY;
	sdlkeymap[SDLK_TAB] = MAC_TAB_KEY;
	sdlkeymap[SDLK_SPACE] = MAC_SPACE_KEY;
	sdlkeymap[SDLK_BACKSPACE] = MAC_DELETE_KEY;
	sdlkeymap[SDLK_ESCAPE] = MAC_ESCAPE_KEY;
	sdlkeymap[SDLK_LCTRL] = MAC_CONTROL_KEY;
	sdlkeymap[SDLK_RCTRL] = MAC_CONTROL_KEY;
	sdlkeymap[SDLK_LSHIFT] = MAC_SHIFT_KEY;
	sdlkeymap[SDLK_RSHIFT] = MAC_SHIFT_KEY;
	sdlkeymap[SDLK_CAPSLOCK] = MAC_CAPS_LOCK_KEY;
	sdlkeymap[SDLK_LALT] = MAC_OPTION_KEY;
	sdlkeymap[SDLK_RALT] = MAC_OPTION_KEY;
	sdlkeymap[SDLK_PAGEUP] = MAC_PAGE_UP_KEY;
	sdlkeymap[SDLK_PAGEDOWN] = MAC_PAGE_DOWN_KEY;
	sdlkeymap[SDLK_INSERT] = MAC_INSERT_KEY;
	sdlkeymap[SDLK_DELETE] = MAC_DEL_KEY;
	sdlkeymap[SDLK_HOME] = MAC_HOME_KEY;
	sdlkeymap[SDLK_END] = MAC_END_KEY;
	sdlkeymap[SDLK_LEFTBRACKET] = MAC_LEFT_BRACKET_KEY;
	sdlkeymap[SDLK_RIGHTBRACKET] = MAC_RIGHT_BRACKET_KEY;
	sdlkeymap[SDLK_UP] = MAC_ARROW_UP_KEY;
	sdlkeymap[SDLK_DOWN] = MAC_ARROW_DOWN_KEY;
	sdlkeymap[SDLK_LEFT] = MAC_ARROW_LEFT_KEY;
	sdlkeymap[SDLK_RIGHT] = MAC_ARROW_RIGHT_KEY;

	mapinit = 1;
}

void GetKeys(unsigned long *keys)
{
	/* this is just weird */
	memcpy(keys, ourkeys, sizeof(ourkeys));
}

static void DoSDLKey(Game *g, SDL_Event *event)
{
	if (mapinit == 0)
		init_sdlkeymap();

	int mackey = sdlkeymap[event->key.keysym.sym];
	if (mackey != -1) {
		int index = mackey / 8;
		int mask = 1 << (mackey % 8);

		if (event->type == SDL_KEYDOWN)
			ourkeys[index] |= mask;
		else
			ourkeys[index] &= ~mask;
	}

	if (event->key.keysym.unicode
	    && !(event->key.keysym.unicode & 0xFF80))
		/* hey, at least it was aleady public */
		g->HandleKeyDown(event->key.keysym.unicode);
}

static void ProcessSDLEvents(Game* g)
{
	SDL_Event event;
	while (SDL_PollEvent(&event)) {
		switch (event.type) {
		case SDL_KEYDOWN:
			if (event.key.keysym.sym == SDLK_RETURN
			    && event.key.keysym.mod & KMOD_ALT) {
				SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
				break;
			} else if (event.key.keysym.sym == SDLK_g
			           && event.key.keysym.mod & KMOD_CTRL) {
				if (SDL_WM_GrabInput(SDL_GRAB_QUERY)
				    == SDL_GRAB_OFF) {
					SDL_WM_GrabInput(SDL_GRAB_ON);
					SDL_ShowCursor(SDL_DISABLE);
				} else {
					SDL_WM_GrabInput(SDL_GRAB_OFF);
					SDL_ShowCursor(SDL_ENABLE);
				}
				break;
			}
		case SDL_KEYUP:
			DoSDLKey(g, &event);
			break;
		case SDL_QUIT:
			exit(0);
		}
	}
}

void Game::EventLoop()
{
	unsigned char theKeyMap[16];
	gQuit = false;
	framespersecond = 60;

	while (!gQuit) {
		ProcessSDLEvents(this);
		start = TimerGetTime(&theTimer);

		GLfloat oldmult = multiplier;
		int colaccuracy = min(sps, sps / (float) framespersecond + 1);
		multiplier /= colaccuracy;
		for (int i = 0; i < (int) (colaccuracy + 0.5); i++)
			Tick();
		if (DrawGLScene())
			SDL_GL_SwapBuffers();
		else
			gQuit = true;
		multiplier = oldmult;

		do {
			end = TimerGetTime(&theTimer);
			timetaken = end - start;
			framespersecond = 6e8 / timetaken;
		} while (framespersecond > maxfps);

		multiplier5 = multiplier4;
		multiplier4 = multiplier3;
		multiplier3 = multiplier2;
		multiplier2 = 1 / framespersecond;
		multiplier = (multiplier2 + multiplier3
		              + multiplier4 + multiplier5) / 4;
		multiplier = min(max(multiplier, 0.00001), 1.0);
		if (visions == 1 && !mainmenu)
			multiplier /= 3;
		if (slomo)
			multiplier /= 5;
		if (paused)
			multiplier = 0;

		GetKeys((unsigned long*) theKeyMap);
		if (IsKeyDown(theKeyMap, MAC_COMMAND_KEY)
		    &&IsKeyDown(theKeyMap, MAC_Q_KEY)) {
			gQuit = true;
			if (score > highscore) {
				highscore=score;
				/* TODO */
				ofstream opstream("Data/Highscore");
				opstream << highscore;
				opstream << "\n";
				opstream << beatgame;
				opstream.close();
			}
		}

		if (IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)) {
			alSourcePause(gSourceID[rainsound]);
			mainmenu = 1;
			alSourcePlay(gSourceID[souloutsound]);
			flashamount = flashr = flashg = flashb = 1;
			alSourceStop(gSourceID[visionsound]);
			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[whichsong]);
			alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
		}
	}
}