Changeset View
Changeset View
Standalone View
Standalone View
source/ps/CConsole.cpp
Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
CConsole::CConsole() | CConsole::CConsole() | ||||
{ | { | ||||
m_bToggle = false; | m_bToggle = false; | ||||
m_bVisible = false; | m_bVisible = false; | ||||
m_fVisibleFrac = 0.0f; | m_fVisibleFrac = 0.0f; | ||||
m_szBuffer = new wchar_t[CONSOLE_BUFFER_SIZE]; | m_szBuffer = new char[CONSOLE_BUFFER_SIZE]; | ||||
FlushBuffer(); | FlushBuffer(); | ||||
m_iMsgHistPos = 1; | m_iMsgHistPos = 1; | ||||
m_charsPerPage = 0; | m_charsPerPage = 0; | ||||
m_prevTime = 0.0; | m_prevTime = 0.0; | ||||
m_bCursorVisState = true; | m_bCursorVisState = true; | ||||
m_cursorBlinkRate = 0.5; | m_cursorBlinkRate = 0.5; | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
void CConsole::SetCursorBlinkRate(double rate) | void CConsole::SetCursorBlinkRate(double rate) | ||||
{ | { | ||||
m_cursorBlinkRate = rate; | m_cursorBlinkRate = rate; | ||||
} | } | ||||
void CConsole::FlushBuffer() | void CConsole::FlushBuffer() | ||||
{ | { | ||||
// Clear the buffer and set the cursor and length to 0 | // Clear the buffer and set the cursor and length to 0 | ||||
memset(m_szBuffer, '\0', sizeof(wchar_t) * CONSOLE_BUFFER_SIZE); | memset(m_szBuffer, '\0', sizeof(char) * CONSOLE_BUFFER_SIZE); | ||||
m_iBufferPos = m_iBufferLength = 0; | m_iBufferPos = m_iBufferLength = 0; | ||||
} | } | ||||
void CConsole::Update(const float deltaRealTime) | void CConsole::Update(const float deltaRealTime) | ||||
{ | { | ||||
if(m_bToggle) | if(m_bToggle) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | void CConsole::DrawWindow(CShaderProgramPtr& shader) | ||||
} | } | ||||
} | } | ||||
void CConsole::DrawHistory(CTextRenderer& textRenderer) | void CConsole::DrawHistory(CTextRenderer& textRenderer) | ||||
{ | { | ||||
int i = 1; | int i = 1; | ||||
std::deque<std::wstring>::iterator Iter; //History iterator | std::deque<std::string>::iterator Iter; //History iterator | ||||
std::lock_guard<std::mutex> lock(m_Mutex); // needed for safe access to m_deqMsgHistory | std::lock_guard<std::mutex> lock(m_Mutex); // needed for safe access to m_deqMsgHistory | ||||
textRenderer.Color(1.0f, 1.0f, 1.0f); | textRenderer.Color(1.0f, 1.0f, 1.0f); | ||||
for (Iter = m_deqMsgHistory.begin(); | for (Iter = m_deqMsgHistory.begin(); | ||||
Iter != m_deqMsgHistory.end() | Iter != m_deqMsgHistory.end() | ||||
&& (((i - m_iMsgHistPos + 1) * m_iFontHeight) < m_fHeight); | && (((i - m_iMsgHistPos + 1) * m_iFontHeight) < m_fHeight); | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | if(m_bCursorVisState) | ||||
// Revert to the standard text color | // Revert to the standard text color | ||||
textRenderer.Color(1.0f, 1.0f, 1.0f); | textRenderer.Color(1.0f, 1.0f, 1.0f); | ||||
} | } | ||||
} | } | ||||
//Inserts a character into the buffer. | //Inserts a character into the buffer. | ||||
void CConsole::InsertChar(const int szChar, const wchar_t cooked) | void CConsole::InsertChar(const int szChar, const char cooked) | ||||
{ | { | ||||
static int iHistoryPos = -1; | static int iHistoryPos = -1; | ||||
if (!m_bVisible) return; | if (!m_bVisible) return; | ||||
switch (szChar) | switch (szChar) | ||||
{ | { | ||||
case SDLK_RETURN: | case SDLK_RETURN: | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void CConsole::InsertMessage(const std::string& message) | void CConsole::InsertMessage(const std::string& message) | ||||
{ | { | ||||
// (TODO: this text-wrapping is rubbish since we now use variable-width fonts) | // (TODO: this text-wrapping is rubbish since we now use variable-width fonts) | ||||
//Insert newlines to wraparound text where needed | //Insert newlines to wraparound text where needed | ||||
std::wstring wrapAround = wstring_from_utf8(message.c_str()); | std::string wrapAround = message; | ||||
std::wstring newline(L"\n"); | std::string newline("\n"); | ||||
size_t oldNewline=0; | size_t oldNewline=0; | ||||
size_t distance; | size_t distance; | ||||
//make sure everything has been initialized | //make sure everything has been initialized | ||||
if ( m_charsPerPage != 0 ) | if ( m_charsPerPage != 0 ) | ||||
{ | { | ||||
while ( oldNewline+m_charsPerPage < wrapAround.length() ) | while ( oldNewline+m_charsPerPage < wrapAround.length() ) | ||||
{ | { | ||||
Show All 18 Lines | while ( (distance = wrapAround.find(newline, oldNewline)) != wrapAround.npos) | ||||
distance -= oldNewline; | distance -= oldNewline; | ||||
m_deqMsgHistory.push_front(wrapAround.substr(oldNewline, distance)); | m_deqMsgHistory.push_front(wrapAround.substr(oldNewline, distance)); | ||||
oldNewline += distance+1; | oldNewline += distance+1; | ||||
} | } | ||||
m_deqMsgHistory.push_front(wrapAround.substr(oldNewline)); | m_deqMsgHistory.push_front(wrapAround.substr(oldNewline)); | ||||
} | } | ||||
} | } | ||||
const wchar_t* CConsole::GetBuffer() | const char* CConsole::GetBuffer() | ||||
{ | { | ||||
m_szBuffer[m_iBufferLength] = 0; | m_szBuffer[m_iBufferLength] = 0; | ||||
return( m_szBuffer ); | return( m_szBuffer ); | ||||
} | } | ||||
void CConsole::SetBuffer(const wchar_t* szMessage) | void CConsole::SetBuffer(const char* szMessage) | ||||
{ | { | ||||
int oldBufferPos = m_iBufferPos; // remember since FlushBuffer will set it to 0 | int oldBufferPos = m_iBufferPos; // remember since FlushBuffer will set it to 0 | ||||
FlushBuffer(); | FlushBuffer(); | ||||
wcsncpy(m_szBuffer, szMessage, CONSOLE_BUFFER_SIZE); | strncpy(m_szBuffer, szMessage, CONSOLE_BUFFER_SIZE); | ||||
m_szBuffer[CONSOLE_BUFFER_SIZE-1] = 0; | m_szBuffer[CONSOLE_BUFFER_SIZE-1] = 0; | ||||
m_iBufferLength = static_cast<int>(wcslen(m_szBuffer)); | m_iBufferLength = static_cast<int>(strlen(m_szBuffer)); | ||||
m_iBufferPos = std::min(oldBufferPos, m_iBufferLength); | m_iBufferPos = std::min(oldBufferPos, m_iBufferLength); | ||||
} | } | ||||
void CConsole::UseHistoryFile(const VfsPath& filename, int max_history_lines) | void CConsole::UseHistoryFile(const VfsPath& filename, int max_history_lines) | ||||
{ | { | ||||
m_MaxHistoryLines = max_history_lines; | m_MaxHistoryLines = max_history_lines; | ||||
m_sHistoryFile = filename; | m_sHistoryFile = filename; | ||||
LoadHistory(); | LoadHistory(); | ||||
} | } | ||||
void CConsole::ProcessBuffer(const wchar_t* szLine) | void CConsole::ProcessBuffer(const char* szLine) | ||||
{ | { | ||||
if (!szLine || wcslen(szLine) <= 0) | if (!szLine || strlen(szLine) <= 0) | ||||
return; | return; | ||||
ENSURE(wcslen(szLine) < CONSOLE_BUFFER_SIZE); | ENSURE(strlen(szLine) < CONSOLE_BUFFER_SIZE); | ||||
m_deqBufHistory.push_front(szLine); | m_deqBufHistory.push_front(szLine); | ||||
SaveHistory(); // Do this each line for the moment; if a script causes | SaveHistory(); // Do this each line for the moment; if a script causes | ||||
// a crash it's a useful record. | // a crash it's a useful record. | ||||
// Process it as JavaScript | // Process it as JavaScript | ||||
shared_ptr<ScriptInterface> pScriptInterface = g_GUI->GetActiveGUI()->GetScriptInterface(); | shared_ptr<ScriptInterface> pScriptInterface = g_GUI->GetActiveGUI()->GetScriptInterface(); | ||||
ScriptRequest rq(*pScriptInterface); | ScriptRequest rq(*pScriptInterface); | ||||
Show All 12 Lines | void CConsole::LoadHistory() | ||||
// do this before LoadFile to avoid an error message if file not found. | // do this before LoadFile to avoid an error message if file not found. | ||||
if (!VfsFileExists(m_sHistoryFile)) | if (!VfsFileExists(m_sHistoryFile)) | ||||
return; | return; | ||||
shared_ptr<u8> buf; size_t buflen; | shared_ptr<u8> buf; size_t buflen; | ||||
if (g_VFS->LoadFile(m_sHistoryFile, buf, buflen) < 0) | if (g_VFS->LoadFile(m_sHistoryFile, buf, buflen) < 0) | ||||
return; | return; | ||||
CStr bytes ((char*)buf.get(), buflen); | CStr str ((char*)buf.get(), buflen); | ||||
CStrW str (bytes.FromUTF8()); | |||||
size_t pos = 0; | size_t pos = 0; | ||||
while (pos != CStrW::npos) | while (pos != CStr::npos) | ||||
{ | { | ||||
pos = str.find('\n'); | pos = str.find('\n'); | ||||
if (pos != CStrW::npos) | if (pos != CStr::npos) | ||||
{ | { | ||||
if (pos > 0) | if (pos > 0) | ||||
m_deqBufHistory.push_front(str.Left(str[pos-1] == '\r' ? pos - 1 : pos)); | m_deqBufHistory.push_front(str.Left(str[pos-1] == '\r' ? pos - 1 : pos)); | ||||
str = str.substr(pos + 1); | str = str.substr(pos + 1); | ||||
} | } | ||||
else if (str.length() > 0) | else if (str.length() > 0) | ||||
m_deqBufHistory.push_front(str); | m_deqBufHistory.push_front(str); | ||||
} | } | ||||
} | } | ||||
void CConsole::SaveHistory() | void CConsole::SaveHistory() | ||||
{ | { | ||||
WriteBuffer buffer; | WriteBuffer buffer; | ||||
const int linesToSkip = (int)m_deqBufHistory.size() - m_MaxHistoryLines; | const int linesToSkip = (int)m_deqBufHistory.size() - m_MaxHistoryLines; | ||||
std::deque<std::wstring>::reverse_iterator it = m_deqBufHistory.rbegin(); | std::deque<std::string>::reverse_iterator it = m_deqBufHistory.rbegin(); | ||||
if(linesToSkip > 0) | if(linesToSkip > 0) | ||||
std::advance(it, linesToSkip); | std::advance(it, linesToSkip); | ||||
for (; it != m_deqBufHistory.rend(); ++it) | for (; it != m_deqBufHistory.rend(); ++it) | ||||
{ | { | ||||
CStr8 line = CStrW(*it).ToUTF8(); | CStr8 line = *it; | ||||
buffer.Append(line.data(), line.length()); | buffer.Append(line.data(), line.length()); | ||||
static const char newline = '\n'; | static const char newline = '\n'; | ||||
buffer.Append(&newline, 1); | buffer.Append(&newline, 1); | ||||
} | } | ||||
g_VFS->CreateFile(m_sHistoryFile, buffer.Data(), buffer.Size()); | g_VFS->CreateFile(m_sHistoryFile, buffer.Data(), buffer.Size()); | ||||
} | } | ||||
static bool isUnprintableChar(SDL_Keysym key) | static bool isUnprintableChar(SDL_Keysym key) | ||||
Show All 26 Lines | if (static_cast<int>(ev->ev.type) == SDL_HOTKEYPRESS) | ||||
if (hotkey == "console.toggle") | if (hotkey == "console.toggle") | ||||
{ | { | ||||
g_Console->ToggleVisible(); | g_Console->ToggleVisible(); | ||||
return IN_HANDLED; | return IN_HANDLED; | ||||
} | } | ||||
else if (g_Console->IsActive() && hotkey == "copy") | else if (g_Console->IsActive() && hotkey == "copy") | ||||
{ | { | ||||
std::string text = utf8_from_wstring(g_Console->GetBuffer()); | SDL_SetClipboardText(g_Console->GetBuffer()); | ||||
SDL_SetClipboardText(text.c_str()); | |||||
return IN_HANDLED; | return IN_HANDLED; | ||||
} | } | ||||
else if (g_Console->IsActive() && hotkey == "paste") | else if (g_Console->IsActive() && hotkey == "paste") | ||||
{ | { | ||||
char* utf8_text = SDL_GetClipboardText(); | char* utf8_text = SDL_GetClipboardText(); | ||||
if (!utf8_text) | if (!utf8_text) | ||||
return IN_HANDLED; | return IN_HANDLED; | ||||
std::wstring text = wstring_from_utf8(utf8_text); | std::string text(utf8_text); | ||||
SDL_free(utf8_text); | SDL_free(utf8_text); | ||||
for (wchar_t c : text) | for (char c : text) | ||||
g_Console->InsertChar(0, c); | g_Console->InsertChar(0, c); | ||||
return IN_HANDLED; | return IN_HANDLED; | ||||
} | } | ||||
} | } | ||||
if (!g_Console->IsActive()) | if (!g_Console->IsActive()) | ||||
return IN_PASS; | return IN_PASS; | ||||
// In SDL2, we no longer get Unicode wchars via SDL_Keysym | |||||
// we use text input events instead and they provide UTF-8 chars | |||||
if (ev->ev.type == SDL_TEXTINPUT && !HotkeyIsPressed("console.toggle")) | if (ev->ev.type == SDL_TEXTINPUT && !HotkeyIsPressed("console.toggle")) | ||||
{ | { | ||||
// TODO: this could be more efficient with an interface to insert UTF-8 strings directly | CStr str(ev->ev.text.text); | ||||
std::wstring wstr = wstring_from_utf8(ev->ev.text.text); | for (size_t i = 0; i < str.length(); ++i) | ||||
for (size_t i = 0; i < wstr.length(); ++i) | g_Console->InsertChar(0, str[i]); | ||||
g_Console->InsertChar(0, wstr[i]); | |||||
return IN_HANDLED; | return IN_HANDLED; | ||||
} | } | ||||
// TODO: text editing events for IME support | // TODO: text editing events for IME support | ||||
if (ev->ev.type != SDL_KEYDOWN) | if (ev->ev.type != SDL_KEYDOWN) | ||||
return IN_PASS; | return IN_PASS; | ||||
int sym = ev->ev.key.keysym.sym; | int sym = ev->ev.key.keysym.sym; | ||||
Show All 12 Lines |
Wildfire Games · Phabricator