mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 01:08:39 +12: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:
parent
445b7c0758
commit
f056b2f4ab
6 changed files with 37 additions and 58 deletions
|
@ -6,14 +6,13 @@
|
||||||
#include "Emu/Cell/lv2/sys_interrupt.h"
|
#include "Emu/Cell/lv2/sys_interrupt.h"
|
||||||
#include "Emu/Cell/lv2/sys_process.h"
|
#include "Emu/Cell/lv2/sys_process.h"
|
||||||
#include "Emu/Cell/lv2/sys_ss.h"
|
#include "Emu/Cell/lv2/sys_ss.h"
|
||||||
|
#include "Emu/Cell/lv2/sys_tty.h"
|
||||||
#include "sysPrxForUser.h"
|
#include "sysPrxForUser.h"
|
||||||
|
|
||||||
logs::channel sysPrxForUser("sysPrxForUser");
|
logs::channel sysPrxForUser("sysPrxForUser");
|
||||||
|
|
||||||
extern u64 get_system_time();
|
extern u64 get_system_time();
|
||||||
|
|
||||||
extern fs::file g_tty;
|
|
||||||
|
|
||||||
vm::gvar<s32> sys_prx_version; // ???
|
vm::gvar<s32> sys_prx_version; // ???
|
||||||
vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
|
vm::gvar<vm::ptr<void()>> g_ppu_atexitspawn;
|
||||||
vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
|
vm::gvar<vm::ptr<void()>> g_ppu_at_Exitspawn;
|
||||||
|
@ -97,20 +96,16 @@ s32 console_getc()
|
||||||
fmt::throw_exception("Unimplemented" HERE);
|
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);
|
sysPrxForUser.trace("console_write(data=*0x%x, len=%d)", data, len);
|
||||||
|
sys_tty_write(0, data, len, vm::var<u32>{});
|
||||||
if (g_tty)
|
|
||||||
{
|
|
||||||
g_tty.write(data.get_ptr(), len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "Emu/Cell/lv2/sys_tty.h"
|
||||||
#include "Emu/Cell/PPUModule.h"
|
#include "Emu/Cell/PPUModule.h"
|
||||||
#include "Utilities/cfmt.h"
|
#include "Utilities/cfmt.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern logs::channel sysPrxForUser;
|
extern logs::channel sysPrxForUser;
|
||||||
|
|
||||||
extern fs::file g_tty;
|
|
||||||
|
|
||||||
// cfmt implementation (TODO)
|
// cfmt implementation (TODO)
|
||||||
|
|
||||||
using qsortcmp = s32(vm::cptr<void> e1, vm::cptr<void> e2);
|
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);
|
sysPrxForUser.warning("_sys_printf(fmt=%s, ...)", fmt);
|
||||||
|
|
||||||
if (g_tty)
|
const auto buf = vm::make_str(ps3_fmt(ppu, fmt, va_args.count));
|
||||||
{
|
|
||||||
g_tty.write(ps3_fmt(ppu, fmt, va_args.count));
|
sys_tty_write(0, buf, buf.get_count() - 1, vm::var<u32>{});
|
||||||
}
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "sys_tty.h"
|
#include "sys_tty.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
logs::channel sys_tty("sys_tty");
|
logs::channel sys_tty("sys_tty");
|
||||||
|
|
||||||
extern fs::file g_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)
|
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)
|
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.write(buf.get_ptr(), len);
|
||||||
|
g_tty_size += (1ll << 48) + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pwritelen)
|
if (!pwritelen)
|
||||||
|
|
|
@ -44,6 +44,7 @@ extern std::shared_ptr<struct lv2_prx> ppu_load_prx(const ppu_prx_object&, const
|
||||||
extern void network_thread_init();
|
extern void network_thread_init();
|
||||||
|
|
||||||
fs::file g_tty;
|
fs::file g_tty;
|
||||||
|
atomic_t<s64> g_tty_size{0};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void fmt_class_string<mouse_handler>::format(std::string& out, u64 arg)
|
void fmt_class_string<mouse_handler>::format(std::string& out, u64 arg)
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QTabBar>
|
#include <QTabBar>
|
||||||
|
|
||||||
|
extern atomic_t<s64> g_tty_size;
|
||||||
|
|
||||||
constexpr auto qstr = QString::fromStdString;
|
constexpr auto qstr = QString::fromStdString;
|
||||||
|
|
||||||
struct gui_listener : logs::listener
|
struct gui_listener : logs::listener
|
||||||
|
@ -302,47 +304,30 @@ void log_frame::RepaintTextColors()
|
||||||
|
|
||||||
void log_frame::UpdateUI()
|
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();
|
const auto start = steady_clock::now();
|
||||||
|
|
||||||
// Check TTY logs
|
// Check TTY logs
|
||||||
|
while (const u64 size = std::max<s64>(0, g_tty_size.load() - m_tty_file.pos()))
|
||||||
while (const u64 size = std::min<u64>(buf.size(), m_tty_file.size() - 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 (buf.find_first_of('\0') != -1)
|
||||||
if (m_TTYAct->isChecked())
|
|
||||||
{
|
{
|
||||||
text.chop(1); // remove newline since Qt automatically adds a newline.
|
m_tty_file.seek(s64{0} - buf.size(), fs::seek_mode::seek_cur);
|
||||||
m_tty->append(text);
|
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
|
// Limit processing time
|
||||||
if (steady_clock::now() >= start + 4ms || text.isEmpty()) break;
|
if (steady_clock::now() >= start + 4ms || buf.empty()) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check main logs
|
// Check main logs
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue