/* client/input.h This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include "core/core.h" #include "client/client.h" #include "client/input.h" #include "client/chat.h" #include "client/console.h" #include "client/camera.h" #include "client/keyboard.h" #include "client/video.h" #include "render/text.h" #include "SDL/SDL.h" namespace client { core::Cvar *cl_mousecontrol = 0; namespace input { // local controls float local_turn = 0.0f; float local_pitch = 0.0f; float local_roll = 0.0f; float local_thrust = 0.0f; // last controlled entity unsigned int last_control = 0; // mouse cursor position int mouse_x = 0; int mouse_y = 0; // true if the mouse is in the deadzone bool mouse_deadzone = false; const float thruster_offset = 0.05f; void init() { con_print << "Initializing input..." << std::endl; client::setkeyboardmode(false); SDL_ShowCursor(SDL_DISABLE); SDL_WM_GrabInput(SDL_GRAB_ON); // SDL_EnableUNICODE(1); cl_mousecontrol = core::Cvar::get("cl_mousecontrol", "0", core::Cvar::Archive); cl_mousecontrol->set_info("[bool] mouse control"); } void shutdown() { con_print << "Shutting down input..." << std::endl; // SDL_EnableUNICODE(0); } // handle key release for the game world void keyreleased(const SDL_keysym &keysym) { switch (keysym.sym) { case SDLK_SPACE: camera::next_mode(); break; case SDLK_KP8: // down local_pitch = 0.0f; break; case SDLK_KP2: // up local_pitch = 0.0f; break; case SDLK_KP4: // left local_turn = 0.0f; break; case SDLK_KP6: // right local_turn = 0.0f; break; default: break; } } // handle key press events for the game world // http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/sdlkey.html void keypressed(const SDL_keysym &keysym) { switch (keysym.sym) { case SDLK_LEFT: camera::key_left(); break; case SDLK_RIGHT: camera::key_right(); break; case SDLK_UP: camera::key_up(); break; case SDLK_DOWN: camera::key_down(); break; case SDLK_KP_PLUS: local_thrust += thruster_offset; break; case SDLK_KP_MINUS: local_thrust -= 2.0f * thruster_offset; break; case SDLK_KP8: // down local_pitch = -1.0f; break; case SDLK_KP2: // up local_pitch = 1.0f; break; case SDLK_KP4: // left local_turn = 1.0f; break; case SDLK_KP6: // right local_turn = -1.0f; break; case SDLK_KP5: local_turn = 0; local_pitch = 0; break; default: break; } } // handle mouse button events for the game world // http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/sdlmousebuttonevent.html void mousebuttonpressed(const SDL_MouseButtonEvent &button) { switch (button.button) { case SDL_BUTTON_WHEELUP: local_thrust += thruster_offset; break; case SDL_BUTTON_WHEELDOWN: local_thrust -= 2.0f * thruster_offset; break; } } void frame(float seconds) { if (core::localcontrol() && (last_control != core::localcontrol()->id())) { local_turn = 0.0f; local_pitch = 0.0f; local_thrust = core::localcontrol()->thrust(); last_control = core::localcontrol()->id(); } SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_MOUSEMOTION: mouse_x = event.motion.x; mouse_y = event.motion.y; break; case SDL_MOUSEBUTTONDOWN: if (!console::visible() && core::application()->connected() && core::localcontrol()) mousebuttonpressed(event.button); break; case SDL_KEYUP: if (event.key.keysym.sym == SDLK_PRINT) { video::screenshot(); } else if (!chat::visible() && !console::visible() && core::application()->connected() && core::localcontrol()) // send key events to the game world keyreleased(event.key.keysym); break; case SDL_KEYDOWN: if (event.key.keysym.sym == '`' || event.key.keysym.sym == '~') { last_control = 0; console::toggle(); if (console::visible() && chat::visible()) chat::toggle(); } else if (console::visible()) { // send key events to the console console::keypressed(translate_keysym(event.key.keysym)); } else if (chat::visible()) { if(event.key.keysym.sym == SDLK_ESCAPE) { chat::toggle(); } else { // send key events to the chatbox chat::keypressed(translate_keysym(event.key.keysym)); } } else if(core::application()->connected()) { if ((event.key.keysym.sym == 't') || (event.key.keysym.sym == 'T')) { chat::toggle(); } else if (core::localcontrol()) { // send key events to the game world keypressed(event.key.keysym); } } break; case SDL_QUIT: core::application()->shutdown(); break; } } if (!console::visible() && core::application()->connected() && core::localcontrol()) { if (local_thrust > 1.0f) local_thrust = 1.0f; else if (local_thrust < -2.0 * thruster_offset) local_thrust = -2.0 * thruster_offset; if (camera::mode == camera::Track) { if (cl_mousecontrol->value()) { // mouse control when camera is in tracking mode int deadzone_size = 24; mouse_deadzone = true; // direction int l = mouse_x - (video::width >> 1); if (abs(l) < ( deadzone_size >> 1 )) { // dead zone local_turn = 0; } else { l = (mouse_x - deadzone_size) - ((video::width - deadzone_size) >> 1); local_turn = float (-l) / (float) ((video::width - deadzone_size) >> 1); mouse_deadzone = false; } // pitch int h = mouse_y - (video::height >> 1); if (abs(h) < ( deadzone_size >> 1 )) { // dead zone local_pitch = 0; } else { h = (mouse_y - deadzone_size) - ((video::height - deadzone_size) >> 1); local_pitch = float (-h) / (float) ((video::height - deadzone_size) >> 1); mouse_deadzone = false; } } else { if (local_turn > 1.0f) local_turn = 1.0f; else if (local_turn < -1.0f) local_turn = -1.0f; if (local_pitch > 1.0f) local_pitch = 1.0f; else if (local_pitch < -1.0f) local_pitch = -1.0f; mouse_deadzone = false; } } core::localcontrol()->set_thrust(local_thrust); core::localcontrol()->set_direction(local_turn); core::localcontrol()->set_pitch(local_pitch); } } } // namespace input } // namespace client