Compare commits

...

4 Commits

Author SHA1 Message Date
Mrlinkwii
976d4a8dbb Revert "CI/Windows: Disable Qt's PCRE2 JIT"
This reverts commit 1ec4c248fb.
2026-01-10 15:47:32 -05:00
Ty
40b1b9b717 Qt: Add an EE SIO RX input textbox to the log window 2026-01-10 15:46:59 -05:00
Ty
a3b817cb1f Core: Use deque for EE SIO RX/TX FIFOs 2026-01-10 15:46:59 -05:00
SternXD
83e152cd21 GameDB: Add post-bloom alignment and native scaling for Urban Reign 2026-01-10 17:18:43 +01:00
11 changed files with 182 additions and 54 deletions

View File

@@ -201,10 +201,6 @@ echo Building Qt base...
rmdir /S /Q "qtbase-everywhere-src-%QT%"
%SEVENZIP% x "qtbase-everywhere-src-%QT%.zip" || goto error
cd "qtbase-everywhere-src-%QT%" || goto error
rem Disable the PCRE2 JIT, it doesn't properly verify AVX2 support.
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-disable-pcre2-jit.patch" || goto error
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error

View File

@@ -1,35 +0,0 @@
--- qtbase/src/3rdparty/pcre2/CMakeLists.txt 2024-03-19 08:46:43.000000000 -0700
+++ qtbase/src/3rdparty/pcre2/CMakeLists.txt 2024-06-06 21:52:20.539619500 -0700
@@ -41,6 +41,7 @@
src/pcre2_xclass.c
DEFINES
HAVE_CONFIG_H
+ PCRE2_DISABLE_JIT
PUBLIC_DEFINES
PCRE2_CODE_UNIT_WIDTH=16
PUBLIC_INCLUDE_DIRECTORIES
@@ -52,23 +53,8 @@
## Scopes:
#####################################################################
-qt_internal_extend_target(BundledPcre2 CONDITION QNX OR UIKIT
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
-qt_internal_extend_target(BundledPcre2 CONDITION (TEST_architecture_arch STREQUAL "arm") AND WIN32
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
-qt_internal_extend_target(BundledPcre2 CONDITION (TEST_architecture_arch STREQUAL "arm64") AND WIN32
- DEFINES
- PCRE2_DISABLE_JIT
-)
-
if (APPLE)
- target_compile_options(BundledPcre2 PRIVATE "SHELL:-Xarch_arm64 -DPCRE2_DISABLE_JIT")
+ target_compile_options(BundledPcre2 PRIVATE "SHELL:-Xarch_arm64")
endif()
qt_internal_extend_target(BundledPcre2 CONDITION WIN32

View File

@@ -2239,6 +2239,8 @@ SCAJ-20152:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCAJ-20153:
name: "コード・エイジ コマンダーズ"
@@ -6229,6 +6231,8 @@ SCES-53688:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCES-53795:
name: "SingStar - '80s"
@@ -7698,6 +7702,8 @@ SCKA-20065:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SCKA-20066:
name: "아이토이 - 플레이 3"
@@ -35952,6 +35958,8 @@ SLPM-60272:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLPM-60273:
name: "絶体絶命都市2 -凍てついた記憶たち- [体験版 Type-B]"
@@ -60340,6 +60348,8 @@ SLPS-25557:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLPS-25558:
name: "ネオジオ バトルコロシアム"
@@ -70360,6 +70370,8 @@ SLUS-21209:
gsHWFixes:
alignSprite: 1 # Fixes vertical lines.
textureInsideRT: 1 # Fixes corruption.
halfPixelOffset: 4 # Aligns post bloom.
nativeScaling: 2 # Fixes post effects.
getSkipCount: "GSC_UrbanReign"
SLUS-21212:
name: "Spartan - Total Warrior"

View File

@@ -5,10 +5,14 @@
#include "MainWindow.h"
#include "QtHost.h"
#include "SettingWidgetBinder.h"
#include "VMManager.h"
#include <QtCore/QLatin1StringView>
#include <QtCore/QUtf8StringView>
#include <QtGui/QIcon>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QScrollBar>
@@ -46,6 +50,12 @@ void LogWindow::updateSettings()
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !Host::InNoGUIMode();
const bool attach_to_main = Host::GetBaseBoolSettingValue("Logging", "AttachLogWindowToMainWindow", true);
const bool curr_enabled = Log::IsHostOutputEnabled();
const bool input_enabled = Host::GetBaseBoolSettingValue("Logging", "ShowEESIOInput");
if(g_log_window && g_log_window->m_line_input)
{
g_log_window->m_input_widget->setVisible(input_enabled);
}
if (new_enabled == curr_enabled)
{
@@ -171,6 +181,10 @@ void LogWindow::createUi()
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableTimestamps", true);
action = settings_menu->addAction(tr("Show EE SIO &Input"));
action->setCheckable(true);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "ShowEESIOInput", false);
settings_menu->addSeparator();
// TODO: Log Level
@@ -181,6 +195,30 @@ void LogWindow::createUi()
m_text->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
m_text->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_text->setWordWrapMode(QTextOption::WrapAnywhere);
m_text->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_line_input = new QLineEdit(this);
connect(m_line_input, &QLineEdit::returnPressed, this, &LogWindow::onInputEntered);
m_local_echo_checkbox = new QCheckBox(tr("Local Echo"), this);
m_local_echo_checkbox->setChecked(m_local_echo);
connect(m_local_echo_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
{
m_local_echo = state == Qt::CheckState::Checked;
});
m_newline_on_enter_checkbox = new QCheckBox(tr("Newline on send"), this);
m_newline_on_enter_checkbox->setChecked(m_newline_on_enter);
connect(m_newline_on_enter_checkbox, &QCheckBox::checkStateChanged, this, [&](Qt::CheckState state)
{
m_newline_on_enter = state == Qt::CheckState::Checked;
});
m_input_hbox = new QHBoxLayout(this);
m_input_hbox->addWidget(m_line_input, 1);
m_input_hbox->addWidget(m_local_echo_checkbox);
m_input_hbox->addWidget(m_newline_on_enter_checkbox);
m_input_hbox->setSpacing(8);
#if defined(_WIN32)
QFont font("Consolas");
@@ -194,7 +232,19 @@ void LogWindow::createUi()
#endif
m_text->setFont(font);
setCentralWidget(m_text);
QWidget* central_widget = new QWidget(this);
m_input_widget = new QWidget(this);
m_input_widget->setVisible(Host::GetBaseBoolSettingValue("Logging", "ShowEESIOInput"));
m_input_widget->setLayout(m_input_hbox);
QVBoxLayout* vlayout = new QVBoxLayout(central_widget);
vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setSpacing(0);
vlayout->addWidget(m_text);
vlayout->addWidget(m_input_widget);
central_widget->setLayout(vlayout);
setCentralWidget(central_widget);
}
void LogWindow::onClearTriggered()
@@ -361,6 +411,31 @@ void LogWindow::appendMessage(quint32 level, quint32 color, const QString& messa
}
}
void LogWindow::onInputEntered()
{
QString text = m_line_input->text();
if (text.isEmpty() && !m_newline_on_enter)
return;
if(m_newline_on_enter)
text.append('\n');
std::string str = text.toUtf8().toStdString();
if(VMManager::WriteBytesToEESIORXFIFO({reinterpret_cast<const u8*>(str.data()), str.size()}))
{
m_line_input->clear();
if(m_local_echo)
// appendMessage expects a newline to be at the end of the string
appendMessage(0, 0, m_newline_on_enter ? text : (text + '\n') );
QTextCursor cursor(m_text->textCursor());
cursor.movePosition(QTextCursor::End);
m_text->setTextCursor(cursor);
}
}
void LogWindow::saveSize()
{
const int current_width = Host::GetBaseIntSettingValue("UI", "LogWindowWidth", DEFAULT_WIDTH);

View File

@@ -5,6 +5,9 @@
#include "common/Console.h"
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QPlainTextEdit>
@@ -36,6 +39,7 @@ private Q_SLOTS:
void onClearTriggered();
void onSaveTriggered();
void appendMessage(quint32 level, quint32 color, const QString& message);
void onInputEntered();
private:
static constexpr int DEFAULT_WIDTH = 750;
@@ -45,8 +49,15 @@ private:
void restoreSize();
QPlainTextEdit* m_text;
QLineEdit* m_line_input;
QMenu* m_level_menu;
QWidget* m_input_widget;
QHBoxLayout* m_input_hbox;
QCheckBox* m_local_echo_checkbox;
QCheckBox* m_newline_on_enter_checkbox;
bool m_local_echo = false;
bool m_newline_on_enter = true;
bool m_attached_to_main_window = true;
bool m_destroying = false;
};

View File

@@ -11,15 +11,27 @@
#include "fmt/format.h"
#include <deque>
using namespace R5900;
const int rdram_devices = 2; // put 8 for TOOL and 2 for PS2 and PSX
int rdram_sdevid = 0;
std::deque<u8> ee_sio_rx_fifo;
std::deque<u8> ee_sio_tx_fifo;
void hwReset()
{
std::memset(eeHw, 0, sizeof(eeHw));
{
std::deque<u8> empty_rx;
std::swap(ee_sio_rx_fifo, empty_rx);
std::deque<u8> empty_tx;
std::swap(ee_sio_tx_fifo, empty_tx);
}
psHu32(SBUS_F260) = 0x1D000060;
// i guess this is kinda a version, it's used by some bioses

View File

@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include <deque>
#pragma once
namespace EEMemoryMap
@@ -355,3 +357,6 @@ extern void hwReset();
extern const int rdram_devices;
extern int rdram_sdevid;
extern std::deque<u8> ee_sio_rx_fifo;
extern std::deque<u8> ee_sio_tx_fifo;

View File

@@ -125,7 +125,23 @@ mem32_t _hwRead32(u32 mem)
switch( mem )
{
case SIO_ISR:
// Not (yet) hardware tested
// The PS2SDK behaviour is as follows:
// TX: Don't write to TX FIFO until until bit 15 is 0
// RX: RX FIFO has data when bits 8-11 are not 0 (maybe a byte count?)
// RX: When reading from the RX FIFO, set bits 0-2 to 1 (why??)
// For TX, we don't do any LLE buffering, so we can keep bit 15 to 0
// For RX, just hack it so when the ee_rx_fifo.size() != 0, ISR = 0xf00
if(!ee_sio_rx_fifo.empty())
return 0xf00;
return 0x0;
break;
case 0x1000f410:
case MCH_RICM:
return 0;
@@ -211,6 +227,16 @@ mem32_t hwRead32_page_0F_INTC_HACK(u32 mem)
template< uint page >
mem8_t _hwRead8(u32 mem)
{
if(mem == SIO_RXFIFO)
{
if(ee_sio_rx_fifo.empty())
return 0; // needs hardware test, what does it return with the FIFO is empty
const char c = ee_sio_rx_fifo.front();
ee_sio_rx_fifo.pop_front();
return c;
}
u32 ret32 = _hwRead32<page, false>(mem & ~0x03);
return ((u8*)&ret32)[mem & 0x03];
}

View File

@@ -285,26 +285,35 @@ void _hwWrite8(u32 mem, u8 value)
#endif
if (mem == SIO_TXFIFO)
{
static bool included_newline = false;
static char sio_buffer[1024];
static int sio_count;
if (value == '\r')
static bool last_char_was_cr = false;
// skip the \n in \r\n
if(last_char_was_cr && (value == '\n'))
{
included_newline = true;
sio_buffer[sio_count++] = '\n';
last_char_was_cr = false;
return;
}
else if (!included_newline || (value != '\n'))
last_char_was_cr = value == '\r';
bool should_flush_cause_newline = false;
if (last_char_was_cr)
{
included_newline = false;
sio_buffer[sio_count++] = value;
should_flush_cause_newline = true;
ee_sio_tx_fifo.push_back('\n');
}
else
{
should_flush_cause_newline = value == '\n';
ee_sio_tx_fifo.push_back(value);
}
if ((sio_count == std::size(sio_buffer)-1) || (sio_count != 0 && sio_buffer[sio_count-1] == '\n'))
// Check if the only thing in the buffer
if (ee_sio_tx_fifo.size() == 1024 || should_flush_cause_newline)
{
sio_buffer[sio_count] = 0;
eeConLog( ShiftJIS_ConvertString(sio_buffer) );
sio_count = 0;
std::string output_string(ee_sio_tx_fifo.begin(), ee_sio_tx_fifo.end());
eeConLog(ShiftJIS_ConvertString(output_string.c_str()));
ee_sio_tx_fifo.clear();
}
return;
}

View File

@@ -526,6 +526,7 @@ void VMManager::SetDefaultLoggingSettings(SettingsInterface& si)
si.SetBoolValue("Logging", "EnableSystemConsole", false);
si.SetBoolValue("Logging", "EnableFileLogging", true);
si.SetBoolValue("Logging", "EnableTimestamps", true);
si.SetBoolValue("Logging", "EnableEESIOInput", false);
si.SetBoolValue("Logging", "EnableVerbose", false);
si.SetBoolValue("Logging", "EnableEEConsole", false);
si.SetBoolValue("Logging", "EnableIOPConsole", false);
@@ -3747,3 +3748,15 @@ void VMManager::PollDiscordPresence()
Discord_RunCallbacks();
}
bool VMManager::WriteBytesToEESIORXFIFO(const std::span<const u8> data)
{
if(ee_sio_rx_fifo.size() + data.size() > 1024)
{
Console.Warning("EE RX FIFO is full, not appending more bytes.");
return false;
}
ee_sio_rx_fifo.insert(ee_sio_rx_fifo.end(), data.begin(), data.end());
return true;
}

View File

@@ -6,6 +6,7 @@
#include <functional>
#include <mutex>
#include <optional>
#include <span>
#include <string>
#include <string_view>
#include <vector>
@@ -264,6 +265,9 @@ namespace VMManager
/// Called when the rich presence string, provided by RetroAchievements, changes.
void UpdateDiscordPresence(bool update_session_time);
/// Append bytes to the EE SIO RX FIFO. If it returns false, the FIFO is full and data is not inserted.
bool WriteBytesToEESIORXFIFO(const std::span<const u8> data);
/// Internal callbacks, implemented in the emu core.
namespace Internal
{