/trunk/nil-ng/src/client/console/SdlConsole.cc
C++ | 283 lines | 225 code | 38 blank | 20 comment | 28 complexity | 058c2a2f1f0492cfd36e25f35aa5f03e MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0
- /********************************************************************************
- * NiL isn't Liero
- * SdlConsole.cc - SDL-based console implementation
- *
- * Copyright (C) 2005,2006,2007 Alexander Kahl <e-user@gmx.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- *****************************************************************************/
- #include <client/SdlConsole.h>
- #include <VFS.h>
- #include <string>
- #include <sstream>
- #include <cmath>
- #include <sys/types.h>
- #include <regex.h>
- #include <malloc.h>
- SdlConsole::SdlConsole(IConsole::Severity minimum, SdlConsole::Mode _mode)
- : IConsole(minimum), Interactive(), Movable(), mode(_mode)
- {
- this->initialize();
- *this->cmessage << "SDL console started!" << IConsole::endl;
- }
- SdlConsole::~SdlConsole()
- {
- *IConsole::primary()->cmessage << "Closing SDL console..." << IConsole::endl;
- delete this->nil_logo;
-
- for(std::vector<Font*>::iterator i = this->font_table.begin(); i < this->font_table.end(); i++)
- delete *i;
- }
- void
- SdlConsole::initialize()
- {
- Graphics& graphics = Graphics::instance();
-
- try
- {
- this->nil_logo = new GraphicItem("data/gfx/logos/nil_small.png");
- this->nil_logo->destination.x += graphics.width() - (this->nil_logo->destination.w + 1);
- }
- catch(NilException ex) // TODO: Replace with appropriate exception
- {
- *this->cerror << "Error loading NiL logo!" << IConsole::endl;
- this->nil_logo = NULL;
- }
-
- Font* font;
- font = new Font(this, "data/fonts/DejaVu LGC Sans Mono.ttf", 8, Graphics::create_color(0x3d, 0x45, 0xb3), Font::NORMAL);
- this->font_table.push_back(font);
- font = new Font(this, "data/fonts/DejaVu LGC Sans Mono.ttf", 8, Graphics::create_color(0xff, 0xff, 0xff), Font::NORMAL);
- this->font_table.push_back(font);
- font = new Font(this, "data/fonts/DejaVu LGC Sans Mono.ttf", 8, Graphics::create_color(0xf2, 0xff, 0x23), Font::NORMAL);
- this->font_table.push_back(font);
- font = new Font(this, "data/fonts/DejaVu LGC Sans Mono.ttf", 8, Graphics::create_color(0xd9, 0x2d, 0x2d), Font::NORMAL);
- this->font_table.push_back(font);
- font = new Font(this, "data/fonts/DejaVu LGC Sans Mono.ttf", 8, Graphics::create_color(0xbf, 0x2d, 0xd9), Font::NORMAL);
- this->font_table.push_back(font);
- switch (this->mode)
- {
- case SdlConsole::INACTIVE:
- this->height = 0;
- break;
- case SdlConsole::ACTIVE:
- this->height = graphics.height() / 4;
- break;
- case SdlConsole::FULLSCREEN:
- this->height = graphics.height();
- break;
- }
- }
- void
- SdlConsole::set_mode(SdlConsole::Mode _mode)
- {
- this->mode = _mode;
-
- switch(this->mode)
- {
- case SdlConsole::INACTIVE:
- case SdlConsole::FULLSCREEN:
- this->movement.second = -100;
- break;
- case SdlConsole::ACTIVE:
- this->movement.second = 100;
- break;
- default:
- break;
- }
- }
- void
- SdlConsole::put_output(std::string message)
- {
- this->buffer += message;
- this->history += message;
- }
- void
- SdlConsole::clear()
- {
- this->buffer.clear();
- }
- void
- SdlConsole::draw()
- {
- if(this->movement.second)
- this->move();
-
- Graphics::instance().blit(this->nil_logo->image, &this->nil_logo->destination);
- IConsole::Severity level = this->chattiness;
- Font *font = this->font_table.at(level);
- unsigned int x = 0;
- int y = this->height - 2 * font->advance_y();
- int index = (int)this->buffer.find_last_of("\n", this->buffer.size() - 2);
- int limit = 0 - (int)font->advance_y();
-
- while(index != -1 && y > limit)
- {
- if(index == (int)std::string::npos)
- index = -1;
-
- for(std::string::size_type i = index + 1; this->buffer.at(i) != '\n'; i++)
- {
- char c = this->buffer.at(i);
-
- if(c == '\033')
- i = this->format_output(this->buffer, i + 1, &level);
- else
- {
- font = this->font_table.at(level);
- SDL_Surface* glyph_surface = font->render_glyph(c);
- SDL_Rect destination_rect = glyph_surface->clip_rect;
- destination_rect.x = x + font->minimum_x(c) + 2;
- destination_rect.y = y + (font->advance_y() - font->maximum_y(c));
- Graphics::instance().blit(glyph_surface, &destination_rect);
- x += font->advance_x(c);
- }
- }
- index = this->buffer.find_last_of("\n", index - 1);
- x = 0;
- y -= font->advance_y();
- }
- }
- int
- SdlConsole::format_output(std::string& sequence,
- std::string::size_type pos,
- IConsole::Severity* level) const
- {
- std::stringstream reader;
- int code;
- struct re_pattern_buffer* pattern_buffer = (struct re_pattern_buffer*) malloc(sizeof(struct re_pattern_buffer));
- pattern_buffer->translate = 0;
- pattern_buffer->fastmap = 0;
- pattern_buffer->buffer = 0;
- pattern_buffer->allocated = 0;
- re_compile_pattern("^[[0-9;]+m", 10, pattern_buffer);
- int length = sequence.substr(pos).size();
- if(re_search(pattern_buffer, sequence.substr(pos).c_str(), length, 0, length, 0) != -1)
- {
- pos++;
-
- for(char c = ' '; c != 'm'; pos++)
- {
- c = sequence.at(pos);
-
- if(c != ';' && c != 'm')
- reader << c;
- else
- {
- reader >> code;
- switch(code)
- {
- case 34: // Blue
- *level = IConsole::DEBUG;
- break;
-
- case 39: // White
- *level = IConsole::MESSAGE;
- break;
-
- case 33: // Yellow
- *level = IConsole::WARNING;
- break;
-
- case 31: // Red
- *level = IConsole::ERROR;
- break;
-
- case 35: // Purple
- *level = IConsole::FATAL;
- break;
- }
- reader.clear();
- }
- }
- }
-
- regfree(pattern_buffer);
- return pos - 1;
- }
- void
- SdlConsole::move()
- {
- Graphics& graphics = Graphics::instance();
-
- switch(this->mode)
- {
- case SdlConsole::INACTIVE:
- if(this->height / abs((int)this->movement.second) > 0)
- this->height += (int)this->movement.second;
- else
- {
- this->height = 0;
- this->movement.second = 0;
- }
- break;
-
- case SdlConsole::ACTIVE:
- if(this->height + this->movement.second < graphics.height() / 4)
- this->height += (int)this->movement.second;
- else
- {
- this->height = graphics.height() / 4;
- this->movement.second = 0;
- }
- break;
-
- case SdlConsole::FULLSCREEN:
- if(this->height + this->movement.second < graphics.height())
- this->height += (int)this->movement.second;
- else
- {
- this->height = graphics.height();
- this->movement.second = 0;
- }
- default:
- break;
- }
- }
- void
- SdlConsole::_handle_keyboard_event(SDL_Event event)
- {
- if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_CARET)
- {
- if(this->mode == SdlConsole::INACTIVE)
- this->set_mode(SdlConsole::ACTIVE);
- else
- this->set_mode(SdlConsole::INACTIVE);
- }
- }
- void
- SdlConsole::_handle_mouse_event(SDL_Event event)
- {
- }