// $Id: console.cpp 2986 2007-08-17 16:20:09Z grumbel $ // // Pingus - A free Lemmings clone // Copyright (C) 2000 Ingo Ruhnke // // 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 2 // 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, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include "fonts.hpp" #include "console.hpp" #include "math.hpp" using std::ostream; // Globale console Console console; ConsoleBuffer::ConsoleBuffer () : buffer(NUM_LINES) { // Set the output buffer setp (char_buffer, char_buffer + CONSOLE_BUFFER_SIZE - 1); // Switch of input buffer setg(0, 0, 0); } ConsoleBuffer::~ConsoleBuffer () { sync (); } int ConsoleBuffer::overflow (int c) { std::string str = fill_buffer(true); str += c; buffer.push_back(str); buffer.pop_front(); setp (char_buffer, char_buffer + CONSOLE_BUFFER_SIZE - 1); return 0; } int ConsoleBuffer::sync () { std::string str = fill_buffer(false); if (!str.empty()) { buffer.push_back(str); buffer.pop_front(); } setp(char_buffer, char_buffer + CONSOLE_BUFFER_SIZE - 1); return 0; } std::string ConsoleBuffer::fill_buffer (bool append) { std::string str; if (append) { str = *(--buffer.end()); buffer.pop_back(); buffer.push_front(""); } for (char* c = pbase (); c != pptr (); ++c) { if (*c != '\n') str += *c; else { if (str.size() > MAX_LINE_LENGTH) { std::string::size_type pos = str.rfind(' '); if (pos == std::string::npos) pos = MAX_LINE_LENGTH; buffer.push_back(str.substr(0, pos)); buffer.pop_front(); str = str.substr(pos, str.size()); } buffer.push_back(str); buffer.pop_front(); str = ""; } } return str; } const std::list& ConsoleBuffer::get_buffer () { return buffer; } Console::Console() : ostream (&streambuf) // std:: is missing here since Win32 doesn't like it { is_init = false; is_visible = false; current_pos = 0; number_of_lines = 12; *this << "================================" << std::endl; *this << "Welcome to Pingus " << VERSION << std::endl; *this << "================================" << std::endl; newline (); *this << "This is the output and debug console, you can toggle it with F1" << std::endl; newline (); } Console::~Console() { } // We are not initialising the console in the constructor, 'cause // that doesn't work (ClanLib hasn't init the display at that point) void void Console::init() { // std::cout << "Console: Init..." << std::endl; font = Fonts::courier_small; // (*this) << "Pingus Output Console (hide/show it with F1)\n" // << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; is_init = true; } // Unload any ClanLib objects that might linger around after we // destroy the graphics context void Console::deinit() { font = Font(); } void Console::draw() { assert(is_init); /** Callculate the position of the first line on the screen */ int start_y_pos = Display::get_height() - (font.get_height() * (number_of_lines + 3)); // The background of the console Display::fill_rect(Rect(0, start_y_pos - 15, Display::get_width(), Display::get_height()), Color(0, 50, 0, 128)); Display::fill_rect(Rect(0, start_y_pos - 15 - 4, Display::get_width(), start_y_pos - 15), Color(0, 150, 0, 128)); const std::list& buffer = streambuf.get_buffer (); unsigned int window_start = Math::max(0, int(buffer.size() - number_of_lines - current_pos)); std::list::const_iterator it = buffer.begin(); // move iterator to the first line to be displayed for (unsigned int i = 0; i < window_start; ++i) ++it; for (unsigned int i = 0; i < number_of_lines && i + window_start < buffer.size(); ++it, ++i) { font.draw(10, start_y_pos + (i * (font.get_height() + 2)), it->c_str() ); } } void Console::increase_lines() { ++number_of_lines; } void Console::decrease_lines() { if (number_of_lines > 0) --number_of_lines; } void Console::scroll_up() { if (current_pos + number_of_lines < streambuf.get_buffer().size()) ++current_pos; } void Console::scroll_down() { if (current_pos) --current_pos; } void Console::set_lines(int a) { number_of_lines = a; } int Console::get_lines() { return number_of_lines; } void Console::puts(const std::string& str) { (*this) << str.c_str() << std::endl; } void Console::newline() { (*this) << std::endl; } void Console::on_event() { draw(); } /* EOF */