Source: src/ex_console.cc
|
|
|
|
//============================================================================
// Author(s) : Fábio Reis Cecin
// Module : console
// Contents : Game Console Class Implementation
// Notes : (none)
// Date : 19.03.2000 (all dates in french notation)
//============================================================================
/*
2 DO:
- reescrever pagedown p/ usar as funcoes "GetLine"
- fazer 2 funcoes auxiliares para "push" de linha no index
(para que pgup/pgdn mantenham o index válido enquanto buscam)
- implementar check de scroll ficando inválido ao
adicionar conteúdo e atropelar o início do conteúdo
apontado pelo scroll (no caso, daí scroll = new_start)
- input fixes:
-// FIXME: fazer uso de um RenderChar() para desenhar o "]" e a "_"
// da linha, aí não precisa desse buf[256] feio aí de baixo e o
// desenho fica mais turbo
-// FIXME: o input não deve ter o "]" se o offset estiver habilitado
// (o prompt deve sumir quando ocorre rolagem do input)
- OTIMIZAÇÃO "FUTURA": não invalidar/redesenhar console inteiro
quando input alterado (nesse caso, fazer um atalho para o render_line
do input, já que o out não é afetado.)
- POSSIVEL OTIMIZAÇÃO: pagedown quando "bate no fim" invalida Index,
mas não precisava (causa um re-scan inútil)
*/
using namespace std;
// External Headers
//
//
#include
#include
#include
#include
#include
#include "ex_console.h"
// tamanho da lista de historico do input do console
#define CONSOLE_HISTORY_LINES 256
//---- CODE SECTION ----------------------------------------------------------
// constructor
console_c::console_c(int outputBufferSizeInKilobytes, int consoleDisplayColumns, int consoleDisplayRows)
{
// salva largura/altura visíveis do console
conDisplay = true;
conCols = consoleDisplayColumns;
conRows = consoleDisplayRows;
//codigo comum dos constructors
outSize = outputBufferSizeInKilobytes * 1024;
defaults();
}
// constructor
console_c::console_c(int outputBufferSizeInKilobytes)
{
// sem largura/altura visíveis do console
conDisplay = false;
conCols = 10; //apenas alguns defauls pra prevenir...
conRows = 10;
//codigo comum dos constructors
outSize = outputBufferSizeInKilobytes * 1024;
defaults();
}
// set defaults (usado pelos ctors)
void console_c::defaults() {
// developer mode desligado (mensagens Dprintf são ignoradas por default)
conDeveloperMode = false;
// console redraw inicialmente ligado
conInputRedrawFlag = true;
conOutputRedrawFlag = true;
// aloca área de memória para o output do console
outBuffer = new char[outSize];
// inicializações arcanas, não mexa!
outStart = 0;
outEnd = -1;
outCount = 0;
// outRows: conRows - 1 (do input)
outRows = conRows - 1;
// scroll inicialmente desativado
outScrolled = false;
// inicializa index
outIndexValid = false; // line index inválido
outLineIndex = new tagLineIndexRecord[outRows];
// aloca área para o input
inSize = 1023; // area USÁVEL (alocado + 1 p/ eventual \0 quando usa todos os chars)
inBuffer = new char[inSize + 1];
inCount = 0; // nº caracteres válidos dentro do input (0=vazio)
// aloca espaco e inicializa history
hisSize = hisSpaceLeft = CONSOLE_HISTORY_LINES;
hisList = new char*[hisSize];
hisFirst = 0;
hisLast = -1;
hisCurrent = -1; // -1 = inicio da history, que e' a "linha vazia"
}
// Caractere (char) enviado para o console
bool console_c::write_string(const char* outstr)
{
int len = strlen(outstr); // len = comprimento do bloco a ser inserido
if (len < 1) return false; // se não há nada: return
if (len >= outSize) // caso raro (só pra não deixar nada sem tratamento):
{ // tamanho maior ou igual ao próprio console. o console fica cheio com a parte final de outstr
outEnd = outCount = outSize;
outEnd--;
outStart = 0;
memcpy(outBuffer, outstr + len - outSize, outSize);
outScrolled = false; // conScroll = -1;
outIndexValid = false; // avacalha com o desenho, pois troca tudo
return true;
}
int new_outEnd = (outEnd + len) % outSize; // new_outEnd - onde o end vai parar
int new_outCount = outCount + len; // new_outCount - novo nº de caracteres
// ops: tem mais caracteres do que cabe no buffer = atropelou start, então conserta o count (start = f(count,end))
// rola o start pra frente do novo End, até achar um início de linha válido (um após um \n == 10)
// FIX: continua tentando (while) até conseguir, se a 1a linha não resolver
while (new_outCount > outSize)
{
int start = new_outEnd;
new_outCount = outSize;
do
{
new_outCount--; // esse é o quente
start++;
if (start >= outSize) start = 0; // wrap around
}
while (((char)*(outBuffer + start) != '\n'));
}
// índices OK, realiza a cópia
//
// size1 = tamanho da 1a metade, é igual ao resto até o fim do buffer ou
// o tamanho de outstr, o que for menor, pode ser zero se
// outEnd for a última posição (outSize-1)
//
// size2 = tamanho da 2a metade, >0 somente se size1 é menor que o
// tamanho de outstr
int size1, size2;
size1 = outSize - outEnd - 1; // tamanho até o final
if (size1 > len) // não copia mais do que tem
size1 = len;
size2 = len - size1; // pega a sobra
if (size1 > 0) memcpy(outBuffer + outEnd + 1, outstr, size1);
if (size2 > 0) memcpy(outBuffer, outstr + size1, size2);
// guarda novos valores
outCount = new_outCount;
outEnd = new_outEnd;
// recalcula o start
int new_outStart = outEnd - outCount + 1;
if (new_outStart < 0) new_outStart += outSize;
// checa para ver se a mudança do START não avacalha
// com o SCROLL atual
// se SIM, scroll = novo start
//
// FIXME, do it! tem new_outStart, outStart e conScroll.
// agora FAZ!
//
// guarda novos valores
outStart = new_outStart;
// invalida o Index, se o scroll estiver grudado no fim
// (senão, continua valido pq não mexeu na tela)
if (!outScrolled) outIndexValid = false;
// ok
return true;
}
// Input de string (char*)
void console_c::read_string(char* instr, bool isScript)
{
// simplesmente digita cada caracter no input, como se fosse a pessoa digitando
char* scan = instr;
while ((char)*scan != '\0') read_char((char)*scan++, isScript);
}
// Input de caractere (char)
void console_c::read_char(char inchar, bool isScript)
{
// sinalizar redraw da linha de input necessário
conInputRedrawFlag = true;
switch (inchar)
{
case 8: // backspace
if (inCount > 0) inCount--;
break;
case '\t': {
break; //Add command completition here
}
case '\n': // new line (10)
case '\r': // enter/return (13)
// envia echo do comando para o console (com \n\0 no final)
//if (NoScriptRunning())
if (!isScript)
{
inBuffer[inCount] = '\n';
inBuffer[inCount+1] = '\0';
printf("]%s", inBuffer);
}
// interpreta comando
inBuffer[inCount] = '\0'; // tira o \n
interprete_command(inBuffer); // interpreta comando
// adiciona a string ao history, se foi pedido pra fazer isso..
//if ((NoScriptRunning()) && (logHistory))
if (!isScript)
history_add(inBuffer);
// continua executando p/ reset input:
case 27: // ESC (limpa input)
inCount = 0;
break;
default: // caractere normal
if (inCount < inSize)
inBuffer[inCount++] = inchar;
//else
// FIXME: beep, aumentar área de armazenamento, etc. ou "do nothing" mesmo
break;
}
}
// Renderiza uma linha na tela
void console_c::render_line(char* buffer, int firstCharOffset, int lineNumber, int charCount)
{
char drawLine[512];
int size1, size2;
size1 = outSize - firstCharOffset;
if (size1 > charCount)
size1 = charCount;
size2 = charCount - size1;
if (size1 > 0) memcpy(drawLine, buffer + firstCharOffset, size1);
if (size2 > 0) memcpy(drawLine + size1, buffer, size2);
drawLine[charCount] = '\0';
//call line-draw implementation of subclass
draw_line(lineNumber, (char*)drawLine);
}
// busca a próxima linha no buffer
// parâmetros:
// firstCharOffset: primeiro caractere da linha atual
// maxWidth: se -1: ignorar largura do console, senão, a funcao para quando a linha completar maxWidth colunas
// retorno:
// r.charPos = se (r.resultCode) charPos = posição do 1o caractere (início) da próxima linha encontrada
// r.charCount = numero de caracteres da linha ATUAL (não da próxima)
// r.resultCode = 0:falha (fim buffer) 1:ok, parou por \n 2: ok, parou por width
console_c::tagGetResult console_c::get_next_line(int firstCharOffset, int maxWidth)
{
int charPos = firstCharOffset; // caractere onde inicia a busca
int resultCode = 0; // condição de parada da busca (0=fim buffer 1="\n" 2=width)
int charCount = 0; // ordem do caractere atual na linha atual
bool notFound = true; // ainda não achou (permanece no while)
do
{
// pega o char da posição
char ch = (char)*(outBuffer + charPos);
// contador de caracteres válidos
if (ch != '\n') charCount++;
// se for o último do buffer o atual, (==end), então não
// há proxima linha, pq este pode ser:
// \n: fim DESTA linha
// char de pos=maxwidth: ultimo caractere DESTA linha desenhável
if (charPos == outEnd)
{
resultCode = 0;
notFound = false;
}
else // o atual não é o último, ou seja, há próximo depois dele
// para poder ser uma nextline, eventualmente
{
// verifica casos de parada (1=\n ou 2=width)
if (ch == '\n')
resultCode = 1;
else
{
if (charCount == maxWidth)
resultCode = 2;
}
// próximo é início de próxima linha (o charPos++ abaixo é proposital)
if (resultCode) notFound = false;
}
// procura a próxima posição (se vai parar o loop, este charPos++ final faz
// o papel de avançar para o primeiro caractere da próxima linha, pois
// charPos agora aponta para o último da linha anterior
charPos++;
if (charPos >= outSize) charPos -= outSize;
}
while (notFound);
// retorna resultados
tagGetResult ret;
ret.charOfs = charPos;
ret.charCount = charCount; // VALIDOS (printáveis fora \n que é um separador)
ret.resultCode = resultCode;
return ret;
}
// busca a linha anterior no buffer (este só para em "\n"s e fim do buffer!)
// parâmetros:
// firstCharOffset: caractere onde inicia a busca
// alreadyAtEnd: TRUE se firstCharOffset já aponta para o último caractere
// da linha "anterior" em questão. FALSE se ainda aponta para o início da
// linha seguinte
// retorno:
// r.charPos = se (r.resultCode) charPos = posição do 1o caractere (início) da linha anterior encontrada
// r.charCount = numero de caracteres da linha ANTERIOR ENCONTRADA
// r.resultCode = 0:falha (não há linha anterior) 1:ok (achou)
console_c::tagGetResult console_c::get_previous_line(int firstCharOffset, bool alreadyAtEnd)
{
int charPos = firstCharOffset; // caractere onde inicia a busca
int resultCode = 0; // condição de parada da busca (0=fim buffer 1="\n" 2=width)
int charCount = 0; // ordem do caractere atual na linha atual
bool notFound = true; // ainda não achou (permanece no while)
int nlCount = 0; // remendo, para detectar linhas nulas (sequencia de \n\n\n\...)
tagGetResult ret; // para retorno
// está no início de uma linha válida
// busca um atrás. \n ou char, pertence à linha anterior
if (!alreadyAtEnd)
{
// charPos == outStart. não tem o que buscar, mané.
if (charPos == outStart)
{
ret.resultCode = 0;
return ret;
}
// \n ou char, desde que exista, é o fim da outra linha
charPos--;
if (charPos < 0) charPos += outSize;
}
do
{
// pega o char da posição
char ch = (char)*(outBuffer + charPos);
// contador de caracteres válidos
if (ch != '\n') charCount++;
// se for o último do buffer o atual, (==start)
// PODE HAVER PRÓXIMA LINHA se == '\n' = é linha nula anterior
// caso contrário, NÂO HÁ
if (((ch == '\n') || (charPos == outStart)) && (nlCount || charCount)) // primeiro é ignorado (tinha que estar lá)
{
// fim da linha - corrige charPos
if (ch == '\n')
{
charPos++;
if (charPos >= outSize) charPos -= outSize;
}
resultCode = 1;
notFound = false;
}
else
{
// procura a próxima posição
charPos--;
if (charPos < 0) charPos += outSize;
}
// para detecção de \n\n\n\ consecutivos
if (ch == '\n') nlCount++;
}
while (notFound);
// retorna resultados
ret.charOfs = charPos;
ret.charCount = charCount; // VALIDOS (printáveis fora \n que é um separador)
ret.resultCode = resultCode;
return ret;
}
// Realiza varredura da tela atual visível (out), atualizando outLineIndex
void console_c::update_output_line_index()
{
// se está válido, retorna (não precisa fazer nada)
if (outIndexValid) return;
// será necessário redesenhar o output, já que está sendo
// necessário alterar o índex
conOutputRedrawFlag = true;
// caso buffer não preencha a tela, o index fica com linhas default nulas
for (int i = 0; i < outRows; i++)
{
outLineIndex[i].count = 0;
outLineIndex[i].start = -1;
}
// casos.. "especiais".. :-)
if (outCount < 2) {
conOutputRedrawFlag = false;
return; // 0 ou 1 caracteres: não escreve nada no console.
}
//
// Atualiza o Index
// CASO 1: scroll fixo no fim. faz busca de trás-pra-frente
//
if (!outScrolled)
{
bool notAtEndAnymore = false;
int lineCount = outRows - 1; // proxima linha livre a ser desenhada
int charPos = outEnd;
tagGetResult res;
while (lineCount >= 0)
{
bool alreadyAtEnd;
if ((charPos == outEnd) && (!notAtEndAnymore))
{
alreadyAtEnd = true;
notAtEndAnymore = true;
}
else
alreadyAtEnd = false;
// procura-se a próxima, obtendo o count da atual
res = get_previous_line(charPos, alreadyAtEnd);
// se achou linha anterior, processa
if (res.resultCode)
{
int linespan = 0; // contador de multilinhas (0=linha única)
int totalcount = res.charCount; // total de caracteres na biglinha
// calcula linespan, deixando o "resto de caracteres da última linha" no totalcount
while (totalcount > conCols)
{
totalcount -= conCols;
linespan++;
}
// startofs - contador/indicador de ofs.inicial da linha
int startofs = res.charOfs + res.charCount - totalcount;
if (startofs < 0) startofs += outSize; // sei lá onde vai parar isso... limita dos dois lados
if (startofs >= outSize) startofs -= outSize;
// preenche a "última"
outLineIndex[lineCount].start = startofs;
outLineIndex[lineCount].count = totalcount;
// preenche as outras, se existirem
while ((linespan) && (lineCount > 0))
{
linespan--; // menos uma
lineCount--; // menos uma
startofs -= conCols; // calcula start da linha
if (startofs < 0) startofs += outSize;
// desenha linha (existe pq linecount > 0 e com o -- fica no mínimo 0)
outLineIndex[lineCount].start = startofs;
outLineIndex[lineCount].count = conCols;
}
// próxima linha a ser desenhada na tela
charPos = startofs;
lineCount--;
}
else // não tem mais próxima linha
break;
}
int i; //fixed by Juraj Michalek
// atualiza PageStart - é o primeiro start válido do índex
// FIXME: e se não tem nenhum?? (out vazio)
//outPageStart = charPos;
for (i = 0; i < outRows; i++)
if (outLineIndex[i].start != -1)
{
outPageStart = outLineIndex[i].start;
break;
}
}
//
// Atualiza o Index
// CASO 2: console scrolled up
//
else
{
tagGetResult res;
int lineCount = 0; // próxima linha livre a ser desenhada na tela
int charPos = outPageStart; // caractere inicial de busca
while (lineCount < outRows) // 0..outRows - 1
{
// grava no Index parte da linha atual que se sabe
outLineIndex[lineCount].start = charPos;
// procura-se a próxima, obtendo o count da atual
res = get_next_line(charPos, conCols);
// grava no Index parte da linha atual que se descobriu agora
outLineIndex[lineCount].count = res.charCount;
// próxima
charPos = res.charOfs;
lineCount++;
}
// atualiza indices "Page"
outPageEnd = outLineIndex[outRows-1].start + outLineIndex[outRows-1].count;
}
// valida
outIndexValid = true;
}
// Redesenha o console inteiro
void console_c::draw_page(bool force)
{
// verifica se possui display
if (!conDisplay)
return;
// chama a varredura de página
update_output_line_index();
// desenha output
// se não é necessário, não mexe
if ((conOutputRedrawFlag) || (force))
{
// limpeza da área de desenho
clear();
// renderiza as linhas já indexadas
for (int j = 0; j < outRows; j++)
render_line(outBuffer, outLineIndex[j].start, j, outLineIndex[j].count);
// desenhado ok
conOutputRedrawFlag = false;
}
// desenha a linha de input, a última do console (conRows-1)
// se não é necessário, não mexe
// FIXME: fazer uso de um RenderChar() para
// desenhar o "]" e a "_" da linha, aí não
// precisa desse buf[256] feio aí de baixo
// e o desenho fica mais turbo
// FIXME: o input não deve ter o "]" se o offset estiver habilitado
// (o prompt deve sumir quando ocorre rolagem do input)
if ((conInputRedrawFlag) || (force))
{
char buf[256];
int offset, count;
offset = inCount - conCols + 2; // +2 por causa do ] e do _
if (offset < 0) offset = 0;
count = inCount;
if (count > conCols - 2) count = conCols - 2; // -2 por causa do ] e do _
buf[0] = '#';
memcpy(buf + 1, inBuffer + offset, count);
buf[count+1] = '_';
// limpeza da área de desenho
clear_prompt();
// 0 porque o "buf" já tem a linha pronta, copia do começo (FIXME acima muda isso)
// conRows-1 porque é a localização fixa da linha de input na tela
// +2 por causa do ] e do _
render_line(buf, 0, conRows - 1, count + 2);
// desenhado ok
conInputRedrawFlag = false;
}
}
// Scroll up
void console_c::scroll_page_up()
{
// scroll já no topo
if (outPageStart == outStart) return; //if (conScroll == outStart) return;
// invalida o display (independente de chamar o reindexador)
conOutputRedrawFlag = true;
int lineCount = 0; // contador de linhas "subidas"
int charPos = outPageStart; // 1o caractere atual
if (!outScrolled) // se scroll no fim, então tem que começar do último
{
charPos = outEnd;
lineCount -= outRows; // remendo: 1o pageup tem que subir 2 páginas, pois começa o scan da mais de baixo.
}
int new_outPageStart = -1;
bool notAtEndAnymore = false;
do
{
tagGetResult res;
bool alreadyAtEnd;
if ((charPos == outEnd) && (!notAtEndAnymore))
{
alreadyAtEnd = true;
notAtEndAnymore = true;
}
else
alreadyAtEnd = false;
// busca o início da anterior
res = get_previous_line(charPos, alreadyAtEnd); //(charPos == outEnd)//((!outScrolled) &&
// vê se não acabou
if (res.resultCode)
{
int linespan = 0; // contador de multilinhas (0=linha única)
int totalcount = res.charCount; // total de caracteres na biglinha
// calcula linespan, deixando o "resto de caracteres da última linha" no totalcount
while (totalcount > conCols)
{
totalcount -= conCols;
linespan++;
}
// startofs - contador/indicador de ofs.inicial da linha
int startofs = res.charOfs + res.charCount - totalcount;
if (startofs < 0) startofs += outSize; // sei lá onde vai parar isso... limita dos dois lados
if (startofs >= outSize) startofs -= outSize;
// preenche a "última"
// push line
for (int i = outRows-1; i > 0; i--)
{
outLineIndex[i].start = outLineIndex[i-1].start;
outLineIndex[i].count = outLineIndex[i-1].count;
}
outLineIndex[0].start = startofs;
outLineIndex[0].count = totalcount;
// preenche as outras, se existirem
while ((linespan) && (lineCount < outRows)) // FIXME
{
linespan--; // menos uma
lineCount++; // menos uma
startofs -= conCols; // calcula start da linha
if (startofs < 0) startofs += outSize;
// push line
for (int i = outRows-1; i > 0; i--)
{
outLineIndex[i].start = outLineIndex[i-1].start;
outLineIndex[i].count = outLineIndex[i-1].count;
}
outLineIndex[0].start = startofs;
outLineIndex[0].count = conCols;
}
// próxima linha a ser desenhada na tela
charPos = startofs;
lineCount++;
// condição de parada
if (lineCount >= outRows) new_outPageStart = charPos;
}
else
{
// não tem anterior, esta é a última, e é o start
new_outPageStart = charPos;
}
charPos = res.charOfs; // próxima posição
}
while (new_outPageStart == -1);
outScrolled = true; // scrollUp ativado
outIndexValid = true; // pageup já atualiza as linhas encontradas
outPageStart = new_outPageStart; // salva os novos PageStart,PageEnd encontrados
outPageEnd = outLineIndex[outRows-1].start + outLineIndex[outRows-1].count;
}
// Scroll down
// FIXME: reescrever função para usar a funcao auxiliar get_next_line()
void console_c::scroll_page_down()
{
// scroll já no fim
if (!outScrolled) return; //if (conScroll == -1) return;
// invalida o display (independente de chamar o reindexador)
conOutputRedrawFlag = true;
// primeiro: Index tem que estar válido para a página atual
// chama a varredura de página
update_output_line_index();
// segundo vai avançando linhas, até
// I- acabar o console (scroll=false, mas ainda valido, start e end inferíveis)
// II- preencher as linhas necessárias
int lineCount = 0;
int colCount = 0;
// FIXME: fazer mais amiguinho
int charPos = outPageEnd + 1;
if (charPos >= outSize)
charPos -= outSize;
if ((char)*(outBuffer + charPos) == '\n') charPos++;
// FIXME: REMENDO DE BUG
int firstLineInARow = 1;
while (lineCount < outRows)
{
char ch = (char)*(outBuffer + charPos);
// INICIO
if (ch != '\n') colCount++;
if ((ch == '\n') || (colCount == conCols))
{
// chpos é o charPos só que voltando ao início da linha e wrap-aware
int chpos = charPos - colCount;
// FIXME: REMENDO DE BUG -- INICIO --
if (ch == '\n') firstLineInARow = 1;
if ((firstLineInARow) && (colCount == conCols))
{
firstLineInARow = 0;
chpos++;
}
// FIXME: REMENDO DE BUG -- FIM --
if (chpos < 0) chpos += outSize;
//render_line(outBuffer, chpos, lineCount, colCount);
// GRAVA no Index
// neste caso, primeiro faz um "shift" e grava no último
for (int l = 0; l < outRows-1; l++)
{
outLineIndex[l].start = outLineIndex[l+1].start;
outLineIndex[l].count = outLineIndex[l+1].count;
}
outLineIndex[outRows-1].start = chpos;
outLineIndex[outRows-1].count = colCount;
colCount = 0; // reseta
lineCount++; // avança
}
charPos++; // próximo...
if (charPos >= outSize) charPos = 0; // ...wrapando
// FIM PASTE
if (charPos == outEnd) // escaneando perto do fim, não interessa: bang!
// OTIMIZAÇÃO: não precisava, vai causar 1 scan inútil;
// (devia continuar válido)
{
outScrolled = false;
outIndexValid = false;
outPageEnd = outEnd;
return;
}
}
// linecount atingido aqui
// como Index=valid...:
outPageStart = outLineIndex[0].start;
outPageEnd = outLineIndex[outRows-1].start + outLineIndex[outRows-1].count;
}
// scroll page down até o fim
void console_c::scroll_all_down()
{
outScrolled = false;
outIndexValid = false;
outPageEnd = outEnd;
}
// altera o numero de linhas visiveis em uma pagina do console
void console_c::set_con_rows(int newConsoleDisplayRows)
{
conRows = newConsoleDisplayRows;
// novo outRows: re-inicializa index
outRows = conRows - 1;
delete [] outLineIndex;
outIndexValid = false; // line index inválido
outLineIndex = new tagLineIndexRecord[outRows];
// scroll no fim
outScrolled = false;
outIndexValid = false;
outPageEnd = outEnd;
conOutputRedrawFlag = true;
}
// altera o numero de colunas visiveis em uma pagina do console
void console_c::set_con_cols(int newConsoleDisplayColumns)
{
conCols = newConsoleDisplayColumns;
// scroll no fim
outScrolled = false;
outIndexValid = false;
outPageEnd = outEnd;
conInputRedrawFlag = true;
conOutputRedrawFlag = true;
}
// faz com que o console passe a se desenhar (novamente?)
void console_c::enable_display(int cols, int rows) {
conDisplay = true;
set_con_cols(cols);
set_con_rows(rows);
}
// desliga rotinas de desenho do console
void console_c::disable_display() {
conDisplay = false;
}
// Destructor do console (libera buffers)
console_c::~console_c()
{
delete[] outBuffer;
delete[] outLineIndex;
delete[] inBuffer;
}
string parse_text(string s) //expansion of text characters
{
int i;
while((i=(int)s.find("\t")) != -1) {
s.replace(i,1," ");
}
return s;
}
void console_c::printf(char* formatstr, ...)
{
va_list argptr;
static char msg[CONSOLE_PRINTF_MAXPRINTMSGSIZE];
string text;
va_start (argptr, formatstr);
vsprintf (msg, formatstr, argptr);
va_end (argptr);
text = msg;
text = parse_text(text);
write_string(text.c_str());
}
void console_c::dprintf(char* formatstr, ...)
{
va_list argptr;
static char msg[CONSOLE_PRINTF_MAXPRINTMSGSIZE];
if (!conDeveloperMode) return; // ignore
va_start (argptr, formatstr);
vsprintf (msg, formatstr, argptr);
va_end (argptr);
printf("%s", msg);
}
// adiciona um comando 'a history list
void console_c::history_add(char* inputstr)
{
// hisFirst: PRIMEIRO a ser colocado (mais velho)
// hisLast: ++ quando adiciona 1 string!
//
hisLast++; // avanca last
if (hisSpaceLeft > 0)
hisSpaceLeft--; // menos um espaco livre
else
{
if (hisLast == hisSize) hisLast -= hisSize; // wrapa last
delete hisList[hisLast]; // deleta o que estiver no last (atropela)
hisFirst++; // avanca first c/ wrap
if (hisFirst == hisSize) hisFirst -= hisSize;
}
// adiciona na history
hisList[hisLast] = strdup(inputstr);
// reseta hisCurrent (volta pro inicio)
hisCurrent = -1;
}
// coloca a "proxima" linha de history na entrada
void console_c::history_back()
{
// se nao ha' strings, nao faz nada
if (hisSpaceLeft == hisSize) return; // ou: if (hisLast == -1)
// se esta' na primeira string (a mais velha), nao faz nada
if (hisCurrent == hisFirst) return;
// se esta' no comeco, vai para a ultima string digitada (last), senao volta um.
if (hisCurrent == -1)
hisCurrent = hisLast;
else
{
hisCurrent--;
if (hisCurrent < 0) hisCurrent += hisSize;
}
// coloca a string no inputbuffer
strcpy(inBuffer, hisList[hisCurrent]);
inCount = strlen(hisList[hisCurrent]);
conInputRedrawFlag = true;
}
// coloca a linha "anterior" de history na entrada
// OBS: a linha "anterior" a "ultima" (mais recente) eh a linha vazia
void console_c::history_forward()
{
// se nao ha' strings, nao faz nada
if (hisSpaceLeft == hisSize) return; // ou: if (hisLast == -1)
// se esta' mostrando a string vazia, nao faz nada
if (hisCurrent == -1) return;
// se ja' esta' mostrando a mais recente, agora mostrara' a string vazia,
if (hisCurrent == hisLast)
{
hisCurrent = -1;
inCount = 0;
}
// senao vai 1 pra frente e mostra essa
else
{
hisCurrent++; // avanca com wrap
if (hisCurrent == hisSize) hisCurrent -= hisSize;
// coloca a string no inputbuffer
strcpy(inBuffer, hisList[hisCurrent]);
inCount = strlen(hisList[hisCurrent]);
}
conInputRedrawFlag = true;
}
// ha' algum script sendo executado? (bloqueia input do usuario)
bool console_c::no_script_running()
{
return true; //FIXME
}
Generated by: georgik on armada on Sat Jul 24 07:07:15 2004, using kdoc 2.0a54. |