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