//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D 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. // // Scorched3D 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 Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include unsigned GLConsoleLine::nextLineNumber_ = 0; GLConsoleLine::GLConsoleLine() : lineType_(eNone), lineNumber_(0) { } GLConsoleLine::~GLConsoleLine() { } void GLConsoleLine::set(const char *line, LineType type) { line_ = std::string(line); lineType_ = type; if (lineType_ == eCommand) { lineNumber_ = ++nextLineNumber_; } if (lineType_ == eCommandCont) { lineNumber_ = nextLineNumber_; } lineNumberStr_= formatString("%4i", lineNumber_); } void GLConsoleLine::drawLine(float x, float y, GLFont2d *font) { static Vector color(0.9f, 0.9f, 0.9f); if (lineType_ != eNone) { if (lineType_ == eCommand) { // We show a line number of those lines with commands // on them font->draw(color, 12, x, y, 0.0f, lineNumberStr_.c_str()); font->draw(color, 12, x + 50.0f, y, 0.0f, line_.c_str()); } else { font->draw(color, 12, x + 50.0f, y, 0.0f, "..."); font->draw(color, 12, x + 90.0f, y, 0.0f, line_.c_str()); } } else { font->draw(color, 12, x + 50.0f, y, 0.0f, line_.c_str()); } } GLConsoleLines::GLConsoleLines(int maxLines) : maxLines_(maxLines), currentLine_(0) { } GLConsoleLines::~GLConsoleLines() { } void GLConsoleLines::clear() { currentLine_ = 0; while (!lines_.empty()) { GLConsoleLine *line = lines_.front(); lines_.pop_front(); delete line; } } void GLConsoleLines::scroll(int lines) { currentLine_ -= lines; if (currentLine_ < 0) currentLine_ = 0; else if (currentLine_ >= (int) lines_.size()) currentLine_ = (int) lines_.size(); } const char *GLConsoleLines::getItem(int linecount) { int linesSize = (int) lines_.size(); if (linecount < 0) { for (int line = currentLine_ + 1; line < linesSize; line++) { GLConsoleLine *consoleline = lines_[line]; if (consoleline->getLineType() == GLConsoleLine::eCommand) { linecount++; currentLine_ = line; if (linecount == 0) break; } } } else { for (int line = currentLine_ - 1; line >= 0 && line < linesSize; line--) { GLConsoleLine *consoleline = lines_[line]; if (consoleline->getLineType() == GLConsoleLine::eCommand) { linecount--; currentLine_ = line; if (linecount == 0) break; } } } // Check the command is valid and return the line if (currentLine_ >= 0 && currentLine_ < linesSize) { if (lines_[currentLine_]->getLineType() == GLConsoleLine::eCommand) { static std::string result; // This current line result = lines_[currentLine_]->getLine(); // Any continues of this line int current = currentLine_ - 1; while (current < linesSize && current >= 0 && lines_[current]->getLineType() == GLConsoleLine::eCommandCont) { result.append(lines_[current]->getLine()); current--; } return result.c_str(); } } return ""; } void GLConsoleLines::addLine(const char *text, bool showPointer) { if (showPointer) reset(); const int bufferSize = 80; int section = 0; int len = (int) strlen(text); if (len < bufferSize) { addSmallLine(section++, text, showPointer); } else { static char buffer[bufferSize + 2]; int c = 0; const char *a; for (a=text, c=0; *a; a++, c++) { buffer[c] = *a; if ((c==bufferSize) || (c>bufferSize-15 && *a ==' ')) { buffer[c+1] = '\0'; c=-1; addSmallLine(section++, buffer, showPointer); } } if (buffer[0]) { buffer[c] = '\0'; addSmallLine(section++, buffer, showPointer); } } } void GLConsoleLines::addSmallLine(int sectionNo, const char *text, bool showPointer) { GLConsoleLine::LineType type = GLConsoleLine::eNone; if (showPointer) { if (sectionNo == 0) type = GLConsoleLine::eCommand; else type = GLConsoleLine::eCommandCont; } if (lines_.size() == maxLines_) { // We need to reuse the lines // reuse the first line GLConsoleLine *line = lines_.back(); lines_.pop_back(); line->set(text, type); lines_.push_front(line); } else { // Add a new line GLConsoleLine *line = new GLConsoleLine; line->set(text, type); lines_.push_front(line); } // Set the lookat and cursor to point at the new line if (currentLine_ != 0) { currentLine_ ++; if (currentLine_ > (int) lines_.size()) currentLine_ = (int) lines_.size(); } } void GLConsoleLines::drawLines(GLFont2d *font, float startHeight, float totalHeight, float totalWidth) { if (currentLine_ != 0) { // Draw arrows at the bottom of the screen if stuff off bottom glColor3f(0.7f, 0.7f, 0.7f); glBegin(GL_TRIANGLES); for (float a=100.0f; adrawLine(20.0f, position, font); position += 15.0f; if (position > totalHeight - 20.0f) { offTop = true; break; } } } if (offTop) { // Draw arrows at top of screen if stuff off top glColor3f(0.7f, 0.7f, 0.7f); glBegin(GL_TRIANGLES); for (float a=100.0f; a