/* * Descent 3 * Copyright (C) 2024 Parallax Software * * 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 . */ /* * $Logfile: /DescentIII/Main/ui/UIConsole.cpp $ * $Revision: 8 $ * $Date: 8/11/99 10:50a $ * $Author: Samir $ * * Console system * * $Log: /DescentIII/Main/ui/UIConsole.cpp $ * * 8 8/11/99 10:50a Samir * possible fix to console bug with really wacky formatted strings * exceeding rowsize. * * 7 4/14/99 1:52a Jeff * fixed case mismatched #includes * * 6 11/03/98 7:05p Samir * added word wrapping console. * * 5 10/13/98 8:21p Samir * disable input to console gadget. * * 4 6/23/98 5:05p Samir * console supports color per line ONLY. * * 3 6/22/98 2:15p Samir * added UIConsoleGadget. * * 2 2/02/98 7:35p Samir * Full scrolling for console windows. * * 1 1/30/98 3:26p Samir * UI Console initial revision. * * $NoKeywords: $ */ #include "UIlib.h" #include "grtext.h" #include "mem.h" #include "textaux.h" #include #include #include #define CONSOLE_LINE_FILLER 128 // UIConsoleGadget should display a simple console gadget inside a window // int m_ConsoleFont; // standard font for text in console // char *m_ConsoleBuffer; // text buffer of console. UIConsoleGadget::UIConsoleGadget() { m_ConsoleFont = -1; m_ConsoleBuffer = NULL; m_ColorRows = NULL; m_PutsBuffer = NULL; } UIConsoleGadget::~UIConsoleGadget() {} // font = console font, NOT GADGET FONT. This font is used to proportion window void UIConsoleGadget::Create(UIWindow *parent, int id, int x, int y, int font, int cols, int rows, int flags) { int cw, ch, w, h; int i; grtext_SetFont(font); cw = grtext_GetLineWidth("A"); ch = grfont_GetHeight(font) + 1; w = cw * (cols + 3); h = ch * (rows + 3); UIGadget::Create(parent, id, x, y, w, h, flags); // initialize console info. m_ConsoleFont = font; m_Rows = rows; m_Cols = cols; m_VisRows = m_Rows; m_VisRowStart = 0; m_CurRow = 0; m_CurCol = 0; m_OffX = cw + cw / 2; m_OffY = ch + ch / 2; m_Rowsize = m_Cols + CONSOLE_LINE_FILLER + 1; m_LineIndex = 0; grtext_Reset(); // extra 32 bytes per row for color coding. m_ConsoleBuffer = (char *)mem_malloc(m_Rows * m_Rowsize); m_PutsBufLen = 512; m_PutsBuffer = (char *)mem_malloc(m_PutsBufLen); m_ColorRows = new ddgr_color[m_Rows]; memset(m_ConsoleBuffer, 0, m_Rows * m_Rowsize); for (i = 0; i < m_Rows; i++) m_ColorRows[i] = GR_GREEN; // lock out any input to this gadget. UIGadget::Disable(); } void UIConsoleGadget::OnDestroy() { if (m_ColorRows) delete[] m_ColorRows; if (m_ConsoleBuffer) mem_free(m_ConsoleBuffer); if (m_PutsBuffer) mem_free(m_PutsBuffer); UIGadget::OnDestroy(); } // functions void UIConsoleGadget::puts(ddgr_color col, const char *str) { int len = strlen(str); ubyte r = GR_COLOR_RED(col), g = GR_COLOR_GREEN(col), b = GR_COLOR_BLUE(col); char *linebuf; if (len >= m_PutsBufLen) { mem_free(m_PutsBuffer); m_PutsBufLen = len + 1; m_PutsBuffer = (char *)mem_malloc(m_PutsBufLen); } textaux_WordWrap(str, m_PutsBuffer, m_W - 2 * m_OffX, m_ConsoleFont); len = strlen(m_PutsBuffer); m_LineColor = col; if (m_CurCol == 0) m_ColorRows[m_CurRow] = m_LineColor; if ((m_LineIndex + 5) >= m_Rowsize) { UIConsoleGadget::PutChar('\n'); // simulate newline to reset line index. // force return character. note that this isn't a newline, but // the above PutChar should've done this anyways. this is redundant code but since this bug didn't // happen often and is hard to reproduce, i'm not sure the aboce PutChar would really work, but the below lines // should definitely prevent a crash though may overwrite some text in the console window. but the // newline should work and not mess up the display. if (m_LineIndex != 0) { // Above PutChar should've done this anyways. useless redundant code. m_CurCol = 0; // doesn't really slow anything down. m_LineIndex = 0; } } // Error("Console line overflow in UIConsoleGadget line index (%d).\n", m_LineIndex); linebuf = m_ConsoleBuffer + (m_Rowsize * m_CurRow); linebuf[m_LineIndex++] = GR_COLOR_CHAR; linebuf[m_LineIndex++] = (r == 0 ? 1 : r); linebuf[m_LineIndex++] = (g == 0 ? 1 : g); linebuf[m_LineIndex++] = (b == 0 ? 1 : b); for (int i = 0; i < len; i++) UIConsoleGadget::PutChar(m_PutsBuffer[i]); } // Inheritable operations void UIConsoleGadget::OnDraw() { int x, y, cy, index; char *linebuf; // draw frame if (m_Flags & UIF_BORDER) { ui_DrawBox(GR_GREEN, 1, 1, m_W - 1, m_H - 1); ui_DrawBox(GR_RGB(64, 255, 64), 3, 3, m_W - 3, m_H - 3); } // draw text ui_SetCharAlpha(255); ui_DrawSetFont(m_ConsoleFont); x = m_OffX; y = m_OffY; index = 0; for (cy = m_VisRowStart; cy < (m_VisRowStart + m_VisRows); cy++) { linebuf = m_ConsoleBuffer + (m_Rowsize * cy); ui_DrawString(m_ColorRows[cy], x, y, linebuf); y = y + ui_GetFontHeight() + 1; } } // OnUserProcess // Takes care of scrolling of text and any keyboard input. void UIConsoleGadget::OnUserProcess() {} // Internal functions void UIConsoleGadget::PutChar(int ch) { char *linebuf; ASSERT(m_CurRow < m_Rows); // ASSERT(m_CurCol < m_Cols); if (ch == '\n') { m_CurCol = 0; m_LineIndex = 0; m_CurRow++; if (m_CurRow < (m_VisRowStart + m_VisRows)) m_ColorRows[m_CurRow] = m_LineColor; } else { linebuf = m_ConsoleBuffer + (m_CurRow * m_Rowsize); linebuf[m_LineIndex] = (char)ch; linebuf[m_LineIndex + 1] = 0; // adjust current character position. m_LineIndex++; m_CurCol++; if (m_LineIndex >= m_Rowsize) { m_LineIndex = 0; m_CurCol = 0; m_CurRow++; if (m_CurRow < (m_VisRowStart + m_VisRows)) m_ColorRows[m_CurRow] = m_LineColor; } } if (m_CurRow >= (m_VisRowStart + m_VisRows)) { // PUT SCROLL CODE HERE UIConsoleGadget::Scroll(); m_ColorRows[m_CurRow] = m_LineColor; } } void UIConsoleGadget::Scroll() { char *linebuf, *linebuf2; int row; // adjust visible row start if visible region is in buffer // other wise scroll all text. if (m_VisRowStart < (m_Rows - m_VisRows)) { m_VisRowStart++; } else { for (row = 1; row < m_Rows; row++) { linebuf = (m_ConsoleBuffer + (m_Rowsize)*row); linebuf2 = (m_ConsoleBuffer + (m_Rowsize) * (row - 1)); memcpy(linebuf2, linebuf, m_Rowsize); memset(linebuf, 0, m_Rowsize); m_ColorRows[row - 1] = m_ColorRows[row]; } m_CurRow--; } } // UIConsole should display a simple console window where anyone can dump text into // int m_ConsoleFont; // standard font for text in console // char *m_ConsoleBuffer; // text buffer of console. UIConsole::UIConsole() {} UIConsole::~UIConsole() {} // font = console font, NOT GADGET FONT. This font is used to proportion window void UIConsole::Create(int x, int y, int font, int cols, int rows) { UIWindow::Create(x, y, 10, 10); UIPrimativeItem item{GR_BLACK}; UIWindow::SetBackItem(&item); m_Console.Create(this, -1, 0, 0, font, cols, rows); m_W = m_Console.W(); m_H = m_Console.H(); } void UIConsole::Destroy() { UIWindow::Destroy(); } // functions void UIConsole::puts(const char *str) { m_Console.puts(GR_GREEN, str); } void UIConsole::puts(ddgr_color col, const char *str) { m_Console.puts(col, str); } // Inheritable operations void UIConsole::OnDraw() { // draw frame UIWindow::OnDraw(); }