Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-06-02 16:20:47 +0000
committerStijn Buys <ingar@osirion.org>2008-06-02 16:20:47 +0000
commit8c17868585e2a12f947ec387947c4521ef21d775 (patch)
tree83d36d3dc36698aa0d36a3b9b9a8bb0826520586 /src
parent0f87d2fd05786f7ab128d4a041673f6fb085139f (diff)
keyboard binds
Diffstat (limited to 'src')
-rw-r--r--src/client/Makefile.am8
-rw-r--r--src/client/chat.cc31
-rw-r--r--src/client/chat.h2
-rw-r--r--src/client/client.cc2
-rw-r--r--src/client/console.cc35
-rw-r--r--src/client/console.h2
-rw-r--r--src/client/input.cc542
-rw-r--r--src/client/input.h4
-rw-r--r--src/client/key.cc29
-rw-r--r--src/client/key.h42
-rw-r--r--src/client/keyboard.cc334
-rw-r--r--src/client/keyboard.h66
-rw-r--r--src/client/view.cc31
-rw-r--r--src/render/camera.cc6
-rw-r--r--src/render/textures.cc6
15 files changed, 897 insertions, 243 deletions
diff --git a/src/client/Makefile.am b/src/client/Makefile.am
index 8c35895..56a2cc2 100644
--- a/src/client/Makefile.am
+++ b/src/client/Makefile.am
@@ -1,12 +1,12 @@
METASOURCES = AUTO
INCLUDES = -I$(top_srcdir)/src
-libclient_la_SOURCES = chat.cc client.cc console.cc hud.cc input.cc keyboard.cc \
- radar.cc video.cc view.cc
+libclient_la_SOURCES = chat.cc client.cc console.cc hud.cc input.cc key.cc \
+ keyboard.cc radar.cc video.cc view.cc
libclient_la_CFLAGS = $(LIBSDL_CFLAGS) $(GL_CFLAGS)
libclient_la_LDFLAGS = -avoid-version -no-undefined $(GL_LIBS) $(LIBSDL_LIBS)
noinst_LTLIBRARIES = libclient.la
-noinst_HEADERS = chat.h client.h console.h input.h keyboard.h radar.h video.h \
- view.h
+noinst_HEADERS = chat.h client.h console.h input.h key.h keyboard.h radar.h \
+ video.h view.h
libclient_la_LIBADD = $(top_builddir)/src/render/librender.la \
$(top_builddir)/src/core/libcore.la
diff --git a/src/client/chat.cc b/src/client/chat.cc
index 6fd5008..6c3140d 100644
--- a/src/client/chat.cc
+++ b/src/client/chat.cc
@@ -24,46 +24,23 @@ size_t input_pos = 0;
// chatbox visibility
bool chat_visible = false;
-//--- engine functions --------------------------------------------
-
-void func_con_chat(std::string const &args)
-{
- std::istringstream argstream(args);
- int i;
-
- if (argstream >> i) {
- if (i) chat_visible = true; else chat_visible = false;
- } else
- chat_visible = !chat_visible;
-
-
-}
-
//--- public ------------------------------------------------------
void init()
{
// add engine functions
- core::Func *func = core::Func::add("ui_chat", (core::FuncPtr) func_con_chat);
- func->set_info("toggle chatbox");
-
history.clear();
history.push_back("");
history_pos = history.rbegin();
input_pos = 0;
-
}
void shutdown()
{
- // remove engine functions
- core::Func::remove("ui_chat");
-
history.clear();
input_pos = 0;
}
-
bool visible()
{
return chat_visible;
@@ -133,14 +110,18 @@ void toggle()
(*history_pos).clear();
}
- setkeyboardmode(chat_visible);
+ setkeyboardmode(console()->visible() || (core::application()->connected() && chat::visible()));
}
-void keypressed(int key)
+void keypressed(unsigned int key)
{
std::deque<std::string>::reverse_iterator upit;
switch( key ) {
+ case SDLK_ESCAPE:
+ toggle();
+ break;
+
case SDLK_TAB:
core::CommandBuffer::complete( (*history_pos), input_pos);
break;
diff --git a/src/client/chat.h b/src/client/chat.h
index 71fb9f5..fdf4c70 100644
--- a/src/client/chat.h
+++ b/src/client/chat.h
@@ -30,7 +30,7 @@ void draw();
void toggle();
/// handle keyboard input
-void keypressed(int key);
+void keypressed(unsigned int key);
/// true of the console is visible
bool visible();
diff --git a/src/client/client.cc b/src/client/client.cc
index a3ad481..a3219e6 100644
--- a/src/client/client.cc
+++ b/src/client/client.cc
@@ -27,7 +27,7 @@ Client app;
//--- engine functions --------------------------------------------
-void func_r_restart(std::stringstream &args)
+void func_r_restart(std::string const &args)
{
video::shutdown();
diff --git a/src/client/console.cc b/src/client/console.cc
index a09272a..c5feb86 100644
--- a/src/client/console.cc
+++ b/src/client/console.cc
@@ -4,18 +4,19 @@
the terms and conditions of the GNU General Public License version 2
*/
-#include "client/console.h"
+#include <iostream>
+#include <fstream>
+#include <cmath>
+
#include "auxiliary/functions.h"
+#include "client/chat.h"
+#include "client/console.h"
+#include "client/video.h"
+#include "client/keyboard.h"
#include "core/core.h"
#include "filesystem/filesystem.h"
#include "render/render.h"
#include "render/textures.h"
-#include "client/video.h"
-#include "client/keyboard.h"
-
-#include <iostream>
-#include <fstream>
-#include <cmath>
namespace client {
@@ -25,22 +26,12 @@ Console *console() {
return &client_console;
}
-//--- engine functions --------------------------------------------
-
-void func_ui_console(std::string const &args)
-{
-
- console()->toggle();
-}
-
//--- public ------------------------------------------------------
void Console::init()
{
con_print << "^BInitializing console..." << std::endl;
- core::Func *func = core::Func::add("ui_console", (core::FuncPtr) func_ui_console);
- func->set_info("toggle console on or off");
console()->load_history();
}
@@ -49,9 +40,6 @@ void Console::shutdown()
con_print << "^BShutting down console..." << std::endl;
console()->save_history();
-
- // remove engine functions
- core::Func::remove("ui_console");
}
//--- Console -----------------------------------------------------
@@ -102,13 +90,12 @@ void Console::toggle()
} else {
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(SDL_DISABLE);
- //clear_notify();
}
-
- setkeyboardmode(visible());
+
+ setkeyboardmode(console()->visible() || (core::application()->connected() && chat::visible()));
}
-void Console::keypressed(int key)
+void Console::keypressed(unsigned int key)
{
std::deque<std::string>::reverse_iterator upit;
diff --git a/src/client/console.h b/src/client/console.h
index 533a8be..05d62ad 100644
--- a/src/client/console.h
+++ b/src/client/console.h
@@ -33,7 +33,7 @@ public:
void toggle();
/// handle keyboard input
- void keypressed(int key);
+ void keypressed(unsigned int key);
/// true of the console is visible
inline bool visible() { return console_visible; }
diff --git a/src/client/input.cc b/src/client/input.cc
index f75cbb9..3d5b30c 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -20,11 +20,16 @@
namespace client
{
-core::Cvar *cl_mousecontrol = 0;
-
namespace input
{
+//--- local variables ---------------------------------------------
+
+Keyboard *keyboard = 0;
+
+bool free_control = true;
+bool free_control_override = false;
+
// local controls
float local_direction = 0.0f;
float local_pitch = 0.0f;
@@ -43,156 +48,270 @@ float mouse_direction = 0;
// true if the mouse is in the deadzone
bool mouse_deadzone = false;
+// true if the mouse has control
+bool mouse_control = false;
const float thruster_offset = 0.05f;
+//--- engine functions --------------------------------------------
+
+void func_screenshot(std::string const & args)
+{
+ video::screenshot();
+}
+
+void func_ui_control(std::string const &args)
+{
+ free_control = !free_control;
+ if (!free_control) {
+ local_direction = 0.0f;
+ local_pitch = 0.0f;
+ local_roll = 0.0f;
+
+ render::Camera::set_direction(0.0f);
+ render::Camera::set_pitch(0.0f);
+ }
+}
+
+void func_ui_console(std::string const &args)
+{
+ console()->toggle();
+}
+
+void func_ui_chat(std::string const &args)
+{
+ if (core::application()->connected()) {
+ chat::toggle();
+ }
+}
+
+void func_ui_view(std::string const &args)
+{
+ if (core::application()->connected() && core::localcontrol()) {
+ render::Camera::next_mode();
+ local_roll = 0;
+ local_pitch = 0;
+ local_direction = 0;
+ }
+}
+
+void func_list_keys(std::string const &args)
+{
+ if (keyboard)
+ keyboard->list_keys();
+}
+
+void func_list_binds(std::string const &args)
+{
+ if (keyboard)
+ keyboard->list_binds();
+}
+
+void func_bind(std::string const &args)
+{
+ if (keyboard) {
+ std::stringstream argstr(args);
+ std::string keyname;
+ if (argstr >> keyname) {
+ if (args.size() > keyname.size()+1) {
+ keyboard->bind(keyname, args.substr(keyname.size()+1));
+ return;
+ }
+ }
+ }
+
+ core::Func *func = core::Func::find("bind");
+ con_print << "bind " << func->info() << std::endl;
+}
+
+void func_unbind(std::string const &args)
+{
+ if (keyboard) {
+ std::stringstream argstr(args);
+ std::string keyname;
+ if (argstr >> keyname) {
+ keyboard->unbind(keyname);
+ return;
+ }
+ }
+
+ core::Func *func = core::Func::find("unbind");
+ con_print << "unbind " << func->info() << std::endl;
+}
+
+//--- input functions ---------------------------------------------
+
void init()
{
con_print << "^BInitializing input..." << std::endl;
+
+ keyboard = new Keyboard();
+
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");
+
+ core::Func *func = 0;
+
+ func = core::Func::add("ui_console", func_ui_console);
+ func->set_info("toggle console on or off");
+
+ func = core::Func::add("ui_chat", func_ui_chat);
+ func->set_info("toggle chatbox on or of");
+
+ func = core::Func::add("ui_view", func_ui_view);
+ func->set_info("switch view mode");
+
+ func = core::Func::add("ui_control",func_ui_control);
+ func->set_info("toggle control on or off");
+
+ func = core::Func::add("list_keys", func_list_keys);
+ func->set_info("list keyboard key names");
+
+ func = core::Func::add("list_binds",func_list_binds);
+ func->set_info("list keyboard binds");
+
+ func = core::Func::add("bind", (core::FuncPtr) func_bind);
+ func->set_info("[key] [str] bind a command to a key");
+
+ func = core::Func::add("unbind", func_unbind);
+ func->set_info("[key] unbind a key");
+
+ func = core::Func::add("screenshot", func_screenshot);
+ func->set_info("make a screenshot");
+
+ keyboard->load_binds();
}
void shutdown()
{
con_print << "^BShutting down input..." << std::endl;
+
+ core::Func::remove("list_keys");
+ core::Func::remove("list_binds");
+
+ core::Func::remove("bind");
+ core::Func::remove("unbind");
+
+ core::Func::remove("screenshot");
+
+ core::Func::remove("ui_console");
+ core::Func::remove("ui_control");
+ core::Func::remove("ui_chat");
+ core::Func::remove("ui_view");
+
+ keyboard->save_binds();
+ delete keyboard;
+ keyboard = 0;
+
+ SDL_ShowCursor(SDL_ENABLE);
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
// SDL_EnableUNICODE(0);
+
}
-// handle key release for the game world
-void keyreleased(const SDL_keysym &keysym)
+void action_press(std::string const &action)
{
- switch (keysym.sym) {
- case SDLK_LEFT:
- render::Camera::set_direction(0.0f);
- break;
- case SDLK_RIGHT:
- render::Camera::set_direction(0.0f);
- break;
- case SDLK_UP:
- render::Camera::set_pitch(0.0f);
- break;
- case SDLK_DOWN:
- render::Camera::set_pitch(0.0f);
- break;
+ /* -- thruster ------------------------------------ */
+ if (action.compare("+thrust") == 0) {
+ local_thrust += thruster_offset;
- case SDLK_SPACE:
- render::Camera::next_mode();
- local_roll = 0;
- local_pitch = 0;
- local_direction = 0;
- break;
+ } else if (action.compare("-thrust") == 0) {
+ local_thrust -= 2.0f * thruster_offset;
+
+ /* -- mouse control ------------------------------- */
+ } else if (action.compare("+control") == 0) {
+ free_control_override = true;
- case SDLK_KP8: // turn down
- local_pitch = 0.0f;
- break;
+ /* -- directional control ------------------------- */
+ } else if (action.compare("+left") == 0) {
+ local_direction = 1.0f;
- case SDLK_KP2: // turn up
- local_pitch = 0.0f;
- break;
+ } else if (action.compare("+right") == 0) {
+ local_direction = -1.0f;
- case SDLK_KP4: // turn left
- local_direction = 0.0f;
- break;
+ } else if (action.compare("+up") == 0) {
+ local_pitch = 1.0f;
- case SDLK_KP6: // turn right
- local_direction = 0.0f;
- break;
+ } else if (action.compare("+down") == 0) {
+ local_pitch = -1.0f;
- case SDLK_KP_DIVIDE: // roll left
- local_roll = 0.0f;
- break;
-
- case SDLK_KP_MULTIPLY: // roll right
- local_roll = 0.0f;
- break;
+ } else if (action.compare("+rollleft") == 0) {
+ local_roll = 1.0f;
- default:
- break;
- }
-}
+ } else if (action.compare("+rollright") == 0) {
+ local_roll = -1.0f;
+
+ /* -- camera control ------------------------------ */
+ } else if (action.compare("+camleft") == 0) {
+ render::Camera::set_direction(1.0f);
-// handle key press events for the game world
+ } else if (action.compare("+camright") == 0) {
+ render::Camera::set_direction(-1.0f);
-// http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/sdlkey.html
-void keypressed(const SDL_keysym &keysym)
+ } else if (action.compare("+camup") == 0) {
+ render::Camera::set_pitch(1.0f);
+
+ } else if (action.compare("+camdown") == 0) {
+ render::Camera::set_pitch(-1.0f);
+ } else
+ con_warn << "Unknown action " << action << std::endl;
+}
+
+void action_release(std::string const &action)
{
- switch (keysym.sym) {
- case SDLK_LEFT:
- render::Camera::set_direction(1.0f);
- break;
- case SDLK_RIGHT:
- render::Camera::set_direction(-1.0f);
- break;
- case SDLK_UP:
- render::Camera::set_pitch(1.0f);
- break;
- case SDLK_DOWN:
- render::Camera::set_pitch(-1.0f);
- 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_direction = 1.0f;
- break;
-
- case SDLK_KP6: // right
- local_direction = -1.0f;
- break;
-
- case SDLK_KP5: // level
- local_direction = 0;
- local_pitch = 0;
- local_roll = 0;
- break;
+ /* -- thruster ------------------------------------ */
+ if (action.compare("+thrust") == 0) {
+
- case SDLK_KP_DIVIDE: // roll left
- local_roll = 1.0f;
- break;
+ } else if (action.compare("-thrust") == 0) {
- case SDLK_KP_MULTIPLY: // roll light
- local_roll = -1.0f;
- break;
+ /* -- mouse control ------------------------------- */
+ } else if (action.compare("+control") == 0) {
+ free_control_override = false;
+ if (!free_control) {
+ local_direction = 0.0f;
+ local_pitch = 0.0f;
+ local_roll = 0.0f;
- default:
- break;
- }
-
-}
+ render::Camera::set_direction(0.0f);
+ render::Camera::set_pitch(0.0f);
+ }
-// handle mouse button events for the game world
+ /* -- directional control ------------------------- */
+ } else if (action.compare("+left") == 0) {
+ local_direction = 0.0f;
-// 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;
+ } else if (action.compare("+right") == 0) {
+ local_direction = 0.0f;
+
+ } else if (action.compare("+up") == 0) {
+ local_pitch = 0.0f;
+
+ } else if (action.compare("+down") == 0) {
+ local_pitch = 0.0f;
+
+ } else if (action.compare("+rollleft") == 0) {
+ local_roll = 0.0f;
+
+ } else if (action.compare("+rollright") == 0) {
+ local_roll = 0.0f;
+
+ /* -- camera control ------------------------------ */
+ } else if (action.compare("+camleft") == 0) {
+ render::Camera::set_direction(0.0f);
+
+ } else if (action.compare("+camright") == 0) {
+ render::Camera::set_direction(0.0f);
+
+ } else if (action.compare("+camup") == 0) {
+ render::Camera::set_pitch(0.0f);
+
+ } else if (action.compare("+camdown") == 0) {
+ render::Camera::set_pitch(0.0f);
}
}
@@ -209,74 +328,125 @@ void frame(float seconds)
mouse_x = video::width / 2;
mouse_y = video::height / 2;
render::Camera::reset();
+ free_control = true;
+ free_control_override = false;
}
SDL_Event event;
-
+ Key *key = 0;
+ bool pressed = false;
+
while (SDL_PollEvent(&event)) {
-
+ pressed = false;
+ key = 0;
+
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);
+ key = keyboard->press(512 + event.button.button);
+ pressed = true;
+ break;
+ case SDL_MOUSEBUTTONUP:
+ key = keyboard->release(512 + event.button.button);
+ pressed = false;
+ break;
+
+ case SDL_KEYDOWN:
+ key = keyboard->press(event.key.keysym.sym);
+ pressed = true;
break;
+
case SDL_KEYUP:
- if (event.key.keysym.sym == SDLK_PRINT) {
- video::screenshot();
- } else if (!chat::visible() && !console()->visible() &&
- core::application()->connected() && core::localcontrol())
+ key = keyboard->release(event.key.keysym.sym);
+ pressed = false;
+ break;
- // send key events to the game world
- keyreleased(event.key.keysym);
+ case SDL_QUIT:
+ core::application()->shutdown();
+ return;
break;
- case SDL_KEYDOWN:
- if (chat::visible() && !console()->visible() && (event.key.keysym.sym == SDLK_ESCAPE)) {
- chat::toggle();
- } else if (event.key.keysym.sym == '`' || event.key.keysym.sym == '~' || (event.key.keysym.sym == SDLK_ESCAPE)) {
- //last_control = 0;
+ }
+
+ if (key) {
+ if (pressed) {
+/*
+ if (keysym.mod & KMOD_NUM) numlock = true else numlock = false;
+ if (keysym.mod & KMOD_CAPS) capslock = true; else capslock = false;
+ if ((keysym.mod & KMOD_LSHIFT) || (keysym.mod & KMOD_RSHIFT)) capslock != capslock;
+*/
+ // FIXME screenshot and console are always captured
+ if (key->bind().compare("ui_console") == 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));
+ local_direction = 0.0f;
+ local_pitch = 0.0f;
+ local_roll = 0.0f;
+ render::Camera::set_direction(0.0f);
+ render::Camera::set_pitch(0.0f);
+
+ } else if (key->bind().compare("screenshot") == 0) {
+ video::screenshot();
+
+ } else if (console()->visible()) {
+ // FIXME send key events to the console
+ if (event.type == SDL_KEYDOWN)
+ 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
+ // FIXME send key events to the chat box
+ if (event.type == SDL_KEYDOWN)
chat::keypressed(translate_keysym(event.key.keysym));
+
+ } else if (core::application()->connected() && core::localcontrol()) {
+
+ char c = key->bind().c_str()[0];
+ if (c == '+' || c == '-') {
+ // action bind
+ action_press(key->bind());
+
+ } else if (c) {
+ // normal bind
+ core::cmd() << key->bind() << "\n";
}
- } 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);
+ } else if (core::application()->connected()) {
+
+ char c = key->bind().c_str()[0];
+ if (c && c != '+' && c != '-') {
+ // normal bind
+ core::cmd() << key->bind() << "\n";
}
}
- break;
- case SDL_QUIT:
- core::application()->shutdown();
- break;
+
+ } else {
+
+ if (core::application()->connected() && core::localcontrol()) {
+
+ char c = key->bind().c_str()[0];
+ if (c == '+' || c == '-') {
+ // action bind
+ action_release(key->bind());
+ }
+ }
+ }
}
-
}
+
+ mouse_control = false;
+ mouse_deadzone = false;
- if (!console()->visible() && core::application()->connected() && core::localcontrol()) {
-
- if (cl_mousecontrol->value()) {
+ if (core::application()->connected() && core::localcontrol()) {
+
+ mouse_control = !console()->visible() && (free_control || free_control_override);
+
+ if (mouse_control) {
// the mouse will not react if it is in the deadzone
- int deadzone_size = 24;
+ int deadzone_size = 8;
mouse_deadzone = true;
// direction
@@ -306,6 +476,7 @@ void frame(float seconds)
if ((render::Camera::mode() == render::Camera::Track) || (render::Camera::mode() == render::Camera::Cockpit)) {
local_direction = mouse_direction * math::absf(mouse_direction);
local_pitch = mouse_pitch * math::absf(mouse_pitch);
+
} else if (render::Camera::mode() == render::Camera::Free) {
// squared values to smoothen camera movement
render::Camera::set_direction( -mouse_direction * math::absf(mouse_direction));
@@ -313,12 +484,61 @@ void frame(float seconds)
}
} else {
+ /*
+ const float MIN_DELTA = 10e-10;
+ const float ANGLE_DELTA = 0.01f;
+
+ math::Axis target_axis; // FIXME
+ float cosangle;
+ const math::Axis & entity_axis= core::localcontrol()->axis();
+
+ // auto-level: pitch
+ local_pitch = 0;
+
+ // project target_axis.up() into the plane with axis->left() normal
+ math::Vector3f n = entity_axis.left();
+ math::Vector3f p = target_axis.up();
+ float u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]);
+ p = target_axis.up() + u * n;
- math::clamp(local_direction, -1.0f, 1.0f);
- math::clamp(local_pitch, -1.0f, 1.0f);
+ float side = entity_axis.forward().x * p.x +
+ entity_axis.forward().y * p.y +
+ entity_axis.forward().z * p.z;
+
+ if ((fabs(side) - MIN_DELTA > 0)) {
+
+ cosangle = math::dotproduct(p, entity_axis.up());
+ if (fabs(cosangle) + ANGLE_DELTA < 1 ) {
+ local_pitch = -3 * math::sgnf(side) * (1-cosangle);
+ }
+ }
+
+ // auto-level: roll
+ local_roll = 0;
+
+ // project target_axis.up() into the plane with axis.forward() normal
+ n = entity_axis.forward();
+ p = target_axis.up();
+ u = p[0]*n[0] + p[1]*n[1] + p[2]*n[2] / (-n[0]*n[0] - n[1]*n[1] - n[2] * n[2]);
+ p = target_axis.up() + u * n;
+
+ side = entity_axis.left().x * p.x +
+ entity_axis.left().y * p.y +
+ entity_axis.left().z * p.z;
+
+ if ((fabs(side) - MIN_DELTA > 0)) {
+
+ cosangle = math::dotproduct(p, entity_axis.up());
+ if (fabs(cosangle) + ANGLE_DELTA < 1 ) {
+ local_roll = 3 * math::sgnf(side) * (1-cosangle);
+ }
+ }
+ */
}
+ math::clamp(local_direction, -1.0f, 1.0f);
+ math::clamp(local_pitch, -1.0f, 1.0f);
math::clamp(local_thrust, 0.0f, 1.0f);
math::clamp(local_roll, -1.0f, 1.0f);
diff --git a/src/client/input.h b/src/client/input.h
index bcbba9b..87f7dfe 100644
--- a/src/client/input.h
+++ b/src/client/input.h
@@ -12,8 +12,6 @@
namespace client
{
-extern core::Cvar *cl_mousecontrol;
-
namespace input
{
@@ -28,7 +26,9 @@ void frame(float seconds);
extern int mouse_x;
extern int mouse_y;
+
extern bool mouse_deadzone;
+extern bool mouse_control;
} // namespace input
diff --git a/src/client/key.cc b/src/client/key.cc
new file mode 100644
index 0000000..066f6ef
--- /dev/null
+++ b/src/client/key.cc
@@ -0,0 +1,29 @@
+/*
+ client/key.cc
+ 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 "client/key.h"
+
+namespace client {
+
+Key::Key(const char *name, unsigned int keysym, char ascii, const char *bind)
+{
+ key_sym = keysym;
+ key_ascii = ascii;
+ key_pressed = 0;
+
+ key_name.assign(name);
+
+ if (bind)
+ key_bind.assign(bind);
+ else
+ key_bind.clear();
+}
+
+Key::~Key()
+{
+}
+
+}
diff --git a/src/client/key.h b/src/client/key.h
new file mode 100644
index 0000000..ece7669
--- /dev/null
+++ b/src/client/key.h
@@ -0,0 +1,42 @@
+/*
+ client/key.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
+*/
+
+#ifndef __INCLUDED_CLIENT_KEY_H__
+#define __INCLUDED_CLIENT_KEY_H__
+
+#include <string>
+
+namespace client {
+
+class Key
+{
+public:
+ Key(const char *name, unsigned int keysym, char ascii=0, const char *bind=0);
+ ~Key();
+
+ inline float & pressed() { return key_pressed; }
+
+ inline std::string const & name() const { return key_name; }
+
+ inline std::string & bind() { return key_bind; }
+
+ inline char ascii() const { return key_ascii; }
+
+ inline unsigned int sym() const { return key_sym; }
+
+private:
+ unsigned int key_sym;
+ char key_ascii;
+
+ std::string key_name;
+ std::string key_bind;
+
+ float key_pressed;
+};
+
+} // namespace client
+
+#endif // __INCLUDED_CLIENT_KEY_H__
diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc
index 8566ded..f9be4f5 100644
--- a/src/client/keyboard.cc
+++ b/src/client/keyboard.cc
@@ -4,21 +4,344 @@
the terms and conditions of the GNU General Public License version 2
*/
-#include "client/keyboard.h"
-
#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+#include "auxiliary/functions.h"
+#include "client/keyboard.h"
+#include "core/application.h"
+#include "core/commandbuffer.h"
+#include "filesystem/filesystem.h"
+#include "sys/sys.h"
namespace client {
+/*
+Notes:
+http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/sdlkey.html
+*/
+
+Keyboard::Keyboard()
+{
+ numlock = false;
+ capslock = false;
+
+ add_key("backspace", SDLK_BACKSPACE);
+ add_key("tab", SDLK_TAB);
+ add_key("clear", SDLK_CLEAR);
+ add_key("enter", SDLK_RETURN);
+ add_key("pause", SDLK_PAUSE);
+ add_key("escape", SDLK_ESCAPE);
+ add_key("space", SDLK_SPACE, ' ', "ui_control");
+ add_key("!", SDLK_EXCLAIM, '!');
+ add_key("\"", SDLK_QUOTEDBL, '"');
+ add_key("#", SDLK_HASH, '#');
+ add_key("$", SDLK_DOLLAR, '$');
+ add_key("&", SDLK_AMPERSAND, '&');
+ add_key("'", SDLK_QUOTE, '\'');
+ add_key("(", SDLK_LEFTPAREN, '(');
+ add_key(")", SDLK_RIGHTPAREN, ')');
+ add_key("*", SDLK_ASTERISK, '*');
+ add_key("+", SDLK_PLUS, '+');
+ add_key(",", SDLK_COMMA, ',');
+ add_key("-", SDLK_MINUS, '-');
+ add_key(".", SDLK_PERIOD, '.');
+ add_key("/", SDLK_SLASH, '/');
+
+ add_key("0", SDLK_0, '0');
+ add_key("1", SDLK_1, '1');
+ add_key("2", SDLK_2, '2');
+ add_key("3", SDLK_3, '3');
+ add_key("4", SDLK_4, '4');
+ add_key("5", SDLK_5, '5');
+ add_key("6", SDLK_6, '6');
+ add_key("7", SDLK_7, '7');
+ add_key("8", SDLK_8, '8');
+ add_key("9", SDLK_9, '9');
+
+ add_key(":", SDLK_COLON, ':');
+ add_key(";", SDLK_SEMICOLON, ';');
+ add_key("<", SDLK_LESS, '<');
+ add_key("=", SDLK_EQUALS, '=');
+ add_key(">", SDLK_GREATER, '>');
+ add_key("?", SDLK_QUESTION, '?');
+ add_key("@", SDLK_AT, '@');
+ add_key("[", SDLK_LEFTBRACKET, '[');
+ add_key("\\", SDLK_BACKSLASH, '\\');
+ add_key("]", SDLK_RIGHTBRACKET, ']');
+ add_key("^", SDLK_CARET, '^');
+ add_key("_", SDLK_UNDERSCORE, '_');
+ add_key("`", SDLK_BACKQUOTE, '`', "ui_console");
+
+ add_key("a", SDLK_a, 'a');
+ add_key("b", SDLK_b, 'b');
+ add_key("c", SDLK_c, 'c');
+ add_key("d", SDLK_d, 'd');
+ add_key("e", SDLK_e, 'e');
+ add_key("f", SDLK_f, 'f');
+ add_key("g", SDLK_g, 'g');
+ add_key("h", SDLK_h, 'h');
+ add_key("i", SDLK_i, 'i');
+ add_key("j", SDLK_j, 'j');
+ add_key("k", SDLK_k, 'k');
+ add_key("l", SDLK_l, 'l');
+ add_key("m", SDLK_m, 'm');
+ add_key("n", SDLK_n, 'n');
+ add_key("o", SDLK_o, 'o');
+ add_key("p", SDLK_p, 'p');
+ add_key("q", SDLK_q, 'q');
+ add_key("r", SDLK_r, 'r');
+ add_key("s", SDLK_s, 's');
+ add_key("t", SDLK_t, 't', "ui_chat");
+ add_key("u", SDLK_u, 'u');
+ add_key("v", SDLK_v, 'v', "ui_view");
+ add_key("w", SDLK_w, 'w');
+ add_key("x", SDLK_x, 'x');
+ add_key("y", SDLK_y, 'y');
+ add_key("z", SDLK_z, 'z');
+
+ add_key("del", SDLK_DELETE);
+ add_key("kp0", SDLK_KP0);
+ add_key("kp1", SDLK_KP1);
+ add_key("kp2", SDLK_KP2, 0, "+down");
+ add_key("kp3", SDLK_KP3);
+ add_key("kp4", SDLK_KP4, 0, "+left");
+ add_key("kp5", SDLK_KP5);
+ add_key("kp6", SDLK_KP6, 0, "+right");
+ add_key("kp7", SDLK_KP7);
+ add_key("kp8", SDLK_KP8, 0, "+up");
+ add_key("kp9", SDLK_KP9);
+
+ add_key("kpperiod", SDLK_KP_PERIOD, '.');
+ add_key("kpdiv", SDLK_KP_DIVIDE, '/', "+rollleft");
+ add_key("kpmul", SDLK_KP_MULTIPLY, '*', "+rollright");
+ add_key("kpmin", SDLK_KP_MINUS, '-', "-thrust");
+ add_key("kpplus", SDLK_KP_PLUS, '+', "+thrust");
+ add_key("kpenter", SDLK_KP_ENTER, '\n');
+ add_key("kpequal", SDLK_KP_EQUALS, '=');
+
+ add_key("up", SDLK_UP, 0, "+camup");
+ add_key("down", SDLK_DOWN, 0, "+camdown");
+ add_key("right", SDLK_RIGHT, 0, "+camright");
+ add_key("left", SDLK_LEFT, 0, "+camleft");
+
+ add_key("insert", SDLK_INSERT);
+ add_key("home", SDLK_HOME);
+ add_key("end", SDLK_END);
+ add_key("pageup", SDLK_PAGEUP);
+ add_key("pagedown", SDLK_PAGEDOWN);
+
+ add_key("f1", SDLK_F1);
+ add_key("f2", SDLK_F2);
+ add_key("f3", SDLK_F3);
+ add_key("f4", SDLK_F4);
+ add_key("f5", SDLK_F5);
+ add_key("f6", SDLK_F6);
+ add_key("f7", SDLK_F7);
+ add_key("f8", SDLK_F8);
+ add_key("f9", SDLK_F9);
+ add_key("f10", SDLK_F11);
+ add_key("f11", SDLK_F11);
+ add_key("f12", SDLK_F12);
+ add_key("f13", SDLK_F13);
+ add_key("f14", SDLK_F14);
+ add_key("f15", SDLK_F15);
+
+ add_key("numlock", SDLK_NUMLOCK);
+ add_key("capslock", SDLK_CAPSLOCK);
+ add_key("scrollock", SDLK_SCROLLOCK);
+
+ add_key("rshift", SDLK_RSHIFT);
+ add_key("lshift", SDLK_LSHIFT);
+
+ add_key("rctrl", SDLK_RCTRL);
+ add_key("lctrl", SDLK_LCTRL);
+
+ add_key("ralt", SDLK_RALT);
+ add_key("lalt", SDLK_LALT);
+
+ add_key("rmeta", SDLK_RMETA);
+ add_key("lmeta", SDLK_LMETA);
+ add_key("lwin", SDLK_LSUPER);
+ add_key("rwin", SDLK_RSUPER);
+ add_key("mode", SDLK_MODE);
+
+ add_key("help", SDLK_HELP);
+ add_key("print", SDLK_PRINT, 0, "screenshot");
+ add_key("sysrq", SDLK_SYSREQ);
+ add_key("breal", SDLK_BREAK);
+ add_key("menu", SDLK_MENU);
+ add_key("power", SDLK_POWER);
+ add_key("euro", SDLK_EURO);
+
+ // mouse key aliases
+ add_key("lmb", 512 + SDL_BUTTON_LEFT, 0, "+control");
+ add_key("rmb", 512 + SDL_BUTTON_RIGHT);
+ add_key("mmb", 512 + SDL_BUTTON_MIDDLE);
+
+ add_key("mwup", 512 + SDL_BUTTON_WHEELUP, 0, "+thrust");
+ add_key("mwdown", 512 + SDL_BUTTON_WHEELDOWN, 0, "-thrust");
+}
+
+Keyboard::~Keyboard()
+{
+ for(iterator it = begin(); it != end(); it++)
+ delete (*it).second;
+
+ keys.clear();
+}
+
+void Keyboard::save_binds()
+{
+ std::string filename(filesystem::writedir);
+ filename.append("binds.cfg");
+ std::ofstream ofs(filename.c_str());
+
+ if (!ofs.is_open()) {
+ con_warn << "Could not write " << filename << std::endl;
+ return;
+ }
+
+ con_print << " writing keyboard binds to " << filename << std::endl;
+
+ ofs << "# binds.cfg - osirion keyboard binds" << std::endl;
+ ofs << "# this file is automaticly generated" << std::endl;
+
+ iterator it;
+ for (it = begin(); it != end(); it++) {
+ Key *key = (*it).second;
+ if (key->bind().size()) {
+ ofs << "bind " << key->name() << " " << key->bind() << std::endl;
+ } else {
+ ofs << "unbind " << key->name() << std::endl;
+ }
+ }
+ ofs.close();
+}
+
+void Keyboard::load_binds()
+{
+ std::string filename(filesystem::writedir);
+ filename.append("binds.cfg");
+ std::ifstream ifs(filename.c_str(), std::ifstream::in);
+
+ if (!ifs.is_open()) {
+ con_warn << "Could not read " << filename << std::endl;
+ return;
+ }
+
+ con_print << " reading keyboard binds from " << filename << std::endl;
+
+ char line[MAXCMDSIZE];
+ while (ifs.getline(line, MAXCMDSIZE-1)) {
+ if (line[0] && line[0] != '#' && line[0] != ';')
+ core::cmd() << line << '\n';
+ }
+
+ // execute commands in the buffer
+ core::CommandBuffer::exec();
+}
+Key * Keyboard::release(unsigned int sym)
+{
+ Key *key = find(sym);
+ if (!key) {
+ return 0;
+ }
+
+ key->pressed() = 0;
+ return key;
+}
+
+Key * Keyboard::press(unsigned int sym)
+{
+ Key *key = find(sym);
+ if (!key) {
+ return 0;
+ }
+
+ if (!key->pressed())
+ key->pressed() = core::application()->time();
+
+ return key;
+}
+
+Key *Keyboard::find(std::string const & name)
+{
+ Key *key = 0;
+ for (iterator it = begin(); it != end() && !key; it++) {
+ if ((*it).second->name().compare(name) == 0) {
+ key = (*it).second;
+ }
+ }
+ return key;
+}
+
+Key *Keyboard::find(unsigned int keysym)
+{
+ iterator it = keys.find(keysym);
+ if (it == end())
+ return 0;
+ else
+ return (*it).second;
+}
+
+void Keyboard::bind(std::string const &name, const std::string str)
+{
+ Key *key = find(name);
+ if (key) {
+ key->bind().assign(str);
+ aux::trim(key->bind());
+ } else {
+ con_print << "Key '" << name << "' not found." << std::endl;
+ }
+}
+
+void Keyboard::unbind(std::string const &name)
+{
+ Key *key = find(name);
+ if (key) {
+ key->bind().clear();
+ } else {
+ con_print << "Key '" << name << "' not found." << std::endl;
+ }
+}
+
+void Keyboard::add_key(const char *name, const unsigned int keysym, const char ascii, const char *bind)
+{
+ keys[keysym] = new Key(name, keysym, ascii, bind);
+}
+
+void Keyboard::list_keys()
+{
+ for (iterator it = begin(); it != end(); it++) {
+ con_print << " " << aux::spaces((*it).second->name(), 6) << " " << (*it).second->bind() << std::endl;
+ }
+ con_print << keys.size() << " keys" << std::endl;
+}
+
+void Keyboard::list_binds()
+{
+ size_t n =0;
+ for (iterator it = begin(); it != end(); it++) {
+ if ((*it).second->bind().size()) {
+ con_print << " " << aux::spaces((*it).second->name(), 6) << " " << (*it).second->bind() << std::endl;
+ n++;
+ }
+ }
+ con_print << n << " binds" << std::endl;
+}
+
void setkeyboardmode(bool input)
{
- if(input)
+/* if(input)
SDL_EnableKeyRepeat(250, SDL_DEFAULT_REPEAT_INTERVAL);
else
SDL_EnableKeyRepeat(10, SDL_DEFAULT_REPEAT_INTERVAL);
+*/
}
-int translate_keysym(const SDL_keysym &keysym)
+unsigned int translate_keysym(const SDL_keysym &keysym)
{
int key = keysym.sym;
@@ -96,6 +419,9 @@ int translate_keysym(const SDL_keysym &keysym)
// special keys
switch(key) {
+ case SDLK_ESCAPE:
+ return SDLK_ESCAPE;
+ break;
case SDLK_KP_ENTER:
return SDLK_RETURN;
break;
diff --git a/src/client/keyboard.h b/src/client/keyboard.h
index 6805818..fb9efaf 100644
--- a/src/client/keyboard.h
+++ b/src/client/keyboard.h
@@ -4,21 +4,77 @@
the terms and conditions of the GNU General Public License version 2
*/
-#ifndef __INCLUDED_CLIENT_KEYS_H__
-#define __INCLUDED_CLIENT_KEYS_H__
+#ifndef __INCLUDED_CLIENT_KEYBOARD_H__
+#define __INCLUDED_CLIENT_KEYBOARD_H__
+
+#include <string>
+#include <map>
#include "SDL/SDL.h"
+#include "client/key.h"
+
namespace client {
+class Keyboard
+{
+public:
+ Keyboard();
+ ~Keyboard();
+
+ /// find a key on a keysym
+ Key *find(unsigned int keysym);
+
+ /// find a key on name
+ Key *find(std::string const & name);
+
+ /// bind a string to a key
+ void bind(std::string const &name, const std::string str);
+
+ /// clear the string bound to a key
+ void unbind(std::string const &name);
+
+ /// list keyboard key names
+ void list_keys();
+
+ /// list keyboard binds
+ void list_binds();
+
+ /// load keyboard binds
+ void load_binds();
+
+ /// save keyboard binds
+ void save_binds();
+
+ /// a key has been pressed
+ Key *press(unsigned int sym);
+
+ /// a key has been pressed
+ Key *release(unsigned int sym);
+
+private:
+ typedef std::map<unsigned int, Key *>::iterator iterator;
+
+ inline iterator begin() { return keys.begin(); }
+
+ inline iterator end() { return keys.end(); }
+
+ void add_key(const char *name, const unsigned int keysym, const char ascii=0, const char *bind=0);
+
+ std::map<unsigned int, Key *> keys;
+
+ bool numlock;
+ bool capslock;
+};
+
/// convert SDL_keysym to a keystroke
-int translate_keysym(const SDL_keysym &keysym);
+unsigned int translate_keysym(const SDL_keysym &keysym);
/// set the keyboard input mode
/** @param input true for console input, false for game input
*/
void setkeyboardmode(bool input);
-} // namespace client
+}
-#endif // __INCLUDED_CLIENT_KEYS_H__
+#endif // __INCLUDED_CLIENT_KEYBOARD_H__
diff --git a/src/client/view.cc b/src/client/view.cc
index 6d3f456..d796655 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -190,21 +190,32 @@ void draw_cursor()
float crosshair_size = 48.0f;
float x = input::mouse_x - (crosshair_size /2);
float y = input::mouse_y - (crosshair_size /2);
-// 0
+
using namespace render;
- render::Textures::bind("bitmaps/crosshair");
+
math::Color color;
- if (cl_crosshaircolor && cl_crosshaircolor->value()) {
- std::stringstream colorstr(cl_crosshaircolor->str());
- colorstr >> color;
- }
+ color.a = 0.5f;
- if (cl_mousecontrol->value() && input::mouse_deadzone)
- color.a = 0.3f;
- else
- color.a = 0.5f;
+ if (render::Camera::mode() == render::Camera::Overview) {
+ render::Textures::bind("bitmaps/crosshairs/aim");
+
+ } else {
+
+ if (input::mouse_control) {
+ render::Textures::bind("bitmaps/crosshairs/control");
+
+ if (cl_crosshaircolor && cl_crosshaircolor->value()) {
+ std::stringstream colorstr(cl_crosshaircolor->str());
+ colorstr >> color;
+ }
+ } else {
+
+ render::Textures::bind("bitmaps/crosshairs/aim");
+ }
+
+ }
gl::color(color);
gl::begin(gl::Quads);
diff --git a/src/render/camera.cc b/src/render/camera.cc
index 8da6bc9..a879b82 100644
--- a/src/render/camera.cc
+++ b/src/render/camera.cc
@@ -130,19 +130,19 @@ void Camera::next_mode()
case Free:
// switch camera to Track mode
set_mode(Track);
- con_print << "camera mode: track" << std::endl;
+ core::application()->notify_message(std::string("view: track"));
break;
case Track:
// switch camera to Cockpit mode
set_mode(Cockpit);
- con_print << "camera mode: cockpit" << std::endl;
+ core::application()->notify_message(std::string("view: cockpit"));
break;
case Cockpit:
// switch camera to Free mode
set_mode(Free);
- con_print << "camera mode: free" << std::endl;
+ core::application()->notify_message(std::string("view: free"));
break;
default:
diff --git a/src/render/textures.cc b/src/render/textures.cc
index cfd627c..71abc87 100644
--- a/src/render/textures.cc
+++ b/src/render/textures.cc
@@ -44,8 +44,10 @@ void Textures::init()
load("bitmaps/loader");
// crosshairs
- load("bitmaps/crosshair");
-
+ load("bitmaps/crosshairs/aim");
+ load("bitmaps/crosshairs/control");
+ load("bitmaps/crosshairs/target");
+
// light flares
load("bitmaps/fx/flare00");
load("bitmaps/fx/flare01");