2021-04-02 16:18:20 +02:00
|
|
|
/* Copyright (C) 2021 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. 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.
|
|
|
|
*
|
|
|
|
* 0 A.D. 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 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2009-04-18 19:51:05 +02:00
|
|
|
/*
|
|
|
|
* Implements the in-game console with scripting support.
|
2007-05-07 18:33:24 +02:00
|
|
|
*/
|
|
|
|
|
2004-06-03 20:38:14 +02:00
|
|
|
#include "precompiled.h"
|
2004-07-10 20:57:13 +02:00
|
|
|
#include <wctype.h>
|
2004-06-03 20:38:14 +02:00
|
|
|
|
2004-06-02 22:40:07 +02:00
|
|
|
#include "CConsole.h"
|
|
|
|
|
2021-05-29 14:31:14 +02:00
|
|
|
#include "graphics/Canvas2D.h"
|
2013-10-18 17:53:07 +02:00
|
|
|
#include "graphics/FontMetrics.h"
|
2012-02-12 21:45:31 +01:00
|
|
|
#include "graphics/TextRenderer.h"
|
2019-08-04 05:52:00 +02:00
|
|
|
#include "gui/CGUI.h"
|
2014-01-04 11:14:53 +01:00
|
|
|
#include "gui/GUIManager.h"
|
2019-08-04 05:52:00 +02:00
|
|
|
#include "gui/GUIMatrix.h"
|
2006-06-09 18:44:16 +02:00
|
|
|
#include "lib/ogl.h"
|
2013-01-12 02:20:01 +01:00
|
|
|
#include "lib/timer.h"
|
2014-09-20 14:12:35 +02:00
|
|
|
#include "lib/utf8.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "maths/MathUtil.h"
|
2008-06-16 20:19:35 +02:00
|
|
|
#include "network/NetClient.h"
|
|
|
|
#include "network/NetServer.h"
|
2006-06-09 18:44:16 +02:00
|
|
|
#include "ps/CLogger.h"
|
2021-05-22 01:10:43 +02:00
|
|
|
#include "ps/ConfigDB.h"
|
2021-05-18 13:09:54 +02:00
|
|
|
#include "ps/CStrInternStatic.h"
|
2007-12-20 21:21:45 +01:00
|
|
|
#include "ps/Filesystem.h"
|
2016-08-02 18:58:30 +02:00
|
|
|
#include "ps/GameSetup/Config.h"
|
2006-06-09 18:44:16 +02:00
|
|
|
#include "ps/Globals.h"
|
|
|
|
#include "ps/Hotkey.h"
|
2016-06-21 12:33:11 +02:00
|
|
|
#include "ps/Profile.h"
|
2006-06-09 18:44:16 +02:00
|
|
|
#include "ps/Pyrogenesis.h"
|
2021-10-17 12:58:51 +02:00
|
|
|
#include "ps/VideoMode.h"
|
2010-10-31 23:00:28 +01:00
|
|
|
#include "scriptinterface/ScriptInterface.h"
|
2021-05-14 12:18:03 +02:00
|
|
|
#include "scriptinterface/JSON.h"
|
2004-08-03 01:14:54 +02:00
|
|
|
|
2021-05-29 14:31:14 +02:00
|
|
|
#include <vector>
|
|
|
|
|
2021-05-22 01:10:43 +02:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
// For text being typed into the console.
|
|
|
|
constexpr int CONSOLE_BUFFER_SIZE = 1024;
|
|
|
|
|
|
|
|
const char* CONSOLE_FONT = "mono-10";
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
2005-07-03 18:25:48 +02:00
|
|
|
CConsole* g_Console = 0;
|
|
|
|
|
2004-07-11 18:03:26 +02:00
|
|
|
CConsole::CConsole()
|
2004-06-03 02:19:22 +02:00
|
|
|
{
|
2004-06-02 22:40:07 +02:00
|
|
|
m_bToggle = false;
|
|
|
|
m_bVisible = false;
|
|
|
|
|
2004-06-03 03:42:40 +02:00
|
|
|
m_fVisibleFrac = 0.0f;
|
2004-06-03 02:19:22 +02:00
|
|
|
|
2004-08-14 13:40:40 +02:00
|
|
|
m_szBuffer = new wchar_t[CONSOLE_BUFFER_SIZE];
|
2004-06-02 22:40:07 +02:00
|
|
|
FlushBuffer();
|
|
|
|
|
|
|
|
m_iMsgHistPos = 1;
|
2012-02-12 21:45:31 +01:00
|
|
|
m_charsPerPage = 0;
|
2013-01-12 02:20:01 +01:00
|
|
|
|
|
|
|
m_prevTime = 0.0;
|
|
|
|
m_bCursorVisState = true;
|
|
|
|
m_cursorBlinkRate = 0.5;
|
|
|
|
|
2021-12-07 21:09:46 +01:00
|
|
|
m_QuitHotkeyWasShown = false;
|
|
|
|
|
|
|
|
InsertMessage("[ 0 A.D. Console v0.15 ]");
|
2015-02-14 02:49:34 +01:00
|
|
|
InsertMessage("");
|
2006-07-06 05:17:44 +02:00
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
|
|
|
|
CConsole::~CConsole()
|
|
|
|
{
|
|
|
|
delete[] m_szBuffer;
|
|
|
|
}
|
|
|
|
|
2021-05-22 01:10:43 +02:00
|
|
|
void CConsole::Init()
|
2004-07-11 18:03:26 +02:00
|
|
|
{
|
2021-05-22 01:10:43 +02:00
|
|
|
// Initialise console history file
|
|
|
|
m_MaxHistoryLines = 200;
|
|
|
|
CFG_GET_VAL("console.history.size", m_MaxHistoryLines);
|
|
|
|
|
|
|
|
m_sHistoryFile = L"config/console.txt";
|
|
|
|
LoadHistory();
|
|
|
|
|
|
|
|
UpdateScreenSize(g_xres, g_yres);
|
|
|
|
|
|
|
|
// Calculate and store the line spacing
|
|
|
|
const CFontMetrics font{CStrIntern(CONSOLE_FONT)};
|
|
|
|
m_iFontHeight = font.GetLineSpacing();
|
|
|
|
m_iFontWidth = font.GetCharacterWidth(L'C');
|
|
|
|
m_charsPerPage = static_cast<size_t>(g_xres / m_iFontWidth);
|
|
|
|
// Offset by an arbitrary amount, to make it fit more nicely
|
|
|
|
m_iFontOffset = 7;
|
|
|
|
|
|
|
|
m_cursorBlinkRate = 0.5;
|
|
|
|
CFG_GET_VAL("gui.cursorblinkrate", m_cursorBlinkRate);
|
2004-07-11 18:03:26 +02:00
|
|
|
}
|
|
|
|
|
2005-07-03 18:25:48 +02:00
|
|
|
void CConsole::UpdateScreenSize(int w, int h)
|
|
|
|
{
|
2021-05-22 01:10:43 +02:00
|
|
|
m_fX = 0;
|
|
|
|
m_fY = 0;
|
2005-07-03 18:25:48 +02:00
|
|
|
float height = h * 0.6f;
|
2021-10-17 12:58:51 +02:00
|
|
|
m_fWidth = w / g_VideoMode.GetScale();
|
|
|
|
m_fHeight = height / g_VideoMode.GetScale();
|
2005-07-03 18:25:48 +02:00
|
|
|
}
|
|
|
|
|
2021-12-07 21:09:46 +01:00
|
|
|
void CConsole::ShowQuitHotkeys()
|
|
|
|
{
|
|
|
|
if (m_QuitHotkeyWasShown)
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::string str;
|
|
|
|
for (const std::pair<const SDL_Scancode_, KeyMapping>& key : g_HotkeyMap)
|
|
|
|
if (key.second.front().name == "console.toggle")
|
|
|
|
str += (str.empty() ? "Press " : " / ") + FindScancodeName(static_cast<SDL_Scancode>(key.first));
|
|
|
|
|
|
|
|
if (!str.empty())
|
|
|
|
InsertMessage(str + " to quit.");
|
|
|
|
|
|
|
|
m_QuitHotkeyWasShown = true;
|
|
|
|
}
|
|
|
|
|
2004-07-13 23:09:55 +02:00
|
|
|
void CConsole::ToggleVisible()
|
|
|
|
{
|
|
|
|
m_bToggle = true;
|
|
|
|
m_bVisible = !m_bVisible;
|
2014-10-04 01:33:41 +02:00
|
|
|
|
|
|
|
// TODO: this should be based on input focus, not visibility
|
|
|
|
if (m_bVisible)
|
2021-12-07 21:09:46 +01:00
|
|
|
{
|
|
|
|
ShowQuitHotkeys();
|
2014-10-04 01:33:41 +02:00
|
|
|
SDL_StartTextInput();
|
2021-12-07 21:09:46 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
SDL_StopTextInput();
|
2004-07-13 23:09:55 +02:00
|
|
|
}
|
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
void CConsole::SetVisible(bool visible)
|
2004-08-03 01:14:54 +02:00
|
|
|
{
|
2012-02-12 21:45:31 +01:00
|
|
|
if (visible != m_bVisible)
|
2004-08-03 01:14:54 +02:00
|
|
|
m_bToggle = true;
|
|
|
|
m_bVisible = visible;
|
2013-01-12 02:20:01 +01:00
|
|
|
if (visible)
|
|
|
|
{
|
|
|
|
m_prevTime = 0.0;
|
|
|
|
m_bCursorVisState = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
void CConsole::FlushBuffer()
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2005-01-23 18:45:25 +01:00
|
|
|
// Clear the buffer and set the cursor and length to 0
|
2004-08-14 13:40:40 +02:00
|
|
|
memset(m_szBuffer, '\0', sizeof(wchar_t) * CONSOLE_BUFFER_SIZE);
|
2004-06-02 22:40:07 +02:00
|
|
|
m_iBufferPos = m_iBufferLength = 0;
|
|
|
|
}
|
|
|
|
|
2012-06-06 21:37:03 +02:00
|
|
|
void CConsole::Update(const float deltaRealTime)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2004-06-03 02:19:22 +02:00
|
|
|
if(m_bToggle)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2004-06-03 02:19:22 +02:00
|
|
|
const float AnimateTime = .30f;
|
2012-06-06 21:37:03 +02:00
|
|
|
const float Delta = deltaRealTime / AnimateTime;
|
2004-06-03 02:19:22 +02:00
|
|
|
if(m_bVisible)
|
|
|
|
{
|
2004-06-03 03:42:40 +02:00
|
|
|
m_fVisibleFrac += Delta;
|
|
|
|
if(m_fVisibleFrac > 1.0f)
|
2004-06-03 02:19:22 +02:00
|
|
|
{
|
2004-06-03 03:42:40 +02:00
|
|
|
m_fVisibleFrac = 1.0f;
|
2004-06-03 02:19:22 +02:00
|
|
|
m_bToggle = false;
|
|
|
|
}
|
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
else
|
2004-06-03 02:19:22 +02:00
|
|
|
{
|
2004-06-03 03:42:40 +02:00
|
|
|
m_fVisibleFrac -= Delta;
|
|
|
|
if(m_fVisibleFrac < 0.0f)
|
2004-06-03 02:19:22 +02:00
|
|
|
{
|
2004-06-03 03:42:40 +02:00
|
|
|
m_fVisibleFrac = 0.0f;
|
2004-06-03 02:19:22 +02:00
|
|
|
m_bToggle = false;
|
|
|
|
}
|
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CConsole::Render()
|
|
|
|
{
|
2004-06-26 14:58:35 +02:00
|
|
|
if (! (m_bVisible || m_bToggle) ) return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2011-11-09 14:09:01 +01:00
|
|
|
PROFILE3_GPU("console");
|
2011-11-04 02:35:50 +01:00
|
|
|
|
2021-05-30 21:10:10 +02:00
|
|
|
CCanvas2D canvas;
|
2012-02-12 21:45:31 +01:00
|
|
|
|
2021-05-30 21:10:10 +02:00
|
|
|
DrawWindow(canvas);
|
2014-07-14 19:15:22 +02:00
|
|
|
|
2021-05-30 20:28:06 +02:00
|
|
|
CTextRenderer textRenderer;
|
2021-06-02 23:21:28 +02:00
|
|
|
textRenderer.SetCurrentFont(CStrIntern(CONSOLE_FONT));
|
2021-06-03 00:16:09 +02:00
|
|
|
// Animation: slide in from top of screen.
|
2021-05-29 14:31:14 +02:00
|
|
|
const float DeltaY = (1.0f - m_fVisibleFrac) * m_fHeight;
|
2021-06-03 00:16:09 +02:00
|
|
|
textRenderer.Translate(m_fX, m_fY - DeltaY);
|
2010-05-04 00:09:18 +02:00
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
DrawHistory(textRenderer);
|
|
|
|
DrawBuffer(textRenderer);
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2021-05-30 21:10:10 +02:00
|
|
|
canvas.DrawText(textRenderer);
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
2021-05-30 21:10:10 +02:00
|
|
|
void CConsole::DrawWindow(CCanvas2D& canvas)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2021-05-29 14:31:14 +02:00
|
|
|
std::vector<CVector2D> points = {
|
|
|
|
CVector2D{m_fWidth, 0.0f},
|
|
|
|
CVector2D{1.0f, 0.0f},
|
|
|
|
CVector2D{1.0f, m_fHeight - 1.0f},
|
|
|
|
CVector2D{m_fWidth, m_fHeight - 1.0f},
|
|
|
|
CVector2D{m_fWidth, 0.0f}
|
2012-02-12 21:45:31 +01:00
|
|
|
};
|
2021-05-29 14:31:14 +02:00
|
|
|
for (CVector2D& point : points)
|
|
|
|
point += CVector2D{m_fX, m_fY - (1.0f - m_fVisibleFrac) * m_fHeight};
|
2012-02-12 21:45:31 +01:00
|
|
|
|
2021-05-29 14:31:14 +02:00
|
|
|
canvas.DrawRect(CRect(points[1], points[3]), CColor(0.0f, 0.0f, 0.5f, 0.6f));
|
|
|
|
canvas.DrawLine(points, 1.0f, CColor(0.5f, 0.5f, 0.0f, 0.6f));
|
2010-05-04 00:09:18 +02:00
|
|
|
|
|
|
|
if (m_fHeight > m_iFontHeight + 4)
|
|
|
|
{
|
2021-05-29 14:31:14 +02:00
|
|
|
points = {
|
|
|
|
CVector2D{0.0f, m_fHeight - static_cast<float>(m_iFontHeight) - 4.0f},
|
|
|
|
CVector2D{m_fWidth, m_fHeight - static_cast<float>(m_iFontHeight) - 4.0f}
|
2012-02-12 21:45:31 +01:00
|
|
|
};
|
2021-05-30 00:30:23 +02:00
|
|
|
for (CVector2D& point : points)
|
|
|
|
point += CVector2D{m_fX, m_fY - (1.0f - m_fVisibleFrac) * m_fHeight};
|
2021-05-29 14:31:14 +02:00
|
|
|
canvas.DrawLine(points, 1.0f, CColor(0.5f, 0.5f, 0.0f, 0.6f));
|
2010-05-04 00:09:18 +02:00
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
void CConsole::DrawHistory(CTextRenderer& textRenderer)
|
2010-10-31 23:00:28 +01:00
|
|
|
{
|
2004-06-02 22:40:07 +02:00
|
|
|
int i = 1;
|
2006-02-11 19:53:32 +01:00
|
|
|
|
2004-06-16 17:42:48 +02:00
|
|
|
std::deque<std::wstring>::iterator Iter; //History iterator
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2019-06-06 21:30:48 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_Mutex); // needed for safe access to m_deqMsgHistory
|
2010-10-31 23:00:28 +01:00
|
|
|
|
2021-06-02 23:21:28 +02:00
|
|
|
textRenderer.SetCurrentColor(CColor(1.0f, 1.0f, 1.0f, 1.0f));
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
for (Iter = m_deqMsgHistory.begin();
|
|
|
|
Iter != m_deqMsgHistory.end()
|
|
|
|
&& (((i - m_iMsgHistPos + 1) * m_iFontHeight) < m_fHeight);
|
|
|
|
++Iter)
|
|
|
|
{
|
|
|
|
if (i >= m_iMsgHistPos)
|
2012-04-13 14:15:50 +02:00
|
|
|
textRenderer.Put(9.0f, m_fHeight - (float)m_iFontOffset - (float)m_iFontHeight * (i - m_iMsgHistPos + 1), Iter->c_str());
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
i++;
|
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
// Renders the buffer to the screen.
|
|
|
|
void CConsole::DrawBuffer(CTextRenderer& textRenderer)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2012-02-12 21:45:31 +01:00
|
|
|
if (m_fHeight < m_iFontHeight)
|
|
|
|
return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2021-06-03 00:16:09 +02:00
|
|
|
const CVector2D savedTranslate = textRenderer.GetTranslate();
|
2004-07-14 00:44:20 +02:00
|
|
|
|
2021-06-02 23:21:28 +02:00
|
|
|
textRenderer.Translate(2.0f, m_fHeight - (float)m_iFontOffset + 1.0f);
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2021-06-02 23:21:28 +02:00
|
|
|
textRenderer.SetCurrentColor(CColor(1.0f, 1.0f, 0.0f, 1.0f));
|
2012-02-25 18:14:47 +01:00
|
|
|
textRenderer.PutAdvance(L"]");
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2021-06-02 23:21:28 +02:00
|
|
|
textRenderer.SetCurrentColor(CColor(1.0f, 1.0f, 1.0f, 1.0f));
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
if (m_iBufferPos == 0)
|
|
|
|
DrawCursor(textRenderer);
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2012-02-12 21:45:31 +01:00
|
|
|
for (int i = 0; i < m_iBufferLength; i++)
|
|
|
|
{
|
2012-02-25 18:14:47 +01:00
|
|
|
textRenderer.PrintfAdvance(L"%lc", m_szBuffer[i]);
|
2012-02-12 21:45:31 +01:00
|
|
|
if (m_iBufferPos-1 == i)
|
|
|
|
DrawCursor(textRenderer);
|
|
|
|
}
|
|
|
|
|
2021-06-03 00:16:09 +02:00
|
|
|
textRenderer.ResetTranslate(savedTranslate);
|
2012-02-12 21:45:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CConsole::DrawCursor(CTextRenderer& textRenderer)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2013-01-12 02:20:01 +01:00
|
|
|
if (m_cursorBlinkRate > 0.0)
|
|
|
|
{
|
|
|
|
// check if the cursor visibility state needs to be changed
|
|
|
|
double currTime = timer_Time();
|
|
|
|
if ((currTime - m_prevTime) >= m_cursorBlinkRate)
|
|
|
|
{
|
|
|
|
m_bCursorVisState = !m_bCursorVisState;
|
|
|
|
m_prevTime = currTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Should always be visible
|
|
|
|
m_bCursorVisState = true;
|
|
|
|
}
|
2004-08-11 16:48:36 +02:00
|
|
|
|
2013-01-12 02:20:01 +01:00
|
|
|
if(m_bCursorVisState)
|
|
|
|
{
|
|
|
|
// Slightly translucent yellow
|
2021-06-02 23:21:28 +02:00
|
|
|
textRenderer.SetCurrentColor(CColor(1.0f, 1.0f, 0.0f, 0.8f));
|
2004-08-11 16:48:36 +02:00
|
|
|
|
2013-01-12 02:20:01 +01:00
|
|
|
// Cursor character is chosen to be an underscore
|
|
|
|
textRenderer.Put(0.0f, 0.0f, L"_");
|
|
|
|
|
2015-03-16 00:59:48 +01:00
|
|
|
// Revert to the standard text color
|
2021-06-02 23:21:28 +02:00
|
|
|
textRenderer.SetCurrentColor(CColor(1.0f, 1.0f, 1.0f, 1.0f));
|
2013-01-12 02:20:01 +01:00
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
2021-05-22 01:10:43 +02:00
|
|
|
bool CConsole::IsEOB() const
|
|
|
|
{
|
|
|
|
return m_iBufferPos == m_iBufferLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CConsole::IsBOB() const
|
|
|
|
{
|
|
|
|
return m_iBufferPos == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CConsole::IsFull() const
|
|
|
|
{
|
|
|
|
return m_iBufferLength == CONSOLE_BUFFER_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CConsole::IsEmpty() const
|
|
|
|
{
|
|
|
|
return m_iBufferLength == 0;
|
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
|
|
|
|
//Inserts a character into the buffer.
|
2012-02-12 21:45:31 +01:00
|
|
|
void CConsole::InsertChar(const int szChar, const wchar_t cooked)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
|
|
|
static int iHistoryPos = -1;
|
|
|
|
|
|
|
|
if (!m_bVisible) return;
|
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
switch (szChar)
|
|
|
|
{
|
|
|
|
case SDLK_RETURN:
|
|
|
|
iHistoryPos = -1;
|
|
|
|
m_iMsgHistPos = 1;
|
|
|
|
ProcessBuffer(m_szBuffer);
|
|
|
|
FlushBuffer();
|
|
|
|
return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_TAB:
|
|
|
|
// Auto Complete
|
|
|
|
return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_BACKSPACE:
|
|
|
|
if (IsEmpty() || IsBOB()) return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
if (m_iBufferPos == m_iBufferLength)
|
|
|
|
m_szBuffer[m_iBufferPos - 1] = '\0';
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int j = m_iBufferPos-1; j < m_iBufferLength-1; j++)
|
|
|
|
m_szBuffer[j] = m_szBuffer[j+1]; // move chars to left
|
|
|
|
m_szBuffer[m_iBufferLength-1] = '\0';
|
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
m_iBufferPos--;
|
|
|
|
m_iBufferLength--;
|
|
|
|
return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_DELETE:
|
|
|
|
if (IsEmpty() || IsEOB()) return;
|
2004-06-26 14:45:54 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
if (m_iBufferPos == m_iBufferLength-1)
|
|
|
|
{
|
|
|
|
m_szBuffer[m_iBufferPos] = '\0';
|
|
|
|
m_iBufferLength--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-01-16 16:46:56 +01:00
|
|
|
if (g_scancodes[SDL_SCANCODE_LCTRL] || g_scancodes[SDL_SCANCODE_RCTRL])
|
2006-05-16 06:41:37 +02:00
|
|
|
{
|
2015-12-16 16:36:56 +01:00
|
|
|
// Make Ctrl-Delete delete up to end of line
|
2004-06-26 14:45:54 +02:00
|
|
|
m_szBuffer[m_iBufferPos] = '\0';
|
2015-12-16 16:36:56 +01:00
|
|
|
m_iBufferLength = m_iBufferPos;
|
2006-05-16 06:41:37 +02:00
|
|
|
}
|
2016-11-23 14:02:58 +01:00
|
|
|
else
|
2006-05-16 06:41:37 +02:00
|
|
|
{
|
2015-12-16 16:36:56 +01:00
|
|
|
// Delete just one char and move the others left
|
|
|
|
for(int j=m_iBufferPos; j<m_iBufferLength-1; j++)
|
|
|
|
m_szBuffer[j] = m_szBuffer[j+1];
|
|
|
|
m_szBuffer[m_iBufferLength-1] = '\0';
|
|
|
|
m_iBufferLength--;
|
2004-06-26 14:45:54 +02:00
|
|
|
}
|
2015-12-16 16:36:56 +01:00
|
|
|
}
|
2004-06-26 14:45:54 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
return;
|
2004-06-26 14:45:54 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_HOME:
|
2021-01-16 16:46:56 +01:00
|
|
|
if (g_scancodes[SDL_SCANCODE_LCTRL] || g_scancodes[SDL_SCANCODE_RCTRL])
|
2015-12-16 16:36:56 +01:00
|
|
|
{
|
2019-06-06 21:30:48 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_Mutex); // needed for safe access to m_deqMsgHistory
|
2010-10-31 23:00:28 +01:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
int linesShown = (int)m_fHeight/m_iFontHeight - 4;
|
2019-09-18 16:44:31 +02:00
|
|
|
m_iMsgHistPos = Clamp(static_cast<int>(m_deqMsgHistory.size()) - linesShown, 1, static_cast<int>(m_deqMsgHistory.size()));
|
2015-12-16 16:36:56 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_iBufferPos = 0;
|
|
|
|
}
|
|
|
|
return;
|
2004-06-26 14:45:54 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_END:
|
2021-01-16 16:46:56 +01:00
|
|
|
if (g_scancodes[SDL_SCANCODE_LCTRL] || g_scancodes[SDL_SCANCODE_RCTRL])
|
2015-12-16 16:36:56 +01:00
|
|
|
{
|
|
|
|
m_iMsgHistPos = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_iBufferPos = m_iBufferLength;
|
|
|
|
}
|
|
|
|
return;
|
2004-06-26 14:45:54 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_LEFT:
|
|
|
|
if (m_iBufferPos) m_iBufferPos--;
|
|
|
|
return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_RIGHT:
|
|
|
|
if (m_iBufferPos != m_iBufferLength) m_iBufferPos++;
|
|
|
|
return;
|
|
|
|
|
|
|
|
// BEGIN: Buffer History Lookup
|
|
|
|
case SDLK_UP:
|
|
|
|
if (m_deqBufHistory.size() && iHistoryPos != (int)m_deqBufHistory.size() - 1)
|
|
|
|
{
|
|
|
|
iHistoryPos++;
|
|
|
|
SetBuffer(m_deqBufHistory.at(iHistoryPos).c_str());
|
|
|
|
m_iBufferPos = m_iBufferLength;
|
|
|
|
}
|
|
|
|
return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_DOWN:
|
|
|
|
if (m_deqBufHistory.size())
|
|
|
|
{
|
|
|
|
if (iHistoryPos > 0)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2015-12-16 16:36:56 +01:00
|
|
|
iHistoryPos--;
|
2011-07-31 01:06:09 +02:00
|
|
|
SetBuffer(m_deqBufHistory.at(iHistoryPos).c_str());
|
|
|
|
m_iBufferPos = m_iBufferLength;
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
2015-12-16 16:36:56 +01:00
|
|
|
else if (iHistoryPos == 0)
|
2006-01-22 10:56:12 +01:00
|
|
|
{
|
2015-12-16 16:36:56 +01:00
|
|
|
iHistoryPos--;
|
|
|
|
FlushBuffer();
|
2006-01-22 10:56:12 +01:00
|
|
|
}
|
2015-12-16 16:36:56 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
// END: Buffer History Lookup
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
// BEGIN: Message History Lookup
|
|
|
|
case SDLK_PAGEUP:
|
|
|
|
{
|
2019-06-06 21:30:48 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_Mutex); // needed for safe access to m_deqMsgHistory
|
2010-10-31 23:00:28 +01:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
if (m_iMsgHistPos != (int)m_deqMsgHistory.size()) m_iMsgHistPos++;
|
|
|
|
return;
|
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
case SDLK_PAGEDOWN:
|
|
|
|
if (m_iMsgHistPos != 1) m_iMsgHistPos--;
|
|
|
|
return;
|
|
|
|
// END: Message History Lookup
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
default: //Insert a character
|
|
|
|
if (IsFull()) return;
|
|
|
|
if (cooked == 0) return;
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2015-12-16 16:36:56 +01:00
|
|
|
if (IsEOB()) //are we at the end of the buffer?
|
|
|
|
m_szBuffer[m_iBufferPos] = cooked; //cat char onto end
|
|
|
|
else
|
|
|
|
{ //we need to insert
|
|
|
|
int i;
|
|
|
|
for(i=m_iBufferLength; i>m_iBufferPos; i--)
|
|
|
|
m_szBuffer[i] = m_szBuffer[i-1]; // move chars to right
|
|
|
|
m_szBuffer[i] = cooked;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iBufferPos++;
|
|
|
|
m_iBufferLength++;
|
|
|
|
|
|
|
|
return;
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-16 17:42:48 +02:00
|
|
|
|
2015-02-14 02:49:34 +01:00
|
|
|
void CConsole::InsertMessage(const std::string& message)
|
2006-09-02 23:20:25 +02:00
|
|
|
{
|
|
|
|
// (TODO: this text-wrapping is rubbish since we now use variable-width fonts)
|
|
|
|
|
2006-07-06 05:17:44 +02:00
|
|
|
//Insert newlines to wraparound text where needed
|
2015-02-14 02:49:34 +01:00
|
|
|
std::wstring wrapAround = wstring_from_utf8(message.c_str());
|
|
|
|
std::wstring newline(L"\n");
|
2006-07-06 05:17:44 +02:00
|
|
|
size_t oldNewline=0;
|
|
|
|
size_t distance;
|
2016-11-23 15:09:58 +01:00
|
|
|
|
2006-07-06 05:17:44 +02:00
|
|
|
//make sure everything has been initialized
|
|
|
|
if ( m_charsPerPage != 0 )
|
|
|
|
{
|
|
|
|
while ( oldNewline+m_charsPerPage < wrapAround.length() )
|
|
|
|
{
|
|
|
|
distance = wrapAround.find(newline, oldNewline) - oldNewline;
|
|
|
|
if ( distance > m_charsPerPage )
|
|
|
|
{
|
|
|
|
oldNewline += m_charsPerPage;
|
|
|
|
wrapAround.insert( oldNewline++, newline );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
oldNewline += distance+1;
|
|
|
|
}
|
|
|
|
}
|
2004-07-11 17:07:38 +02:00
|
|
|
// Split into lines and add each one individually
|
2006-07-06 05:17:44 +02:00
|
|
|
oldNewline = 0;
|
|
|
|
|
2004-07-11 17:07:38 +02:00
|
|
|
{
|
2019-06-06 21:30:48 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_Mutex); // needed for safe access to m_deqMsgHistory
|
2010-10-31 23:00:28 +01:00
|
|
|
|
|
|
|
while ( (distance = wrapAround.find(newline, oldNewline)) != wrapAround.npos)
|
|
|
|
{
|
|
|
|
distance -= oldNewline;
|
|
|
|
m_deqMsgHistory.push_front(wrapAround.substr(oldNewline, distance));
|
|
|
|
oldNewline += distance+1;
|
|
|
|
}
|
|
|
|
m_deqMsgHistory.push_front(wrapAround.substr(oldNewline));
|
2004-07-11 17:07:38 +02:00
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
2004-08-03 01:14:54 +02:00
|
|
|
const wchar_t* CConsole::GetBuffer()
|
|
|
|
{
|
|
|
|
m_szBuffer[m_iBufferLength] = 0;
|
|
|
|
return( m_szBuffer );
|
|
|
|
}
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2010-03-20 23:01:39 +01:00
|
|
|
void CConsole::SetBuffer(const wchar_t* szMessage)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2006-01-22 10:56:12 +01:00
|
|
|
int oldBufferPos = m_iBufferPos; // remember since FlushBuffer will set it to 0
|
|
|
|
|
2004-06-02 22:40:07 +02:00
|
|
|
FlushBuffer();
|
|
|
|
|
2004-08-14 13:40:40 +02:00
|
|
|
wcsncpy(m_szBuffer, szMessage, CONSOLE_BUFFER_SIZE);
|
2013-01-21 21:33:25 +01:00
|
|
|
m_szBuffer[CONSOLE_BUFFER_SIZE-1] = 0;
|
2020-05-05 13:18:00 +02:00
|
|
|
m_iBufferLength = static_cast<int>(wcslen(m_szBuffer));
|
2006-01-22 10:56:12 +01:00
|
|
|
m_iBufferPos = std::min(oldBufferPos, m_iBufferLength);
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
2006-11-07 22:03:13 +01:00
|
|
|
void CConsole::ProcessBuffer(const wchar_t* szLine)
|
|
|
|
{
|
2020-11-13 14:18:22 +01:00
|
|
|
if (!szLine || wcslen(szLine) <= 0)
|
|
|
|
return;
|
2006-02-11 19:53:32 +01:00
|
|
|
|
2011-04-30 15:01:45 +02:00
|
|
|
ENSURE(wcslen(szLine) < CONSOLE_BUFFER_SIZE);
|
2004-06-02 22:40:07 +02:00
|
|
|
|
|
|
|
m_deqBufHistory.push_front(szLine);
|
2005-05-10 09:13:25 +02:00
|
|
|
SaveHistory(); // Do this each line for the moment; if a script causes
|
|
|
|
// a crash it's a useful record.
|
2004-06-02 22:40:07 +02:00
|
|
|
|
2010-10-31 23:00:28 +01:00
|
|
|
// Process it as JavaScript
|
2021-05-22 21:28:40 +02:00
|
|
|
std::shared_ptr<ScriptInterface> pScriptInterface = g_GUI->GetActiveGUI()->GetScriptInterface();
|
Improve JS Exception handling.
- Check for pending exceptions after function calls and script
executions.
- Call LOGERROR instead of JS_ReportError when there is a conversion
error in FromJSVal, since that can only be called from C++ (where JS
errors don't really make sense). Instead, C++ callers of FromJSVal
should handle the failure and, themselves, either report an error or
simply do something else.
- Wrap JS_ReportError since that makes updating it later easier.
This isn't a systematical fix since ToJSVal also ought return a boolean
for failures, and we probably should trigger errors instead of warnings
on 'implicit' conversions, rather a preparation diff.
Part of the SM52 migration, stage: SM45 compatible (actually SM52
incompatible, too).
Based on a patch by: Itms
Comments by: Vladislavbelov, Stan`
Refs #742, #4893
Differential Revision: https://code.wildfiregames.com/D3093
This was SVN commit r24187.
2020-11-15 19:29:17 +01:00
|
|
|
ScriptRequest rq(*pScriptInterface);
|
2016-11-23 15:09:58 +01:00
|
|
|
|
2020-11-13 14:18:22 +01:00
|
|
|
JS::RootedValue rval(rq.cx);
|
2020-11-30 10:03:20 +01:00
|
|
|
pScriptInterface->Eval(CStrW(szLine).ToUTF8().c_str(), &rval);
|
2014-07-27 00:33:16 +02:00
|
|
|
if (!rval.isUndefined())
|
2021-05-14 12:18:03 +02:00
|
|
|
InsertMessage(Script::ToString(rq, &rval));
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|
|
|
|
|
2005-05-10 09:13:25 +02:00
|
|
|
void CConsole::LoadHistory()
|
|
|
|
{
|
2006-05-04 17:27:06 +02:00
|
|
|
// note: we don't care if this file doesn't exist or can't be read;
|
|
|
|
// just don't load anything in that case.
|
|
|
|
|
2007-12-20 21:21:45 +01:00
|
|
|
// do this before LoadFile to avoid an error message if file not found.
|
2011-02-25 17:30:55 +01:00
|
|
|
if (!VfsFileExists(m_sHistoryFile))
|
2006-05-04 17:27:06 +02:00
|
|
|
return;
|
|
|
|
|
2021-05-22 21:28:40 +02:00
|
|
|
std::shared_ptr<u8> buf; size_t buflen;
|
2007-12-20 21:21:45 +01:00
|
|
|
if (g_VFS->LoadFile(m_sHistoryFile, buf, buflen) < 0)
|
2006-01-24 09:16:29 +01:00
|
|
|
return;
|
|
|
|
|
2007-12-20 21:21:45 +01:00
|
|
|
CStr bytes ((char*)buf.get(), buflen);
|
2006-01-24 09:16:29 +01:00
|
|
|
|
2007-02-01 15:46:14 +01:00
|
|
|
CStrW str (bytes.FromUTF8());
|
2006-01-24 09:16:29 +01:00
|
|
|
size_t pos = 0;
|
2007-02-01 15:46:14 +01:00
|
|
|
while (pos != CStrW::npos)
|
2005-05-10 09:13:25 +02:00
|
|
|
{
|
2007-02-01 15:46:14 +01:00
|
|
|
pos = str.find('\n');
|
|
|
|
if (pos != CStrW::npos)
|
2005-05-10 09:13:25 +02:00
|
|
|
{
|
2007-02-01 15:46:14 +01:00
|
|
|
if (pos > 0)
|
|
|
|
m_deqBufHistory.push_front(str.Left(str[pos-1] == '\r' ? pos - 1 : pos));
|
|
|
|
str = str.substr(pos + 1);
|
2005-05-10 09:13:25 +02:00
|
|
|
}
|
2007-02-01 15:46:14 +01:00
|
|
|
else if (str.length() > 0)
|
|
|
|
m_deqBufHistory.push_front(str);
|
2005-05-10 09:13:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CConsole::SaveHistory()
|
|
|
|
{
|
2007-12-20 21:21:45 +01:00
|
|
|
WriteBuffer buffer;
|
|
|
|
const int linesToSkip = (int)m_deqBufHistory.size() - m_MaxHistoryLines;
|
2008-08-11 06:18:10 +02:00
|
|
|
std::deque<std::wstring>::reverse_iterator it = m_deqBufHistory.rbegin();
|
2007-12-20 21:21:45 +01:00
|
|
|
if(linesToSkip > 0)
|
|
|
|
std::advance(it, linesToSkip);
|
|
|
|
for (; it != m_deqBufHistory.rend(); ++it)
|
2005-05-10 09:13:25 +02:00
|
|
|
{
|
2007-12-20 21:21:45 +01:00
|
|
|
CStr8 line = CStrW(*it).ToUTF8();
|
|
|
|
buffer.Append(line.data(), line.length());
|
|
|
|
static const char newline = '\n';
|
|
|
|
buffer.Append(&newline, 1);
|
2005-05-10 09:13:25 +02:00
|
|
|
}
|
2007-12-20 21:21:45 +01:00
|
|
|
g_VFS->CreateFile(m_sHistoryFile, buffer.Data(), buffer.Size());
|
2005-05-10 09:13:25 +02:00
|
|
|
}
|
|
|
|
|
2012-02-06 23:47:35 +01:00
|
|
|
static bool isUnprintableChar(SDL_Keysym key)
|
2006-03-15 20:19:03 +01:00
|
|
|
{
|
2015-12-15 09:53:24 +01:00
|
|
|
switch (key.sym)
|
|
|
|
{
|
2015-12-16 16:36:56 +01:00
|
|
|
// We want to allow some, which are handled specially
|
|
|
|
case SDLK_RETURN: case SDLK_TAB:
|
|
|
|
case SDLK_BACKSPACE: case SDLK_DELETE:
|
|
|
|
case SDLK_HOME: case SDLK_END:
|
|
|
|
case SDLK_LEFT: case SDLK_RIGHT:
|
|
|
|
case SDLK_UP: case SDLK_DOWN:
|
|
|
|
case SDLK_PAGEUP: case SDLK_PAGEDOWN:
|
2021-04-02 16:18:20 +02:00
|
|
|
return true;
|
2015-12-16 16:36:56 +01:00
|
|
|
|
|
|
|
// Ignore the others
|
|
|
|
default:
|
2021-04-02 16:18:20 +02:00
|
|
|
return false;
|
2015-12-15 09:53:24 +01:00
|
|
|
}
|
2006-03-15 20:19:03 +01:00
|
|
|
}
|
|
|
|
|
2006-08-26 23:52:18 +02:00
|
|
|
InReaction conInputHandler(const SDL_Event_* ev)
|
2004-06-02 22:40:07 +02:00
|
|
|
{
|
2019-09-15 14:16:28 +02:00
|
|
|
if (!g_Console)
|
|
|
|
return IN_PASS;
|
|
|
|
|
2020-05-26 23:47:03 +02:00
|
|
|
if (static_cast<int>(ev->ev.type) == SDL_HOTKEYPRESS)
|
2004-07-13 23:09:55 +02:00
|
|
|
{
|
2010-10-23 04:37:00 +02:00
|
|
|
std::string hotkey = static_cast<const char*>(ev->ev.user.data1);
|
|
|
|
|
2011-02-20 21:50:26 +01:00
|
|
|
if (hotkey == "console.toggle")
|
2004-07-21 18:34:07 +02:00
|
|
|
{
|
2021-04-03 22:12:40 +02:00
|
|
|
ResetActiveHotkeys();
|
2004-07-21 18:34:07 +02:00
|
|
|
g_Console->ToggleVisible();
|
2006-03-15 20:19:03 +01:00
|
|
|
return IN_HANDLED;
|
2004-07-21 18:34:07 +02:00
|
|
|
}
|
2011-06-25 02:04:41 +02:00
|
|
|
else if (g_Console->IsActive() && hotkey == "copy")
|
2004-08-03 01:14:54 +02:00
|
|
|
{
|
2020-05-05 13:18:00 +02:00
|
|
|
std::string text = utf8_from_wstring(g_Console->GetBuffer());
|
|
|
|
SDL_SetClipboardText(text.c_str());
|
2006-03-15 20:19:03 +01:00
|
|
|
return IN_HANDLED;
|
2004-08-03 01:14:54 +02:00
|
|
|
}
|
2011-06-25 02:04:41 +02:00
|
|
|
else if (g_Console->IsActive() && hotkey == "paste")
|
2004-08-03 01:14:54 +02:00
|
|
|
{
|
2020-05-05 13:18:00 +02:00
|
|
|
char* utf8_text = SDL_GetClipboardText();
|
|
|
|
if (!utf8_text)
|
|
|
|
return IN_HANDLED;
|
|
|
|
|
|
|
|
std::wstring text = wstring_from_utf8(utf8_text);
|
|
|
|
SDL_free(utf8_text);
|
|
|
|
|
|
|
|
for (wchar_t c : text)
|
|
|
|
g_Console->InsertChar(0, c);
|
2004-08-03 01:14:54 +02:00
|
|
|
|
2006-03-15 20:19:03 +01:00
|
|
|
return IN_HANDLED;
|
2004-08-03 01:14:54 +02:00
|
|
|
}
|
2004-07-13 23:09:55 +02:00
|
|
|
}
|
|
|
|
|
2011-02-20 21:50:26 +01:00
|
|
|
if (!g_Console->IsActive())
|
2005-10-20 19:44:56 +02:00
|
|
|
return IN_PASS;
|
2004-07-21 18:34:07 +02:00
|
|
|
|
2014-09-20 14:12:35 +02:00
|
|
|
// In SDL2, we no longer get Unicode wchars via SDL_Keysym
|
|
|
|
// we use text input events instead and they provide UTF-8 chars
|
2021-04-02 16:18:20 +02:00
|
|
|
if (ev->ev.type == SDL_TEXTINPUT)
|
2014-09-20 14:12:35 +02:00
|
|
|
{
|
|
|
|
// TODO: this could be more efficient with an interface to insert UTF-8 strings directly
|
|
|
|
std::wstring wstr = wstring_from_utf8(ev->ev.text.text);
|
|
|
|
for (size_t i = 0; i < wstr.length(); ++i)
|
|
|
|
g_Console->InsertChar(0, wstr[i]);
|
|
|
|
return IN_HANDLED;
|
|
|
|
}
|
2014-09-22 21:00:20 +02:00
|
|
|
// TODO: text editing events for IME support
|
2014-09-20 14:12:35 +02:00
|
|
|
|
2021-04-02 16:18:20 +02:00
|
|
|
if (ev->ev.type != SDL_KEYDOWN && ev->ev.type != SDL_KEYUP)
|
2005-10-20 19:44:56 +02:00
|
|
|
return IN_PASS;
|
2004-07-13 23:09:55 +02:00
|
|
|
|
2012-02-06 23:47:35 +01:00
|
|
|
int sym = ev->ev.key.keysym.sym;
|
2011-02-20 21:50:26 +01:00
|
|
|
|
2021-04-02 16:18:20 +02:00
|
|
|
// Stop unprintable characters (ctrl+, alt+ and escape).
|
|
|
|
if (ev->ev.type == SDL_KEYDOWN && isUnprintableChar(ev->ev.key.keysym) &&
|
2011-02-20 21:50:26 +01:00
|
|
|
!HotkeyIsPressed("console.toggle"))
|
|
|
|
{
|
2014-09-20 14:12:35 +02:00
|
|
|
g_Console->InsertChar(sym, 0);
|
2011-02-20 21:50:26 +01:00
|
|
|
return IN_HANDLED;
|
|
|
|
}
|
2004-07-13 23:09:55 +02:00
|
|
|
|
2021-04-02 16:18:20 +02:00
|
|
|
// We have a probably printable key - we should return HANDLED so it can't trigger hotkeys.
|
|
|
|
// However, if Ctrl/Meta modifiers are active (or it's escape), just pass it through instead,
|
|
|
|
// assuming that we are indeed trying to trigger hotkeys (e.g. copy/paste).
|
|
|
|
// Also ignore the key if we are trying to toggle the console off.
|
|
|
|
// See also similar logic in CInput.cpp
|
|
|
|
if (EventWillFireHotkey(ev, "console.toggle") ||
|
|
|
|
g_scancodes[SDL_SCANCODE_LCTRL] || g_scancodes[SDL_SCANCODE_RCTRL] ||
|
|
|
|
g_scancodes[SDL_SCANCODE_LGUI] || g_scancodes[SDL_SCANCODE_RGUI])
|
|
|
|
return IN_PASS;
|
|
|
|
|
|
|
|
return IN_HANDLED;
|
2004-06-02 22:40:07 +02:00
|
|
|
}
|