1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 11:13:19 +01:00

Improve TTY output

Use atomic variable to sync TTY size
Implement console_putc (liblv2)
Write plaintext instead of HTML
Slightly improve performance
Fix random line breaks in TTY
This commit is contained in:
Nekotekina 2018-03-01 13:48:42 +03:00
parent 445b7c0758
commit f056b2f4ab
6 changed files with 37 additions and 58 deletions

View File

@ -6,14 +6,13 @@
#include "Emu/Cell/lv2/sys_interrupt.h"
#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_ss.h"
#include "Emu/Cell/lv2/sys_tty.h"
#include "sysPrxForUser.h"
logs::channel sysPrxForUser("sysPrxForUser");
extern u64 get_system_time();
extern fs::file g_tty;
vm::gvar<s32> sys_prx_version; // ???
vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
@ -97,20 +96,16 @@ s32 console_getc()
fmt::throw_exception("Unimplemented" HERE);
}
s32 console_putc()
void console_putc(char ch)
{
fmt::throw_exception("Unimplemented" HERE);
sysPrxForUser.trace("console_putc(ch=0x%x)", ch);
sys_tty_write(0, vm::var<char>(ch), 1, vm::var<u32>{});
}
s32 console_write(vm::ptr<char> data, u32 len)
error_code console_write(vm::ptr<char> data, u32 len)
{
sysPrxForUser.warning("console_write(data=*0x%x, len=%d)", data, len);
if (g_tty)
{
g_tty.write(data.get_ptr(), len);
}
sysPrxForUser.trace("console_write(data=*0x%x, len=%d)", data, len);
sys_tty_write(0, data, len, vm::var<u32>{});
return CELL_OK;
}

View File

@ -1,15 +1,12 @@
#include "stdafx.h"
#include "Emu/Cell/lv2/sys_tty.h"
#include "Emu/Cell/PPUModule.h"
#include "Utilities/cfmt.h"
#include <string.h>
#include <ctype.h>
extern logs::channel sysPrxForUser;
extern fs::file g_tty;
// cfmt implementation (TODO)
using qsortcmp = s32(vm::cptr<void> e1, vm::cptr<void> e2);
@ -420,10 +417,9 @@ s32 _sys_printf(ppu_thread& ppu, vm::cptr<char> fmt, ppu_va_args_t va_args)
{
sysPrxForUser.warning("_sys_printf(fmt=%s, ...)", fmt);
if (g_tty)
{
g_tty.write(ps3_fmt(ppu, fmt, va_args.count));
}
const auto buf = vm::make_str(ps3_fmt(ppu, fmt, va_args.count));
sys_tty_write(0, buf, buf.get_count() - 1, vm::var<u32>{});
return CELL_OK;
}

View File

@ -1,11 +1,10 @@
#include "stdafx.h"
#include "sys_tty.h"
logs::channel sys_tty("sys_tty");
extern fs::file g_tty;
extern atomic_t<s64> g_tty_size;
error_code sys_tty_read(s32 ch, vm::ptr<char> buf, u32 len, vm::ptr<u32> preadlen)
{
@ -28,7 +27,10 @@ error_code sys_tty_write(s32 ch, vm::cptr<char> buf, u32 len, vm::ptr<u32> pwrit
if (written_len > 0 && g_tty)
{
// Lock size by making it negative
g_tty_size -= (1ll << 48);
g_tty.write(buf.get_ptr(), len);
g_tty_size += (1ll << 48) + len;
}
if (!pwritelen)

View File

@ -44,6 +44,7 @@ extern std::shared_ptr<struct lv2_prx> ppu_load_prx(const ppu_prx_object&, const
extern void network_thread_init();
fs::file g_tty;
atomic_t<s64> g_tty_size{0};
template <>
void fmt_class_string<mouse_handler>::format(std::string& out, u64 arg)

View File

@ -9,6 +9,8 @@
#include <QScrollBar>
#include <QTabBar>
extern atomic_t<s64> g_tty_size;
constexpr auto qstr = QString::fromStdString;
struct gui_listener : logs::listener
@ -193,7 +195,7 @@ void log_frame::CreateAndConnectActions()
auto l_initAct = [this](QAction* act, logs::level logLevel)
{
act->setCheckable(true);
// This sets the log level properly when the action is triggered.
connect(act, &QAction::triggered, [this, logLevel]()
{
@ -302,47 +304,30 @@ void log_frame::RepaintTextColors()
void log_frame::UpdateUI()
{
std::vector<char> buf(4096);
// Get UTF-8 string from file
auto get_utf8 = [&](const fs::file& file, u64 size) -> QString
{
size = file.read(buf.data(), size);
for (u64 i = 0; i < size; i++)
{
// Get UTF-8 sequence length (no real validation performed)
const u64 tail =
(buf[i] & 0xF0) == 0xF0 ? 3 :
(buf[i] & 0xE0) == 0xE0 ? 2 :
(buf[i] & 0xC0) == 0xC0 ? 1 : 0;
if (i + tail >= size)
{ // Copying is expensive-- O(i)-- but I suspect this corruption will be exceptionally unlikely.
file.seek(i - size, fs::seek_cur);
std::vector<char> sub(&buf[0], &buf[i]);
return QString(sub.data());
}
}
return QString(buf.data());
};
const auto start = steady_clock::now();
// Check TTY logs
while (const u64 size = std::min<u64>(buf.size(), m_tty_file.size() - m_tty_file.pos()))
while (const u64 size = std::max<s64>(0, g_tty_size.load() - m_tty_file.pos()))
{
QString text = get_utf8(m_tty_file, size);
std::string buf;
buf.resize(size);
buf.resize(m_tty_file.read(&buf.front(), buf.size()));
// Hackily used the state of the check.. be better if I actually stored this value.
if (m_TTYAct->isChecked())
if (buf.find_first_of('\0') != -1)
{
text.chop(1); // remove newline since Qt automatically adds a newline.
m_tty->append(text);
m_tty_file.seek(s64{0} - buf.size(), fs::seek_mode::seek_cur);
break;
}
if (buf.size() && m_TTYAct->isChecked())
{
QTextCursor text_cursor{m_tty->document()};
text_cursor.movePosition(QTextCursor::End);
text_cursor.insertText(qstr(buf));
}
// Limit processing time
if (steady_clock::now() >= start + 4ms || text.isEmpty()) break;
if (steady_clock::now() >= start + 4ms || buf.empty()) break;
}
// Check main logs

View File

@ -48,8 +48,8 @@ private:
QList<QColor> m_color;
QColor m_color_stack;
QTextEdit *m_log;
QTextEdit *m_tty;
QTextEdit* m_log;
QTextEdit* m_tty;
QString m_old_text;
ullong m_log_counter;
bool m_stack_log;