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/console.cc')
-rw-r--r--src/client/console.cc536
1 files changed, 252 insertions, 284 deletions
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