mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-27 07:54:51 +01:00
553 lines
17 KiB
C++
553 lines
17 KiB
C++
|
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||
|
|
||
|
#include "StdAfx.h"
|
||
|
#include "LCDDrawing.h"
|
||
|
|
||
|
extern CGame *_pGame;
|
||
|
|
||
|
// console variables
|
||
|
static const FLOAT tmConsoleFade = 0.0f; // how many seconds it takes console to fade in/out
|
||
|
static FLOAT fConsoleFadeValue = 0.0f; // faded value of console (0..1)
|
||
|
static CTimerValue tvConsoleLast;
|
||
|
|
||
|
static CTString strConsole;
|
||
|
static CTString strInputHistory = "\n";
|
||
|
static CTString strEditingLine;
|
||
|
static CTString strExpandStart;
|
||
|
static CTString strLastExpanded;
|
||
|
static CTString strCurrentLine;
|
||
|
static BOOL bLastExpandedFound;
|
||
|
static INDEX iSymbolOffset;
|
||
|
static INDEX iHistoryLine=0;
|
||
|
static INDEX iCursorPos=0;
|
||
|
static INDEX ctConsoleLinesOnScreen;
|
||
|
|
||
|
static INDEX con_iFirstLine = 1;
|
||
|
extern FLOAT con_fHeightFactor;
|
||
|
extern FLOAT con_tmLastLines;
|
||
|
|
||
|
// find a line with given number in a multi-line string counting from end of string
|
||
|
BOOL GetLineCountBackward(const char *pchrStringStart, const char *pchrStringEnd,
|
||
|
INDEX iBackwardLine, CTString &strResult)
|
||
|
{
|
||
|
// start at the end of string
|
||
|
const char *pchrCurrent = pchrStringEnd;
|
||
|
INDEX ctLinesDone=0;
|
||
|
|
||
|
// while line of given number is not found
|
||
|
while(ctLinesDone!=iBackwardLine) {
|
||
|
// go one character back
|
||
|
pchrCurrent--;
|
||
|
// if got before start of string
|
||
|
if (pchrCurrent < pchrStringStart) {
|
||
|
// line is not found
|
||
|
return FALSE;
|
||
|
}
|
||
|
// if at line break
|
||
|
if(*pchrCurrent == '\n') {
|
||
|
// count lines
|
||
|
ctLinesDone++;
|
||
|
}
|
||
|
}
|
||
|
// check that pointer is not outside range
|
||
|
ASSERT(pchrCurrent>=pchrStringStart && pchrCurrent<pchrStringEnd);
|
||
|
|
||
|
// if exactly on line break, skip it
|
||
|
if (*pchrCurrent=='\n') {
|
||
|
pchrCurrent++;
|
||
|
}
|
||
|
|
||
|
// find end of that line
|
||
|
const char *pchrLineEnd=strchr(pchrCurrent, '\r');
|
||
|
if (pchrLineEnd==NULL) {
|
||
|
pchrLineEnd = pchrStringEnd;
|
||
|
}
|
||
|
|
||
|
// copy the found line
|
||
|
char achrLine[ 1024];
|
||
|
strncpy( achrLine, pchrCurrent, pchrLineEnd-pchrCurrent);
|
||
|
achrLine[ pchrLineEnd-pchrCurrent]=0;
|
||
|
strResult = achrLine;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CGame::ConsoleRender(CDrawPort *pdp)
|
||
|
{
|
||
|
if( _pGame->gm_csConsoleState==CS_OFF) {
|
||
|
con_iFirstLine = 1;
|
||
|
tvConsoleLast = _pTimer->GetHighPrecisionTimer();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// get console height
|
||
|
con_fHeightFactor = Clamp( con_fHeightFactor, 0.1f, 1.0f);
|
||
|
FLOAT fHeightFactor = con_fHeightFactor;
|
||
|
if( !gm_bGameOn) fHeightFactor = 0.9f;
|
||
|
|
||
|
// calculate up-down speed to be independent of refresh speed
|
||
|
CTimerValue tvNow = _pTimer->GetHighPrecisionTimer();
|
||
|
CTimerValue tvDelta = tvNow - tvConsoleLast;
|
||
|
tvConsoleLast = tvNow;
|
||
|
FLOAT fFadeSpeed = (FLOAT)(tvDelta.GetSeconds() / tmConsoleFade);
|
||
|
|
||
|
// if console is dropping down
|
||
|
if( _pGame->gm_csConsoleState==CS_TURNINGON) {
|
||
|
// move it down
|
||
|
fConsoleFadeValue += fFadeSpeed;
|
||
|
// if finished moving
|
||
|
if( fConsoleFadeValue>1.0f) {
|
||
|
// stop
|
||
|
fConsoleFadeValue = 1.0f;
|
||
|
_pGame->gm_csConsoleState = CS_ON;
|
||
|
}
|
||
|
}
|
||
|
// if console is pulling up
|
||
|
if( _pGame->gm_csConsoleState==CS_TURNINGOFF) {
|
||
|
// move it up
|
||
|
fConsoleFadeValue -= fFadeSpeed;
|
||
|
// if finished moving
|
||
|
if( fConsoleFadeValue<0.0f) {
|
||
|
// stop
|
||
|
fConsoleFadeValue = 0.0f;
|
||
|
_pGame->gm_csConsoleState = CS_OFF;
|
||
|
// if not in network
|
||
|
if (!_pNetwork->IsNetworkEnabled()) {
|
||
|
// don't show last lines on screen after exiting console
|
||
|
CON_DiscardLastLineTimes();
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (_pGame->gm_csConsoleState==CS_TALK) {
|
||
|
fHeightFactor = 0.1f;
|
||
|
fConsoleFadeValue = 1.0f;
|
||
|
}
|
||
|
|
||
|
// calculate size of console box so that it covers upper half of the screen
|
||
|
FLOAT fHeight = ClampUp( fHeightFactor*fConsoleFadeValue*2, fHeightFactor);
|
||
|
CDrawPort dpConsole( pdp, 0.0f, 0.0f, 1.0f, fHeight);
|
||
|
// lock drawport
|
||
|
if( !dpConsole.Lock()) return;
|
||
|
|
||
|
LCDPrepare(fConsoleFadeValue);
|
||
|
LCDSetDrawport(&dpConsole);
|
||
|
dpConsole.Fill(LCDFadedColor(C_BLACK|225));
|
||
|
|
||
|
PIX pixSizeI = dpConsole.GetWidth();
|
||
|
PIX pixSizeJ = dpConsole.GetHeight();
|
||
|
COLOR colLight = LCDFadedColor(C_WHITE|255);
|
||
|
COLOR colDark = LCDFadedColor(SE_COL_BLUE_LIGHT|255);
|
||
|
INDEX iBackwardLine = con_iFirstLine;
|
||
|
if( iBackwardLine>1) Swap( colLight, colDark);
|
||
|
PIX pixLineSpacing = _pfdConsoleFont->fd_pixCharHeight + _pfdConsoleFont->fd_pixLineSpacing;
|
||
|
|
||
|
LCDRenderCloudsForComp();
|
||
|
//LCDRenderGrid();
|
||
|
LCDRenderClouds2();
|
||
|
dpConsole.DrawLine( 0, pixSizeJ-1, pixSizeI, pixSizeJ-1, LCDFadedColor(SE_COL_BLUE_NEUTRAL|255));
|
||
|
const COLOR colFill = (colDark & ~CT_AMASK) | 0x2F;
|
||
|
dpConsole.Fill( 0, pixSizeJ-pixLineSpacing*1.6f, pixSizeI, pixLineSpacing*1.6f, colFill);
|
||
|
|
||
|
// setup font
|
||
|
PIX pixTextX = (PIX)(dpConsole.GetWidth()*0.01f);
|
||
|
PIX pixYLine = dpConsole.GetHeight()-14;
|
||
|
dpConsole.SetFont( _pfdConsoleFont);
|
||
|
|
||
|
// print editing line of text
|
||
|
dpConsole.SetTextMode(-1);
|
||
|
CTString strPrompt;
|
||
|
if (_pGame->gm_csConsoleState == CS_TALK) {
|
||
|
strPrompt = TRANS("say: ");
|
||
|
} else {
|
||
|
strPrompt = "=> ";
|
||
|
}
|
||
|
CTString strLineOnScreen = strPrompt + strEditingLine;
|
||
|
dpConsole.PutText( strLineOnScreen, pixTextX, pixYLine, colLight);
|
||
|
dpConsole.SetTextMode(+1);
|
||
|
|
||
|
// add blinking cursor
|
||
|
if( ((ULONG)(_pTimer->GetRealTimeTick()*2)) & 1) {
|
||
|
CTString strCursor="_";
|
||
|
FLOAT fTextScalingX = dpConsole.dp_fTextScaling * dpConsole.dp_fTextAspect;
|
||
|
PIX pixCellSize = _pfdConsoleFont->fd_pixCharWidth * fTextScalingX + dpConsole.dp_pixTextCharSpacing;
|
||
|
PIX pixCursorX = pixTextX + (iCursorPos+strlen(strPrompt))*pixCellSize;
|
||
|
dpConsole.PutText( strCursor, pixCursorX, pixYLine+2, colDark);
|
||
|
}
|
||
|
|
||
|
// render previous outputs
|
||
|
con_iFirstLine = ClampDn( con_iFirstLine, 1L);
|
||
|
pixYLine -= (PIX)(pixLineSpacing * 1.333f);
|
||
|
ctConsoleLinesOnScreen = pixYLine/pixLineSpacing;
|
||
|
while( pixYLine >= 0) {
|
||
|
CTString strLineOnScreen = CON_GetLastLine(iBackwardLine);
|
||
|
dpConsole.PutText( strLineOnScreen, pixTextX, pixYLine, colDark);
|
||
|
iBackwardLine++;
|
||
|
pixYLine -= pixLineSpacing;
|
||
|
}
|
||
|
|
||
|
// all done
|
||
|
dpConsole.Unlock();
|
||
|
}
|
||
|
|
||
|
|
||
|
// print last few lines from console to top of screen
|
||
|
void CGame::ConsolePrintLastLines(CDrawPort *pdp)
|
||
|
{
|
||
|
// get number of lines to print
|
||
|
con_tmLastLines = Clamp( con_tmLastLines, 1.0f, 10.0f);
|
||
|
INDEX ctLines = CON_NumberOfLinesAfter( _pTimer->GetRealTimeTick() - con_tmLastLines);
|
||
|
// if no lines left to print, just skip it
|
||
|
if( ctLines==0) return;
|
||
|
|
||
|
// setup font
|
||
|
_pfdConsoleFont->SetFixedWidth();
|
||
|
pdp->SetFont( _pfdConsoleFont);
|
||
|
PIX pixCharHeight = _pfdConsoleFont->GetHeight() -1;
|
||
|
// put some filter underneath for easier reading
|
||
|
pdp->Fill( 0, 0, pdp->GetWidth(), pixCharHeight*ctLines, C_BLACK|128);
|
||
|
// for each line
|
||
|
for( INDEX iLine=0; iLine<ctLines; iLine++) {
|
||
|
CTString strLine = CON_GetLastLine(iLine+1);
|
||
|
pdp->PutText( strLine, 0, pixCharHeight*(ctLines-iLine-1), SE_COL_BLUE_LIGHT|255);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Key_Backspace( BOOL bShift, BOOL bRight)
|
||
|
{
|
||
|
// do nothing if string is empty
|
||
|
INDEX ctChars = strlen(strEditingLine);
|
||
|
if( ctChars==0) return;
|
||
|
|
||
|
if( bRight && iCursorPos<ctChars) { // DELETE key
|
||
|
if( bShift) { // delete to end of line
|
||
|
strEditingLine.TrimRight(iCursorPos);
|
||
|
} else { // delete only one char
|
||
|
strEditingLine.DeleteChar(iCursorPos);
|
||
|
}
|
||
|
}
|
||
|
if( !bRight && iCursorPos>0) { // BACKSPACE key
|
||
|
if( bShift) { // delete to start of line
|
||
|
strEditingLine.TrimLeft(ctChars-iCursorPos);
|
||
|
iCursorPos=0;
|
||
|
} else { // delete only one char
|
||
|
strEditingLine.DeleteChar(iCursorPos-1);
|
||
|
iCursorPos--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Key_ArrowUp(void)
|
||
|
{
|
||
|
CTString strSlash = "/";
|
||
|
CTString strHistoryLine;
|
||
|
if( iHistoryLine==0) strCurrentLine = strEditingLine;
|
||
|
INDEX iCurrentHistoryLine = iHistoryLine;
|
||
|
do {
|
||
|
// determine previous line in history
|
||
|
iCurrentHistoryLine++;
|
||
|
const char *pchrHistoryStart = (const char*)strInputHistory;
|
||
|
const char *pchrHistoryEnd = pchrHistoryStart +strlen( strInputHistory) -1;
|
||
|
// we reach top of history, if line doesn't exist in history
|
||
|
if( !GetLineCountBackward( pchrHistoryStart, pchrHistoryEnd, iCurrentHistoryLine, strHistoryLine)) return;
|
||
|
} while( strCurrentLine!="" &&
|
||
|
strnicmp( strHistoryLine, strCurrentLine, Min(strlen(strHistoryLine), strlen(strCurrentLine)))!=0 &&
|
||
|
strnicmp( strHistoryLine, strSlash+strCurrentLine, Min(strlen(strHistoryLine), strlen(strCurrentLine)+1))!=0);
|
||
|
// set new editing line
|
||
|
iHistoryLine = iCurrentHistoryLine;
|
||
|
strEditingLine = strHistoryLine;
|
||
|
iCursorPos = strlen(strEditingLine);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Key_ArrowDown(void)
|
||
|
{
|
||
|
CTString strSlash = "/";
|
||
|
CTString strHistoryLine;
|
||
|
if( iHistoryLine==0) strCurrentLine = strEditingLine;
|
||
|
INDEX iCurrentHistoryLine = iHistoryLine;
|
||
|
while( iCurrentHistoryLine>1) {
|
||
|
iCurrentHistoryLine--;
|
||
|
const char *pchrHistoryStart = (const char *) strInputHistory;
|
||
|
const char *pchrHistoryEnd = pchrHistoryStart +strlen(strInputHistory) -1;
|
||
|
// line must exist in history
|
||
|
BOOL bExists = GetLineCountBackward( pchrHistoryStart, pchrHistoryEnd, iCurrentHistoryLine, strHistoryLine);
|
||
|
ASSERT( bExists);
|
||
|
// set new editing line
|
||
|
if( strCurrentLine=="" ||
|
||
|
strnicmp( strHistoryLine, strCurrentLine, Min(strlen(strHistoryLine), strlen(strCurrentLine))) ==0 ||
|
||
|
strnicmp( strHistoryLine, strSlash+strCurrentLine, Min(strlen(strHistoryLine), strlen(strCurrentLine)+1))==0) {
|
||
|
iHistoryLine = iCurrentHistoryLine;
|
||
|
strEditingLine = strHistoryLine;
|
||
|
iCursorPos = strlen(strEditingLine);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DoCheat(const CTString &strCommand, const CTString &strVar)
|
||
|
{
|
||
|
_pShell->SetINDEX(strVar, !_pShell->GetINDEX(strVar));
|
||
|
BOOL bNew = _pShell->GetINDEX(strVar);
|
||
|
CPrintF("%s: %s\n", strCommand, bNew?"ON":"OFF");
|
||
|
}
|
||
|
|
||
|
static void Key_Return(void)
|
||
|
{
|
||
|
// ignore keydown return (keyup will be handled) - because of key bind to return
|
||
|
//if( _pGame->gm_csConsoleState==CS_TALK) return;
|
||
|
|
||
|
// clear editing line from whitespaces
|
||
|
strEditingLine.TrimSpacesLeft();
|
||
|
strEditingLine.TrimSpacesRight();
|
||
|
// reset display position
|
||
|
con_iFirstLine = 1;
|
||
|
|
||
|
// ignore empty lines
|
||
|
if( strEditingLine=="" || strEditingLine=="/") {
|
||
|
strEditingLine = "";
|
||
|
iCursorPos = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// add to history
|
||
|
strInputHistory += strEditingLine +"\r\n";
|
||
|
iHistoryLine = 0;
|
||
|
|
||
|
// check for cheats
|
||
|
#define CHEAT_PREFIX "please"
|
||
|
if (strEditingLine.HasPrefix(CHEAT_PREFIX) || strEditingLine.HasPrefix("/" CHEAT_PREFIX)) {
|
||
|
strEditingLine.RemovePrefix(CHEAT_PREFIX);
|
||
|
strEditingLine.RemovePrefix("/ " CHEAT_PREFIX );
|
||
|
strEditingLine.TrimSpacesLeft();
|
||
|
if (strEditingLine=="god") {
|
||
|
DoCheat(strEditingLine, "cht_bGod");
|
||
|
|
||
|
} else if (strEditingLine=="giveall") {
|
||
|
DoCheat(strEditingLine, "cht_bGiveAll");
|
||
|
|
||
|
} else if (strEditingLine=="killall") {
|
||
|
DoCheat(strEditingLine, "cht_bKillAll");
|
||
|
|
||
|
} else if (strEditingLine=="open") {
|
||
|
DoCheat(strEditingLine, "cht_bOpen");
|
||
|
|
||
|
} else if (strEditingLine=="tellall") {
|
||
|
DoCheat(strEditingLine, "cht_bAllMessages");
|
||
|
|
||
|
} else if (strEditingLine=="fly") {
|
||
|
DoCheat(strEditingLine, "cht_bFly");
|
||
|
|
||
|
} else if (strEditingLine=="ghost") {
|
||
|
DoCheat(strEditingLine, "cht_bGhost");
|
||
|
|
||
|
} else if (strEditingLine=="invisible") {
|
||
|
DoCheat(strEditingLine, "cht_bInvisible");
|
||
|
|
||
|
} else if (strEditingLine=="refresh") {
|
||
|
DoCheat(strEditingLine, "cht_bRefresh");
|
||
|
} else {
|
||
|
CPrintF("sorry?\n");
|
||
|
}
|
||
|
// parse editing line
|
||
|
} else if( strEditingLine[0]=='/') {
|
||
|
// add to output and execute
|
||
|
CPrintF( "-> %s\n", strEditingLine);
|
||
|
strEditingLine+=";";
|
||
|
_pShell->Execute(strEditingLine+1);
|
||
|
}
|
||
|
else if( !_pGame->gm_bGameOn) {
|
||
|
// add to output and execute
|
||
|
CPrintF( "-> %s\n", strEditingLine);
|
||
|
strEditingLine+=";";
|
||
|
_pShell->Execute(strEditingLine);
|
||
|
}
|
||
|
else {
|
||
|
// just send chat
|
||
|
_pNetwork->SendChat(-1, -1, strEditingLine);
|
||
|
}
|
||
|
|
||
|
// reset editing line
|
||
|
strEditingLine = "";
|
||
|
iCursorPos = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
// find first character that is not part of a symbol, backwards
|
||
|
char *strrnonsym(const char *strString)
|
||
|
{
|
||
|
const char *pch = strString+strlen(strString)-1;
|
||
|
while( pch>=strString) {
|
||
|
char ch = *pch;
|
||
|
if( !isalnum(ch) && ch!='_') return (char*)pch;
|
||
|
pch--;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Key_Tab( BOOL bShift)
|
||
|
{
|
||
|
// clear editing line from whitespaces
|
||
|
strEditingLine.TrimSpacesLeft();
|
||
|
strEditingLine.TrimSpacesRight();
|
||
|
// eventualy prepend the command like with '/'
|
||
|
if (strEditingLine[0]!='/') strEditingLine = CTString("/")+strEditingLine;
|
||
|
|
||
|
// find symbol letter typed so far
|
||
|
CTString strSymbol;
|
||
|
CTString strLastThatCanBeExpanded;
|
||
|
if( strLastExpanded == "") {
|
||
|
strExpandStart = strEditingLine;
|
||
|
iSymbolOffset = 0;
|
||
|
char *pcLastSymbol = strrnonsym( strEditingLine);
|
||
|
// remember symbol text and offset inside editing line
|
||
|
if( pcLastSymbol!=NULL) {
|
||
|
strExpandStart = pcLastSymbol+1;
|
||
|
iSymbolOffset = (INDEX)(pcLastSymbol+1 - (const char*)strEditingLine);
|
||
|
}
|
||
|
// printout all symbols that matches (if not only one, and not TAB only)
|
||
|
INDEX ctSymbolsFound=0;
|
||
|
BOOL bFirstFound = FALSE;
|
||
|
CTString strLastMatched;
|
||
|
{FOREACHINDYNAMICARRAY( _pShell->sh_assSymbols, CShellSymbol, itss) {
|
||
|
// TAB only pressd?
|
||
|
if( strExpandStart=="") break;
|
||
|
// get completion name if current symbol is for user
|
||
|
if( !(itss->ss_ulFlags&SSF_USER)) continue;
|
||
|
strSymbol = itss->GetCompletionString();
|
||
|
// if this symbol can be expanded
|
||
|
if( strnicmp( strSymbol, strExpandStart, Min(strlen(strSymbol),strlen(strExpandStart))) == 0) {
|
||
|
// can we print last found symbol ?
|
||
|
if( strLastMatched!="") {
|
||
|
if( !bFirstFound) CPrintF( " -\n");
|
||
|
CPrintF( " %s\n", strLastMatched);
|
||
|
bFirstFound = TRUE;
|
||
|
}
|
||
|
strLastMatched = strSymbol;
|
||
|
ctSymbolsFound++;
|
||
|
}
|
||
|
}}
|
||
|
// print last symbol
|
||
|
if( ctSymbolsFound>1) CPrintF( " %s\n", strLastMatched);
|
||
|
}
|
||
|
|
||
|
// for each of symbols in the shell
|
||
|
bLastExpandedFound = FALSE;
|
||
|
BOOL bTabSymbolFound = FALSE;
|
||
|
{FOREACHINDYNAMICARRAY( _pShell->sh_assSymbols, CShellSymbol, itss)
|
||
|
{
|
||
|
// skip if it is not visible to user
|
||
|
if( !(itss->ss_ulFlags&SSF_USER)) continue;
|
||
|
// get completion name for that symbol
|
||
|
strSymbol = itss->GetCompletionString();
|
||
|
|
||
|
// if this symbol can be expanded
|
||
|
if( strnicmp( strSymbol, strExpandStart, Min(strlen(strSymbol),strlen(strExpandStart))) == 0)
|
||
|
{
|
||
|
// at least one symbol is found, so tab will work
|
||
|
bTabSymbolFound = TRUE;
|
||
|
// if this is first time we are doing this
|
||
|
if( strLastExpanded == "") {
|
||
|
// remember symbol as last expanded and set it as current
|
||
|
strLastExpanded = strSymbol;
|
||
|
break;
|
||
|
}
|
||
|
// if last expanded was already found, set this symbol as result and remember it as last expanded
|
||
|
if( bLastExpandedFound) {
|
||
|
strLastExpanded = strSymbol;
|
||
|
break;
|
||
|
}
|
||
|
// if last expanded was not found yet, check if this one is last expanded
|
||
|
if( stricmp( strLastExpanded, strSymbol) == 0) {
|
||
|
// if looping backward (Shift+Tab)
|
||
|
if( bShift) {
|
||
|
// if we can loop backwards
|
||
|
if( strLastThatCanBeExpanded != "") {
|
||
|
strLastExpanded = strLastThatCanBeExpanded;
|
||
|
break;
|
||
|
// act like no symbols are found
|
||
|
} else {
|
||
|
bTabSymbolFound = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// if so, mark it
|
||
|
bLastExpandedFound = TRUE;
|
||
|
}
|
||
|
// remember current as last that can be expanded (for loopbing back)
|
||
|
strLastThatCanBeExpanded = strSymbol;
|
||
|
}
|
||
|
}}
|
||
|
// if symbol was found
|
||
|
if( bTabSymbolFound) {
|
||
|
// set it in current editing line
|
||
|
*((char*)(const char*)strEditingLine +iSymbolOffset) = '\0';
|
||
|
strEditingLine += strLastExpanded;
|
||
|
}
|
||
|
iCursorPos = strlen(strEditingLine);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Key_PgUp( BOOL bShift)
|
||
|
{
|
||
|
if( bShift) con_iFirstLine += ctConsoleLinesOnScreen;
|
||
|
else con_iFirstLine++;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void Key_PgDn( BOOL bShift)
|
||
|
{
|
||
|
if( bShift) con_iFirstLine -= ctConsoleLinesOnScreen;
|
||
|
else con_iFirstLine--;
|
||
|
con_iFirstLine = ClampDn( con_iFirstLine, 1L);
|
||
|
}
|
||
|
|
||
|
|
||
|
void CGame::ConsoleKeyDown( MSG msg)
|
||
|
{
|
||
|
// if console is off
|
||
|
if (_pGame->gm_csConsoleState==CS_OFF || _pGame->gm_csConsoleState==CS_TURNINGOFF) {
|
||
|
// do nothing
|
||
|
return;
|
||
|
}
|
||
|
BOOL bShift = GetKeyState(VK_SHIFT) & 0x8000;
|
||
|
switch( msg.wParam) {
|
||
|
case VK_RETURN: Key_Return(); break;
|
||
|
case VK_UP: Key_ArrowUp(); break;
|
||
|
case VK_DOWN: Key_ArrowDown(); break;
|
||
|
case VK_TAB: Key_Tab(bShift); break;
|
||
|
case VK_PRIOR: Key_PgUp(bShift); break;
|
||
|
case VK_NEXT: Key_PgDn(bShift); break;
|
||
|
case VK_BACK: Key_Backspace(bShift, FALSE); break;
|
||
|
case VK_DELETE: Key_Backspace(bShift, TRUE); break;
|
||
|
case VK_LEFT: if( iCursorPos > 0) iCursorPos--; break;
|
||
|
case VK_RIGHT: if( iCursorPos < strlen(strEditingLine)) iCursorPos++; break;
|
||
|
case VK_HOME: iCursorPos = 0; break;
|
||
|
case VK_END: iCursorPos = strlen(strEditingLine); break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CGame::ConsoleChar( MSG msg)
|
||
|
{
|
||
|
// if console is off, do nothing
|
||
|
if (_pGame->gm_csConsoleState==CS_OFF) return;
|
||
|
|
||
|
// for all keys except tab and shift, discard last found tab browsing symbol
|
||
|
char chrKey = msg.wParam;
|
||
|
if( msg.wParam!=VK_TAB && msg.wParam!=VK_SHIFT) strLastExpanded = "";
|
||
|
|
||
|
// if key with letter pressed
|
||
|
if( isprint(chrKey) && chrKey!='`') {
|
||
|
// insert it to editing line
|
||
|
strEditingLine.InsertChar( iCursorPos, chrKey);
|
||
|
iCursorPos++;
|
||
|
// reset history line
|
||
|
iHistoryLine = 0;
|
||
|
}
|
||
|
}
|
||
|
|