Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-07-22 17:21:35 +0000
committerStijn Buys <ingar@osirion.org>2008-07-22 17:21:35 +0000
commit9adc3720cd8fe2ba843d014dbbfe81bf936f9715 (patch)
treeb6610b334a33ede55068f1daa1b869c251548c6f
parentbb8b4e081d33f4f1aca6ba23a78842e1fc9cd721 (diff)
more keyboard handling cleanups
-rw-r--r--doc/TODO74
-rw-r--r--src/client/action.cc30
-rw-r--r--src/client/action.h45
-rw-r--r--src/client/input.cc198
-rw-r--r--src/client/key.cc6
-rw-r--r--src/client/key.h10
-rw-r--r--src/client/keyboard.cc66
-rw-r--r--src/client/keyboard.h2
8 files changed, 247 insertions, 184 deletions
diff --git a/doc/TODO b/doc/TODO
index 7663087..2dcf176 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,31 +1,43 @@
TODO
milestone 1:
- console text color and wrapping (ok)
- keyboard binds (ok)
-
fix turning
fix camera rotation
fix camera frustum clip
-
- better crosshair bitmaps
+ fix cl_prediction
milestone 2:
targetting system
server-client event system, hit-once lightweight entities
explosion events
weapon fire events
+ zones
+
+milestone 3:
+ gui
filesystem:
write a filesystem based on streams
write handlers for zip
-
+ fs_homedir, to define the writeable directory
+ fs_datadir, readonly package datadir
+ fs_base, fs_mod, fs_game, to be used by modules
+
model:
engine flare key (ok)
+ split map loader from model (ok)
+ load vertices into VertexData
support map classes (e.g. func_rotate), requires class VertexData
- split map loader from model, load vertices into VertexData
+ rework textures/shaders
+ on .map load, convert 'common/entity' to a flag
+ rename 'entity' to 'primairy'
+ add 'common/primairy_dark', ''common/secondairy', 'common/secondairy_dark' and convert to flags
+ sort triangles by flags
+ render by flag
+ use quads array and quad flag?
+
core:
connection to remote game (ok)
read/write configuration file (ok)
@@ -36,32 +48,38 @@ core:
refactor 'say', it should not be a game function (ok)
execute config files (ok)
- zones
- game module loading/unloading
+ zones (breaks network proto)
+ game module loading/unloading (breaks network proto, server must send module type)
+ support entity secondairy color (breaks network proto)
+
+ toggle func to toggle a bool cvar
network:
UDP datagrams (ok)
buffered sends (ok)
client connection state (ok)
zlib compression (partial)
- fix lag (usable for now)
+ protocol version in handshake (ok)
+ rcon framework (ok)
- protocol description
- chat, channels
- rcon, commands
+ protocol description (incomplete)
+ private chat
+ zone/system chat (requires zones)
+ group/clan chat (requires groups)
+ rcon authentication, rcon command, servers must be able to disable rcon
- protocol version in handshake
+ fix lag/client prediction
detect and disconnect clients behaving badly
client:
- input handler switching (ok)
console chars (ok)
- key bindings (ok)
+ console text color and wrapping (ok)
+ input handler switching (ok)
+ key binds (ok)
+ better crosshair bitmaps (ok)
- keyboard handler, must be able to handle keyboard layouts
- decent input handling implementation
-
- on-the-fly cl_mousecontrol (toggle function)
+ modifier key binds
+ keyboard repeat
render:
render pipeline (ok)
@@ -70,13 +88,25 @@ render:
texture registry (ok)
add small camera light (ok)
- text quads render pipe
- fix lighting without sun
+ text quads render pipe? (see model quads)
+ test/fix? lighting without sun in world.ini
+ sun light strenght
+
+gui:
+ a gui library with widgets and buttons
+ convert console and chat to gui
sound:
engine sounds (ok)
user interface sounds (ok)
+ enitity/event positional sounds
+
+game:
+ implement player credits
+ entity health/shield/armor
+ gui concept artwork
+
win32 port:
network not functional (ok)
texture loading is broken (ok)
diff --git a/src/client/action.cc b/src/client/action.cc
new file mode 100644
index 0000000..b86476e
--- /dev/null
+++ b/src/client/action.cc
@@ -0,0 +1,30 @@
+/*
+ client/action.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 "client/action.h"
+
+namespace client
+{
+
+Action::Action(const char *name, Identifier action, const char *info)
+{
+ action_name.assign(name);
+ action_id = action;
+
+ set_info(info);
+}
+
+Action::~Action()
+{
+}
+
+void Action::set_info(const char *info) {
+ if (info)
+ action_info.assign(info);
+ else
+ action_info.clear();
+}
+}
diff --git a/src/client/action.h b/src/client/action.h
new file mode 100644
index 0000000..c7086c8
--- /dev/null
+++ b/src/client/action.h
@@ -0,0 +1,45 @@
+/*
+ client/action.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_ACTION_H__
+#define __INCLUDED_CLIENT_ACTION_H__
+
+#include <string>
+
+namespace client {
+
+/// an Action that can be bound to a key
+class Action
+{
+public:
+ /// actions
+ enum Identifier {None=0};
+
+ /// define a new action
+ Action(const char *name, Identifier action, const char *info = 0);
+ ~Action();
+
+ /// name of the Action
+ inline std::string const & name() const { return action_name; }
+
+ /// Action Identifier
+ inline Identifier id() const { return action_id; }
+
+ inline std::string const & info() const { return action_info; }
+
+ /// set info
+ void set_info(const char *info);
+
+
+private:
+ std::string action_name;
+ std::string action_info;
+ Identifier action_id;
+};
+
+} // namespace client
+
+#endif // __INCLUDED_CLIENT_ACTION_H__
diff --git a/src/client/input.cc b/src/client/input.cc
index 775f03a..f8d76f2 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -29,9 +29,10 @@ namespace input
//--- local variables ---------------------------------------------
+// keyboard instance
Keyboard *keyboard = 0;
-
-//bool free_control = true;
+// keyboard modifiers shift, ctrl, alt etc
+int keyboard_modifiers = 0;
// local controls
@@ -377,6 +378,73 @@ void action_release(std::string const &action)
}
}
+void key_pressed(Key *key)
+{
+
+ if ((key->sym() == SDLK_ESCAPE) || (key->bind(Key::None).compare("ui_console") == 0)) {
+ console()->toggle();
+ 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 (console()->visible()) {
+ // send key events to the console
+ if (key->sym() < 512)
+ console()->keypressed(translate_keysym(key->sym(), keyboard_modifiers));
+
+ } else if (chat::visible()) {
+ // send key events to the chat box
+ if (key->sym() < 512)
+ chat::keypressed(translate_keysym(key->sym(), keyboard_modifiers));
+
+ } else if (core::application()->connected() && core::localcontrol()) {
+
+ if ((key->sym() == 512 + SDL_BUTTON_LEFT) && targets::hover()) {
+ // hovering target selected
+ targets::select_target(targets::hover());
+
+ } else {
+ // FIXME modifiers
+ char c = key->bind(Key::None).c_str()[0];
+ if (c == '+') {
+ // action bind
+ action_press(key->bind(Key::None));
+
+ } else if (c) {
+ // normal bind
+ core::cmd() << key->bind(Key::None) << "\n";
+ }
+ }
+
+ } else if (core::application()->connected()) {
+ // FIXME modifiers
+
+ char c = key->bind(Key::None).c_str()[0];
+ if (c && c != '+') {
+ // normal bind
+ core::cmd() << key->bind(Key::None) << "\n";
+ }
+ }
+
+}
+
+void key_released(Key *key)
+{
+ if (core::application()->connected() && core::localcontrol() && !console()->visible() && !chat::visible()) {
+
+ // FIXME modifiers
+ char c = key->bind(Key::None).c_str()[0];
+ if (c == '+') {
+ // action bind
+ action_release(key->bind(Key::None));
+ }
+ }
+}
+
+
void frame(float seconds)
{
if (core::localcontrol() && (last_control != core::localcontrol()->id())) {
@@ -423,11 +491,13 @@ void frame(float seconds)
break;
case SDL_KEYDOWN:
+ keyboard_modifiers = event.key.keysym.mod;
key = keyboard->press(event.key.keysym.sym);
pressed = true;
break;
case SDL_KEYUP:
+ keyboard_modifiers = event.key.keysym.mod;
key = keyboard->release(event.key.keysym.sym);
pressed = false;
break;
@@ -439,74 +509,10 @@ void frame(float seconds)
}
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 console key is always captured
- // FIXME ESC should escape to gui
-
- if ((key->sym() == SDLK_ESCAPE) || (key->bind(Key::None).compare("ui_console") == 0)) {
- console()->toggle();
- 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 (console()->visible()) {
- // send key events to the console
- if (event.type == SDL_KEYDOWN)
- console()->keypressed(translate_keysym(event.key.keysym));
-
- } else if (chat::visible()) {
- // 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()) {
-
- if ((key->sym() == 512 + SDL_BUTTON_LEFT) && targets::hover()) {
- // hovering target selected
- targets::select_target(targets::hover());
-
- } else {
- // FIXME modifier
- char c = key->bind(Key::None).c_str()[0];
- if (c == '+') {
- // action bind
- action_press(key->bind(Key::None));
-
- } else if (c) {
- // normal bind
- core::cmd() << key->bind(Key::None) << "\n";
- }
- }
-
- } else if (core::application()->connected()) {
- // FIXME modifier
-
- char c = key->bind(Key::None).c_str()[0];
- if (c && c != '+') {
- // normal bind
- core::cmd() << key->bind(Key::None) << "\n";
- }
- }
-
- } else {
-
- if (core::application()->connected() && core::localcontrol() && !console()->visible() && !chat::visible()) {
- // FIXME modifier (note: mmmmm, modifier could be released by now)
- char c = key->bind(Key::None).c_str()[0];
- if (c == '+') {
- // action bind
- action_release(key->bind(Key::None));
- }
- }
- }
+ if (pressed)
+ key_pressed(key);
+ else
+ key_released(key);
}
}
@@ -555,58 +561,6 @@ void frame(float seconds)
render::Camera::set_direction( -mouse_direction * math::absf(mouse_direction));
render::Camera::set_pitch(-mouse_pitch * math::absf(mouse_pitch));
}
-
- } 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;
-
- 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);
- }
- }
- */
}
diff --git a/src/client/key.cc b/src/client/key.cc
index 9b0c942..27ed22a 100644
--- a/src/client/key.cc
+++ b/src/client/key.cc
@@ -9,7 +9,7 @@
namespace client {
-Key::Key(const char *name, unsigned int keysym, char ascii, const char *bind)
+Key::Key(const char *name, int keysym, char ascii, const char *bind)
{
key_sym = keysym;
key_ascii = ascii;
@@ -21,6 +21,10 @@ Key::Key(const char *name, unsigned int keysym, char ascii, const char *bind)
if (bind)
key_bind.assign(bind);
+
+ key_bind_shift.clear();
+ key_bind_ctrl.clear();
+ key_bind_alt.clear();
}
Key::~Key()
diff --git a/src/client/key.h b/src/client/key.h
index bd6f6bd..6f190c0 100644
--- a/src/client/key.h
+++ b/src/client/key.h
@@ -7,6 +7,8 @@
#ifndef __INCLUDED_CLIENT_KEY_H__
#define __INCLUDED_CLIENT_KEY_H__
+#include "SDL/SDL.h"
+
#include <string>
namespace client {
@@ -20,11 +22,11 @@ class Key
{
public:
/// define a new key
- Key(const char *name, unsigned int keysym, char ascii=0, const char *bind=0);
+ Key(const char *name, int keysym, char ascii=0, const char *bind=0);
~Key();
/// key modifiers
- enum Modifier { None=0, Shift=1, Ctrl=2, Alt=3 };
+ enum Modifier { None=0, Shift=KMOD_LSHIFT+KMOD_RSHIFT, Ctrl=KMOD_LCTRL + KMOD_RCTRL, Alt=KMOD_LALT+KMOD_RALT };
/// clear all binds
void clear();
@@ -44,11 +46,11 @@ public:
inline char ascii() const { return key_ascii; }
- inline unsigned int sym() const { return key_sym; }
+ inline int sym() const { return key_sym; }
private:
std::string key_name;
- unsigned int key_sym;
+ int key_sym;
char key_ascii;
float key_pressed;
diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc
index da93814..410e76c 100644
--- a/src/client/keyboard.cc
+++ b/src/client/keyboard.cc
@@ -429,17 +429,16 @@ void setkeyboardmode(bool input)
*/
}
-unsigned int translate_keysym(const SDL_keysym &keysym)
+unsigned int translate_keysym(int keysym, int modifier)
{
- int key = keysym.sym;
bool shift = false;
bool numlock = false;
// keypad keys
- if (keysym.mod & KMOD_NUM) {
+ if (modifier & KMOD_NUM) {
numlock = true;
- switch (key) {
+ switch (keysym) {
case SDLK_KP0:
return '0';
break;
@@ -475,7 +474,7 @@ unsigned int translate_keysym(const SDL_keysym &keysym)
break;
}
} else {
- switch (key) {
+ switch (keysym) {
case SDLK_KP0:
return SDLK_INSERT;
break;
@@ -510,7 +509,7 @@ unsigned int translate_keysym(const SDL_keysym &keysym)
}
// special keys
- switch (key) {
+ switch (keysym) {
case SDLK_ESCAPE:
return SDLK_ESCAPE;
break;
@@ -535,91 +534,90 @@ unsigned int translate_keysym(const SDL_keysym &keysym)
}
// caps lock
- if (keysym.mod & KMOD_CAPS)
+ if (modifier & KMOD_CAPS)
shift = true;
// left/right shift
- if ((keysym.mod & KMOD_LSHIFT) || (keysym.mod & KMOD_RSHIFT)) {
+ if ((KMOD_LSHIFT + KMOD_RSHIFT) & modifier) {
shift = !shift;
}
if (shift) {
- if ((key >= 'a' && key <= 'z')) {
- key = key + 'A' - 'a';
- return key;
+ if ((keysym >= 'a' && keysym <= 'z')) {
+ return keysym + 'A' - 'a';
}
- switch (key) {
+ switch (keysym) {
case '`':
- key = '~';
+ return '~';
break;
case '1':
- key = '!';
+ return '!';
break;
case '2':
- key = '@';
+ return '@';
break;
case '3':
- key = '#';
+ return '#';
break;
case '4':
- key = '$';
+ return '$';
break;
case '5':
- key = '%';
+ return '%';
break;
case '6':
- key = '^';
+ return '^';
break;
case '7':
- key = '&';
+ return '&';
break;
case '8':
- key = '*';
+ return '*';
break;
case '9':
- key = '(';
+ return '(';
break;
case '0':
- key = ')';
+ return ')';
break;
case '-':
- key = '_';
+ return '_';
break;
case '=':
- key = '+';
+ return '+';
break;
// second row
case '[':
- key = '{';
+ return '{';
break;
case ']':
- key = '}';
+ return '}';
break;
case '|':
- key = '\\';
+ return '\\';
break;
// third row
case ';':
- key = ':';
+ return ':';
break;
case '\'':
- key = '"';
+ return '"';
break;
// fourth row
case ',':
- key = '<';
+ return '<';
break;
case '.':
- key = '>';
+ return '>';
break;
case '/':
- key = '?';
+ return '?';
break;
}
}
- return key;
+ return keysym;
}
} // namespace client
diff --git a/src/client/keyboard.h b/src/client/keyboard.h
index 1c70179..9712009 100644
--- a/src/client/keyboard.h
+++ b/src/client/keyboard.h
@@ -82,7 +82,7 @@ private:
};
/// convert SDL_keysym to a keystroke
-unsigned int translate_keysym(const SDL_keysym &keysym);
+unsigned int translate_keysym(int keysym, int modifier);
/// set the keyboard input mode
/** @param input true for console input, false for game input