From a185c11f2397c0296a4b62cc266b4fa00a63c1e2 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 14 May 2008 21:07:10 +0000 Subject: console, camera & interpolation --- src/client/console.cc | 536 ++++++++++++++++++++++++-------------------------- 1 file changed, 252 insertions(+), 284 deletions(-) (limited to 'src/client/console.cc') 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 text; +Console::~Console() +{ + history.clear(); +} -// input history -std::deque history; -std::deque::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::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::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 lines; - for (std::deque::iterator it = text.begin(); it != text.end() && current_line < bottom; it++) { + for (std::deque::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::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::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 -- cgit v1.2.3