Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/camera.cc129
-rw-r--r--src/client/chat.cc51
-rw-r--r--src/client/client.cc16
-rw-r--r--src/client/console.cc536
-rw-r--r--src/client/console.h84
-rw-r--r--src/client/input.cc20
-rw-r--r--src/client/view.cc10
7 files changed, 465 insertions, 381 deletions
diff --git a/src/client/camera.cc b/src/client/camera.cc
index 29310fc..21bf930 100644
--- a/src/client/camera.cc
+++ b/src/client/camera.cc
@@ -28,6 +28,7 @@ math::Vector3f target;
math::Vector3f eye;
math::Axis axis;
+const float MIN_DELTA = 10e-10;
// current camera mode
Mode mode;
@@ -86,10 +87,18 @@ void set_mode(Mode newmode) {
target_pitch = 0.0f;
distance = 0.4f;
+ axis.clear();
+
switch(newmode) {
case Track:
// switch camera to Track mode
mode = Track;
+ if (core::localcontrol()) {
+ if (core::localcontrol()->state())
+ axis.assign(core::localcontrol()->state()->axis());
+ else
+ axis.assign(core::localcontrol()->axis());
+ }
break;
case Free:
@@ -148,7 +157,7 @@ void next_mode()
void draw(float seconds)
{
math::Matrix4f matrix;
-
+ math::Axis target_axis;
float d = 0;
if (!core::localcontrol()) {
@@ -165,37 +174,102 @@ void draw(float seconds)
distance = 20.0f;
} else {
-
if (mode == Overview)
set_mode(Track);
if (core::localcontrol()->state()) {
target.assign(core::localcontrol()->state()->location());
- axis.assign(core::localcontrol()->state()->axis());
+ target_axis.assign(core::localcontrol()->state()->axis());
} else {
target.assign(core::localcontrol()->location());
- axis.assign(core::localcontrol()->axis());
+ target_axis.assign(core::localcontrol()->axis());
}
-
+
if (mode == Track) {
- if (core::localcontrol()->state() && core::localcontrol()->model()) {
- target -= (core::localcontrol()->model()->maxbbox().x + 0.15f) * core::localcontrol()->state()->axis().forward();
-
- target += (core::localcontrol()->model()->maxbbox().z + 0.3f ) *
- core::localcontrol()->state()->axis().up();
+ float cosangle;
+ float angle;
+ float side;
+ float u;
+ const float cam_speed = seconds * 4 ;
+
+ math::Vector3f n;
+ math::Vector3f p;
+
+ // camera axis: pitch
+
+ // project target_axis.up() into the plane with axis->left() normal
+ n = axis.left();
+ 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 = axis.forward().x * p.x +
+ axis.forward().y * p.y +
+ axis.forward().z * p.z;
+
+ if ((fabs(side) - MIN_DELTA > 0)) {
+
+ cosangle = math::dotproduct(p, axis.up());
+ if (fabs(cosangle) + MIN_DELTA < 1 ) {
+ angle = acos(cosangle) * 180.0f / M_PI;
+ angle = math::sgnf(side) * angle * cam_speed;
+ axis.change_pitch(-angle);
+ }
}
- // make the camera swing while turning
- target_direction = core::localcontrol()->target_direction;
- target_pitch = core::localcontrol()->target_pitch;
+ // camera axis: direction
+
+ // project target_axis.forward() into the plane with axis.up() normal
+ n = axis.up();
+ p = target_axis.forward();
+ 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.forward() + u * n;
+
+ side = axis.left().x * p.x +
+ axis.left().y * p.y +
+ axis.left().z * p.z;
+
+ if ((fabs(side) - MIN_DELTA > 0)) {
+
+ cosangle = math::dotproduct(p, axis.forward());
+ if (fabs(cosangle) + MIN_DELTA < 1 ) {
+ angle = acos(cosangle) * 180.0f / M_PI;
+ angle = math::sgnf(side) * angle * cam_speed;
+ axis.change_direction(angle);
+ }
+ }
- yaw_target = - 30 * target_direction;
- pitch_target = - 30 * target_pitch;
- //pitch_target = pitch_track - 30 * target_pitch;
+ // camera axis: roll
+
+ // project target_axis.up() into the plane with axis.forward() normal
+ n = 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 = axis.left().x * p.x +
+ axis.left().y * p.y +
+ axis.left().z * p.z;
+
+ if ((fabs(side) - MIN_DELTA > 0)) {
+
+ cosangle = math::dotproduct(p, axis.up());
+ if (fabs(cosangle) + MIN_DELTA < 1 ) {
+ angle = acos(cosangle) * 180.0f / M_PI;
+ angle = math::sgnf(side) * angle * cam_speed;
+ axis.change_roll(angle);
+ }
+ }
distance = 0.0f;
+ if (core::localcontrol()->model()) {
+ target -= (core::localcontrol()->model()->maxbbox().x + 0.1f) * axis.forward();
+ target += (core::localcontrol()->model()->maxbbox().z + 0.1f ) * axis.up();
+ }
+
} else if (mode == Free) {
+ axis.assign(target_axis);
yaw_target = yaw_current - 90 * target_direction;
pitch_target = pitch_current - 90 * target_pitch;
@@ -205,26 +279,25 @@ void draw(float seconds)
} else {
distance = 1.0f;
}
-
- } else if (mode == Cockpit) {
- if (core::localcontrol()->state() && core::localcontrol()->model())
- target += (core::localcontrol()->model()->maxbbox().x+0.05) *
- core::localcontrol()->state()->axis().forward();
-
- distance = 0.0f;
- }
-
- if (mode != Cockpit) {
// adjust direction
d = degrees180f(yaw_current - yaw_target);
yaw_current = degrees360f( yaw_current - d * seconds);
axis.change_direction(yaw_current);
- // adjust pitch target
+ // adjust pitch
d = degrees180f(pitch_current - pitch_target);
- pitch_current = degrees360f(pitch_current - d *seconds);
+ pitch_current = degrees360f(pitch_current - d * seconds);
axis.change_pitch(pitch_current);
+
+ } else if (mode == Cockpit) {
+ axis.assign(target_axis);
+
+ if (core::localcontrol()->state() && core::localcontrol()->model())
+ target += (core::localcontrol()->model()->maxbbox().x+0.05) *
+ core::localcontrol()->state()->axis().forward();
+
+ distance = 0.0f;
}
}
diff --git a/src/client/chat.cc b/src/client/chat.cc
index 1953390..9171387 100644
--- a/src/client/chat.cc
+++ b/src/client/chat.cc
@@ -4,6 +4,7 @@
the terms and conditions of the GNU General Public License version 2
*/
+#include "auxiliary/functions.h"
#include "core/core.h"
#include "client/chat.h"
#include "client/console.h"
@@ -71,24 +72,54 @@ void draw()
{
using namespace render;
- if (console::visible() || !visible())
+ if (console()->visible() || !visible())
return;
- size_t width = (size_t) (video::width / Text::fontwidth()) - 7;
- size_t draw_pos = 0;
- while (input_pos - draw_pos > width)
- draw_pos += 2;
+ size_t width = (size_t) (video::width / Text::fontwidth()) - 8;
+ float y = video::height*8/10;
+ Text::draw(4, y, "^BSay^F:^B ");
- // draw the chat input
- float y = video::height * 8.0 / 10.0;
+ std::string firstpart((*history_pos).substr(0, input_pos));
+ size_t draw_width = 0;
+ const char *c = firstpart.c_str();
- Text::draw(4 , y, "^Bsay^F:^B");
- Text::draw(4+Text::fontwidth()*5 , y, (*history_pos).substr(draw_pos, width));
+ while (*c) {
+ if (aux::is_color_code(c)) {
+ c++;
+ } else {
+ draw_width++;
+ }
+ c++;
+ }
+
+ c = firstpart.c_str();
+ while (*c && draw_width > width - 2) {
+ if (aux::is_color_code(c)) {
+ c++;
+ Text::setcolor(*c);
+ } else {
+ draw_width--;
+ }
+ c++;
+ }
+
+ if (*c) {
+ Text::draw(4+5*Text::fontwidth(), y, c);
+ }
+
+ if (input_pos < (*history_pos).size()) {
+ // FIXME limit to width
+ if (input_pos > 1 && aux::is_color_code((*history_pos).c_str() + input_pos -1)) {
+ Text::setcolor((*history_pos)[input_pos]);
+ }
+ c = (*history_pos).c_str() + input_pos;
+ Text::draw(4+Text::fontwidth()*(draw_width+5), y, c);
+ }
// draw cursor
if ((core::application()->time() - ::floorf(core::application()->time())) < 0.5f) {
std::string cursor("^B_");
- Text::draw(4+Text::fontwidth()*(input_pos - draw_pos+5), y, cursor);
+ Text::draw(4+Text::fontwidth()*(draw_width+5), y , cursor);
}
}
diff --git a/src/client/client.cc b/src/client/client.cc
index 97c0128..85dec27 100644
--- a/src/client/client.cc
+++ b/src/client/client.cc
@@ -25,6 +25,7 @@ namespace client
core::Cvar *cl_framerate = 0;
//--- private definition ------------------------------------------
+
/// client application implementation
class Client : public core::Application
{
@@ -49,10 +50,8 @@ Client app;
void func_r_restart(std::stringstream &args)
{
video::shutdown();
- console::flush();
if (!video::init()) {
- console::flush();
app.quit(1);
}
}
@@ -87,6 +86,7 @@ void Client::init(int count, char **arguments)
// initialize core
core::Cvar::sv_dedicated = core::Cvar::set("sv_private", "0");
core::Application::init(count, arguments);
+ Console::init();
// client variables
core::Cvar *cvar = 0;
@@ -104,12 +104,10 @@ void Client::init(int count, char **arguments)
// Initialize the video subsystem
if (!video::init()) {
- console::flush();
quit(1);
}
// initialize console
- console::init();
chat::init();
// initialize input
@@ -128,6 +126,9 @@ void Client::run()
Uint32 client_framerate = (Uint32)(1000/120);
Uint32 elapsed = 0;
+ console()->flush();
+ console()->clear_notify();
+
while (true) {
Uint32 chrono = SDL_GetTicks();
@@ -155,24 +156,19 @@ void Client::run()
void Client::shutdown()
{
con_print << "^BShutting down client..." << std::endl;
- console::flush();
// remove engine functions
core::Func::remove("r_restart");
chat::shutdown();
- console::shutdown();
- console::flush();
+ Console::shutdown();
input::shutdown();
- console::flush();
video::shutdown();
- console::flush();
core::Application::shutdown();
- console::flush();
quit(0);
}
diff --git a/src/client/console.cc b/src/client/console.cc
index 4c65581..f692db4 100644
--- a/src/client/console.cc
+++ b/src/client/console.cc
@@ -4,12 +4,12 @@
the terms and conditions of the GNU General Public License version 2
*/
+#include "client/console.h"
#include "auxiliary/functions.h"
#include "core/core.h"
#include "filesystem/filesystem.h"
#include "render/render.h"
#include "render/textures.h"
-#include "client/console.h"
#include "client/video.h"
#include "client/keyboard.h"
@@ -19,116 +19,225 @@
namespace client {
-namespace console {
+Console client_console;
-//--- private definition ------------------------------------------
+Console *console() {
+ return &client_console;
+}
+//--- engine functions --------------------------------------------
-/// private client console implementation
-class Console : public sys::ConsoleInterface {
-public:
- /// stream to send normal messages too
- virtual std::ostream & messagestream();
+void func_con_toggle(std::string const &args)
+{
+
+ console()->toggle();
+}
- /// stream to send warning messages too
- virtual std::ostream & warningstream();
+//--- public ------------------------------------------------------
- /// stream to send error messages too
- virtual std::ostream & errorstream();
-
- /// stream to send debug messages too
- virtual std::ostream & debugstream();
+void Console::init()
+{
+ con_print << "^BInitializing console..." << std::endl;
- /// flush buffered messages
- virtual void flush();
+ core::Func *func = core::Func::add("con_toggle", (core::FuncPtr) func_con_toggle);
+ func->set_info("toggle console on or off");
+ console()->load_history();
+}
+
+void Console::shutdown()
+{
+ con_print << "^BShutting down console..." << std::endl;
- /// console text buffer
- std::stringstream buffer;
-};
+ console()->save_history();
-// private client console object
-Console console;
+ // remove engine functions
+ core::Func::remove("con_toggle");
+}
+
+//--- Console -----------------------------------------------------
+
+Console::Console()
+{
+ clear();
+}
-// console text data
-std::deque<std::string> text;
+Console::~Console()
+{
+ history.clear();
+}
-// input history
-std::deque<std::string> history;
-std::deque<std::string>::reverse_iterator history_pos;
-size_t input_pos = 0;
+void Console::clear()
+{
+ console_visible = false;
+ console_scroll = 0;
+ history.clear();
+ history.push_back("");
+ history_pos = history.rbegin();
+ input_pos = 0;
-// console visibility
-bool console_visible = false;
-size_t console_scroll = 0;
+ clear_notify();
-// notifications
-size_t notify_pos = 0;
-std::string notify_text[MAXNOTIFYLINES];
-float notify_time[MAXNOTIFYLINES];
+}
-//--- engine functions --------------------------------------------
+void Console::draw() {
+ if (visible())
+ draw_console();
+ else
+ draw_notify();
+}
-void func_con_toggle(std::string const &args)
+void Console::toggle()
{
+ console_visible = !console_visible;
- std::istringstream argstream(args);
- int i;
+ if (console_visible) {
+ console_scroll = 0;
+ input_pos = 0;
+
+ history_pos = history.rbegin();
+ (*history_pos).clear();
- if (argstream >> i) {
- if (i) console_visible = false; else console_visible = true;
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+ SDL_ShowCursor(SDL_ENABLE);
+ } else {
+ SDL_WM_GrabInput(SDL_GRAB_ON);
+ SDL_ShowCursor(SDL_DISABLE);
+ clear_notify();
}
- toggle();
+
+ setkeyboardmode(visible());
}
-//--- public ------------------------------------------------------
-
-void clear_notify()
+void Console::keypressed(int key)
{
- for (size_t i=0; i < MAXNOTIFYLINES; i++) {
- notify_text[i].clear();
- notify_time[i] = 0;
+ std::deque<std::string>::reverse_iterator upit;
+
+ switch( key ) {
+ case SDLK_TAB:
+ core::CommandBuffer::complete( (*history_pos), input_pos);
+ break;
+ case SDLK_RETURN:
+ if ((*history_pos).size()) {
+ // store input into history
+ while (history.size() >= MAXHISTOLINES) {
+ history.pop_front();
+ }
+
+ core::cmd() << (*history_pos) << std::endl;
+ con_print << "^B>" << (*history_pos) << std::endl;
+ (*history.rbegin()) = (*history_pos);
+
+ history.push_back("");
+ history_pos = history.rbegin();
+ input_pos = 0;
+ }
+ break;
+ case SDLK_UP:
+ upit = history_pos;
+ ++upit;
+ if (upit != history.rend()) {
+ history_pos = upit;
+ input_pos = (*history_pos).size();
+ }
+ break;
+ case SDLK_DOWN:
+ if (history_pos != history.rbegin()) {
+ --history_pos;
+ input_pos = (*history_pos).size();
+ }
+ break;
+ case SDLK_HOME:
+ input_pos = 0;
+ break;
+ case SDLK_END:
+ input_pos = (*history_pos).size();
+ break;
+ case SDLK_LEFT:
+ if (input_pos > 0)
+ input_pos--;
+ break;
+ case SDLK_RIGHT:
+ if (input_pos < (*history_pos).size())
+ input_pos++;
+ break;
+ case SDLK_BACKSPACE:
+ if ((*history_pos).size() && input_pos) {
+ (*history_pos).erase(input_pos-1, 1);
+ input_pos--;
+ }
+ break;
+ case SDLK_PAGEUP:
+ console_scroll +=5;
+ if (console_scroll > consoleinterface_text.size()) console_scroll = consoleinterface_text.size();
+ break;
+ case SDLK_PAGEDOWN:
+ if (console_scroll > 5) console_scroll -=5;
+ else console_scroll = 0;
+ break;
+ default:
+ if ((key >= 32 ) && (key <175)) {
+ if (input_pos == (*history_pos).size())
+ (*history_pos) += (char)key;
+ else
+ (*history_pos).insert(input_pos, 1, (char)key);
+ input_pos++;
+ }
+ break;
}
+
+
}
-void init()
+void Console::save_history()
{
- con_print << "^BInitializing console..." << std::endl;
-
- console_visible = false;
-
- // add engine functions
- core::Func *func = core::Func::add("con_toggle", (core::FuncPtr) func_con_toggle);
- func->set_info("toggle console on or off");
- clear_notify();
- text.clear();
- console_scroll = 0;
+ if (history.size() <= 1)
+ return;
- history.clear();
- history.push_back("");
- history_pos = history.rbegin();
- input_pos = 0;
+ std::string filename(filesystem::writedir);
+ filename.append("history.txt");
+ std::ofstream ofs(filename.c_str());
- load_history();
+ if (!ofs.is_open()) {
+ con_warn << "Could not write " << filename << std::endl;
+ return;
+ }
+ std::deque<std::string>::iterator it;
+ size_t l = 1;
+ for (it = history.begin(); it != history.end(); it++) {
+ if (l < history.size())
+ ofs << (*it) << std::endl;
+ l++;
+ }
+
+ ofs.close();
}
-void shutdown()
+void Console::load_history()
{
- con_print << "^BShutting down console..." << std::endl;
-
- save_history();
+ std::string filename(filesystem::writedir);
+ filename.append("history.txt");
+ std::ifstream ifs(filename.c_str(), std::ifstream::in);
- // remove engine functions
- //core::Func::remove("con_toggle");
-
- text.clear();
- console_scroll = 0;
+ if (!ifs.is_open()) {
+ con_warn << "Could not read " << filename << std::endl;
+ return;
+ }
history.clear();
+ char line[MAXCMDSIZE];
+ while (ifs.getline(line, MAXCMDSIZE-1)) {
+ history.push_back(line);
+ }
+
+ ifs.close();
+
+ history.push_back("");
+ history_pos = history.rbegin();
input_pos = 0;
}
-void draw_notify()
+void Console::draw_notify()
{
using namespace render;
@@ -150,6 +259,7 @@ void draw_notify()
const char *c = linedata.c_str();
char pen = 'N';
+ char wordpen = 'N';
while (*c) {
@@ -170,7 +280,7 @@ void draw_notify()
h += Text::fontheight();
line.clear();
line += '^';
- line += pen;
+ line += wordpen;
line_length = 0;
}
}
@@ -180,6 +290,7 @@ void draw_notify()
word.clear();
word_length = 0;
+ wordpen = pen;
// new line
if (*c == '\n' ) {
@@ -205,7 +316,7 @@ void draw_notify()
h += Text::fontheight();
line.clear();
line += '^';
- line += pen;
+ line += wordpen;
line_length = 0;
}
@@ -214,6 +325,7 @@ void draw_notify()
word.clear();
word_length = 0;
+ wordpen = pen;
}
}
@@ -225,7 +337,7 @@ void draw_notify()
}
}
-void draw_console()
+void Console::draw_console()
{
using namespace render;
@@ -251,17 +363,17 @@ void draw_console()
gl::color(0.0f, 1.0f, 0.0f, 0.5f);
Text::draw(video::width-Text::fontwidth()*(version.size()+1), video::height*con_height-Text::fontheight()-4, version);
- // draw the console text
- if (console_scroll > text.size())
- console_scroll = text.size();
+ // draw the console consoleinterface_text
+ if (console_scroll > consoleinterface_text.size())
+ console_scroll = consoleinterface_text.size();
size_t height = (size_t) (video::height * con_height / Text::fontheight()) -1;
size_t width = (size_t) ((video::width-8) / Text::fontwidth());
- size_t bottom = text.size() - console_scroll;
+ size_t bottom = consoleinterface_text.size() - console_scroll;
size_t current_line = 0;
std::deque<std::string> lines;
- for (std::deque<std::string>::iterator it = text.begin(); it != text.end() && current_line < bottom; it++) {
+ for (std::deque<std::string>::iterator it = consoleinterface_text.begin(); it != consoleinterface_text.end() && current_line < bottom; it++) {
if (current_line >= bottom - height) {
std::string linedata(*it);
linedata += '\n';
@@ -274,6 +386,7 @@ void draw_console()
const char *c = linedata.c_str();
char pen = 'N';
+ char wordpen = 'N';
while (*c) {
@@ -293,7 +406,7 @@ void draw_console()
lines.push_back(line);
line.clear();
line += '^';
- line += pen;
+ line += wordpen;
line_length = 0;
}
}
@@ -303,6 +416,7 @@ void draw_console()
word.clear();
word_length = 0;
+ wordpen = pen;
// new line
if (*c == '\n' ) {
@@ -326,7 +440,7 @@ void draw_console()
lines.push_back(line);
line.clear();
line += '^';
- line += pen;
+ line += wordpen;
line_length = 0;
}
@@ -335,6 +449,7 @@ void draw_console()
word.clear();
word_length = 0;
+ wordpen = pen;
}
}
@@ -354,233 +469,86 @@ void draw_console()
// draw the console input
- size_t draw_pos = 0;
y = video::height*con_height - Text::fontheight() - 4;
-
- while (input_pos - draw_pos > width)
- draw_pos += 2;
-
Text::draw(4, y, "^B>");
- Text::draw(4+Text::fontwidth(), y , (*history_pos).substr(draw_pos, width-1));
- // draw cursor
- if ((core::application()->time() - ::floorf(core::application()->time())) < 0.5f) {
- std::string cursor("^B_");
- Text::draw(4+Text::fontwidth()*(input_pos-draw_pos+1), y , cursor);
- }
-
-}
-
-void draw(){
- if (visible())
- draw_console();
- else
- draw_notify();
-}
+ std::string firstpart((*history_pos).substr(0, input_pos));
+ size_t draw_width = 0;
+ const char *c = firstpart.c_str();
-void flush()
-{
- char line[MAXCMDSIZE];
- while(console.buffer.getline(line, MAXCMDSIZE-1)) {
- while (text.size() >= MAXCONLINES) {
- text.pop_front();
+ while (*c) {
+ if (aux::is_color_code(c)) {
+ c++;
+ } else {
+ draw_width++;
}
- text.push_back(std::string(line));
-
- // save notification
- notify_text[notify_pos] = line;
- notify_time[notify_pos] = core::application()->time();
- notify_pos = (notify_pos+1) % MAXNOTIFYLINES;
-
- // print to stdout
- std::cout << line << std::endl;
+ c++;
}
-
- console.buffer.clear();
-}
-
-void toggle()
-{
- console_visible = !console_visible;
-
- if (console_visible) {
- console_scroll = 0;
- input_pos = 0;
- history_pos = history.rbegin();
- (*history_pos).clear();
-
- SDL_WM_GrabInput(SDL_GRAB_OFF);
- SDL_ShowCursor(SDL_ENABLE);
- } else {
- SDL_WM_GrabInput(SDL_GRAB_ON);
- SDL_ShowCursor(SDL_DISABLE);
- clear_notify();
+ c = firstpart.c_str();
+ while (*c && draw_width > width - 2) {
+ if (aux::is_color_code(c)) {
+ c++;
+ Text::setcolor(*c);
+ } else {
+ draw_width--;
+ }
+ c++;
}
-
- setkeyboardmode(console::visible());
-}
-
-void keypressed(int key)
-{
- std::deque<std::string>::reverse_iterator upit;
-
- switch( key ) {
- case SDLK_TAB:
- core::CommandBuffer::complete( (*history_pos), input_pos);
- break;
- case SDLK_RETURN:
- if ((*history_pos).size()) {
- // store input into history
- while (history.size() >= MAXHISTOLINES) {
- history.pop_front();
- }
- core::cmd() << (*history_pos) << std::endl;
- con_print << "^B>" << (*history_pos) << std::endl;
- (*history.rbegin()) = (*history_pos);
+ if (*c) {
+ Text::draw(4+Text::fontwidth(), y, c);
+ }
- history.push_back("");
- history_pos = history.rbegin();
- input_pos = 0;
- }
- break;
- case SDLK_UP:
- upit = history_pos;
- ++upit;
- if (upit != history.rend()) {
- history_pos = upit;
- input_pos = (*history_pos).size();
- }
- break;
- case SDLK_DOWN:
- if (history_pos != history.rbegin()) {
- --history_pos;
- input_pos = (*history_pos).size();
+ if (input_pos < (*history_pos).size()) {
+ // FIXME limit to width
+ if (input_pos > 1 && aux::is_color_code((*history_pos).c_str() + input_pos -1)) {
+ Text::setcolor((*history_pos)[input_pos]);
}
- break;
- case SDLK_HOME:
- input_pos = 0;
- break;
- case SDLK_END:
- input_pos = (*history_pos).size();
- break;
- case SDLK_LEFT:
- if (input_pos > 0)
- input_pos--;
- break;
- case SDLK_RIGHT:
- if (input_pos < (*history_pos).size())
- input_pos++;
- break;
- case SDLK_BACKSPACE:
- if ((*history_pos).size() && input_pos) {
- (*history_pos).erase(input_pos-1, 1);
- input_pos--;
- }
- break;
- case SDLK_PAGEUP:
- console_scroll +=5;
- if (console_scroll > text.size()) console_scroll = text.size();
- break;
- case SDLK_PAGEDOWN:
- if (console_scroll > 5) console_scroll -=5;
- else console_scroll = 0;
- break;
- default:
- if ((key >= 32 ) && (key <175)) {
- if (input_pos == (*history_pos).size())
- (*history_pos) += (char)key;
- else
- (*history_pos).insert(input_pos, 1, (char)key);
- input_pos++;
- }
- break;
+ c = (*history_pos).c_str() + input_pos;
+ Text::draw(4+Text::fontwidth()*(draw_width+1), y, c);
}
-
-}
-
-bool visible()
-{
- return console_visible;
-}
-
-void save_history()
-{
-
- if (history.size() <= 1)
- return;
-
- std::string filename(filesystem::writedir);
- filename.append("history.txt");
- std::ofstream ofs(filename.c_str());
-
- if (!ofs.is_open()) {
- con_warn << "Could not write " << filename << std::endl;
- return;
- }
- std::deque<std::string>::iterator it;
- size_t l = 1;
- for (it = history.begin(); it != history.end(); it++) {
- if (l < history.size())
- ofs << (*it) << std::endl;
- l++;
+ // draw cursor
+ if ((core::application()->time() - ::floorf(core::application()->time())) < 0.5f) {
+ std::string cursor("^B_");
+ Text::draw(4+Text::fontwidth()*(draw_width+1), y , cursor);
}
- ofs.close();
}
-void load_history()
-{
- std::string filename(filesystem::writedir);
- filename.append("history.txt");
- std::ifstream ifs(filename.c_str(), std::ifstream::in);
- if (!ifs.is_open()) {
- con_warn << "Could not read " << filename << std::endl;
- return;
- }
-
- history.clear();
- char line[MAXCMDSIZE];
- while (ifs.getline(line, MAXCMDSIZE-1)) {
- history.push_back(line);
+void Console::clear_notify()
+{
+ for (size_t i=0; i < MAXNOTIFYLINES; i++) {
+ notify_text[i].clear();
+ notify_time[i] = 0;
}
-
- ifs.close();
-
- history.push_back("");
- history_pos = history.rbegin();
- input_pos = 0;
+ notify_pos = 0;
}
-//--- private -----------------------------------------------------
void Console::flush()
{
- console::flush();
-}
+ char line[MAXCMDSIZE];
-std::ostream & Console::messagestream()
-{
- return (buffer << "^N");
-}
+ while(consoleinterface_buffer.getline(line, MAXCMDSIZE-1)) {
-std::ostream & Console::warningstream()
-{
- return (buffer << "^W");
-}
+ while (consoleinterface_text.size() >= sys::MAXCONLINES) {
+ consoleinterface_text.pop_front();
+ }
+ consoleinterface_text.push_back(std::string(line));
-std::ostream & Console::errorstream()
-{
- return (buffer << "^R");
-}
+ // save notification
+ notify_text[notify_pos] = line;
+ notify_time[notify_pos] = core::application()->time();
+ notify_pos = (notify_pos+1) % MAXNOTIFYLINES;
-std::ostream & Console::debugstream()
-{
- return (buffer << "^D");
+ // print to stdout
+ print_ansi(line);
+ std::cout << std::endl;
+ }
+
+ consoleinterface_buffer.clear();
}
-} // namespace console
-
} // namespace client
diff --git a/src/client/console.h b/src/client/console.h
index dc831b7..2f8d6a0 100644
--- a/src/client/console.h
+++ b/src/client/console.h
@@ -9,54 +9,70 @@
#include "sys/consoleinterface.h"
-#include <sstream>
-#include <deque>
+namespace client {
-const size_t MAXCONLINES = 2048;
-const size_t MAXHISTOLINES = 512;
const size_t MAXNOTIFYLINES = 3;
+const size_t MAXHISTOLINES = 512;
-namespace client {
+/// client console implementation
+class Console : public sys::ConsoleInterface {
+public:
+ Console();
+ virtual ~Console();
-/// the client console
-namespace console {
+ virtual void flush();
-/// initialize client console
-/** Adds the engine functions for the client console
- */
-void init();
+ void draw_console();
-/// shutdown the client console
-/** Removes the engine functions for the client console
- */
-void shutdown();
+ void draw_notify();
-/// flush buffer messages and print to stdout
-void flush();
-
-/// draw the console
-void draw();
+ /// clear notifications
+ void clear_notify();
-/// toggle the console on or off
-void toggle();
+ /// draw client notifications or console text
+ void draw();
-/// handle keyboard input
-void keypressed(int key);
+ /// toggle the console on or off
+ void toggle();
-/// true of the console is visible
-bool visible();
+ /// handle keyboard input
+ void keypressed(int key);
-/// load input history
-void load_history();
+ /// true of the console is visible
+ inline bool visible() { return console_visible; }
-/// save input history
-void save_history();
+ /// load input history
+ void load_history();
-extern size_t notify_pos;
-extern std::string notify_text[MAXNOTIFYLINES];
-extern float notify_time[MAXNOTIFYLINES];
+ /// save input history
+ void save_history();
-}
+ /// clear console
+ void clear();
+
+ /// initialize client console
+ static void init();
+
+ /// shutdown the client console
+ static void shutdown();
+
+private:
+ // notifications
+ size_t notify_pos;
+ std::string notify_text[MAXNOTIFYLINES];
+ float notify_time[MAXNOTIFYLINES];
+
+ // input history
+ std::deque<std::string> history;
+ std::deque<std::string>::reverse_iterator history_pos;
+ size_t input_pos;
+
+ bool console_visible;
+ size_t console_scroll;
+
+};
+
+Console *console();
}
diff --git a/src/client/input.cc b/src/client/input.cc
index f40591c..22db6bc 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -221,31 +221,31 @@ void frame(float seconds)
mouse_y = event.motion.y;
break;
case SDL_MOUSEBUTTONDOWN:
- if (!console::visible() && core::application()->connected() && core::localcontrol())
+ 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() &&
+ } 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 (chat::visible() && !console::visible() && (event.key.keysym.sym == SDLK_ESCAPE)) {
+ 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;
- console::toggle();
+ console()->toggle();
- if (console::visible() && chat::visible())
+ if (console()->visible() && chat::visible())
chat::toggle();
- } else if (console::visible()) {
+ } else if (console()->visible()) {
// send key events to the console
- console::keypressed(translate_keysym(event.key.keysym));
+ console()->keypressed(translate_keysym(event.key.keysym));
} else if (chat::visible()) {
if(event.key.keysym.sym == SDLK_ESCAPE) {
@@ -270,7 +270,7 @@ void frame(float seconds)
}
- if (!console::visible() && core::application()->connected() && core::localcontrol()) {
+ if (!console()->visible() && core::application()->connected() && core::localcontrol()) {
if (cl_mousecontrol->value()) {
// the mouse will not react if it is in the deadzone
@@ -302,8 +302,8 @@ void frame(float seconds)
}
if ((camera::mode == camera::Track) || (camera::mode == camera::Cockpit)) {
- local_direction = mouse_direction;
- local_pitch = mouse_pitch;
+ local_direction = mouse_direction * math::absf(mouse_direction);
+ local_pitch = mouse_pitch * math::absf(mouse_pitch);
} else if (camera::mode == camera::Free) {
// squared values to smoothen camera movement
camera::set_direction( -mouse_direction * math::absf(mouse_direction));
diff --git a/src/client/view.cc b/src/client/view.cc
index 63c373e..e2c8687 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -128,7 +128,7 @@ void draw_status()
{
using namespace render;
- if (console::visible())
+ if (console()->visible())
return;
// print the status in the upper left corner
@@ -171,7 +171,7 @@ void draw_status()
void draw_cursor()
{
- if (!core::localcontrol() || console::visible())
+ if (!core::localcontrol() || console()->visible())
return;
float crosshair_size = 48.0f;
@@ -222,7 +222,7 @@ void frame(float seconds)
fps = 9999;
// flush console messages
- console::flush();
+ console()->flush();
// Clear the color and depth buffers.
gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -234,7 +234,7 @@ void frame(float seconds)
gl::loadidentity();
// FIXME width must always be one
- const float frustumsize = 0.5f;
+ const float frustumsize = 0.25f;
gl::frustum(-frustumsize*video::aspect, frustumsize*video::aspect, -frustumsize, frustumsize, 1.0f, 1024.0f);
gl::matrixmode(GL_MODELVIEW); // map world to screen coordinates
@@ -263,7 +263,7 @@ void frame(float seconds)
// draw text elements
Text::setfont("bitmaps/fonts/console", 12, 18);
- console::draw();
+ console()->draw();
chat::draw();
Text::setfont("bitmaps/fonts/gui", 16, 24);