Compare commits

...

5 Commits

Author SHA1 Message Date
refractionpcsx2
2640678cac GS/HW: Adjust which function gets used for clearing depth on perfect match 2025-06-14 01:30:00 +02:00
KamFretoZ
8b90e2d53d BPM: Fix CTD when exiting BPM in No GUI mode 2025-06-14 01:28:49 +02:00
KamFretoZ
f87175dc7f Host: Move Batch/NoGUI mode check to Host
Moved from QtHost to Host for more accesibility
2025-06-14 01:28:49 +02:00
refractionpcsx2
b30444c0d0 GS/HW: Fix bug and improve inside target tracking on HW moves 2025-06-12 23:01:36 +01:00
refractionpcsx2
c1da0caf15 GS/HW: Fix possible null reference causing a crash 2025-06-12 18:26:15 +01:00
9 changed files with 60 additions and 29 deletions

View File

@@ -43,7 +43,7 @@ void LogWindow::updateSettings()
{
std::unique_lock lock(s_log_mutex);
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !QtHost::InNoGUIMode();
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();

View File

@@ -1130,7 +1130,7 @@ bool MainWindow::shouldHideMainWindow() const
// NOTE: We can't use isRenderingToMain() here, because this happens post-fullscreen-switch.
return (Host::GetBoolSettingValue("UI", "HideMainWindowWhenRunning", false) && !g_emu_thread->shouldRenderToMain()) ||
(g_emu_thread->shouldRenderToMain() && (isRenderingFullscreen() || m_is_temporarily_windowed)) ||
QtHost::InNoGUIMode();
Host::InNoGUIMode();
}
bool MainWindow::shouldMouseLock() const
@@ -1306,7 +1306,7 @@ bool MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, b
// reshow the main window during display updates, because otherwise fullscreen transitions and renderer switches
// would briefly show and then hide the main window. So instead, we do it on shutdown, here. Except if we're in
// batch mode, when we're going to exit anyway.
if (!isRenderingToMain() && isHidden() && !QtHost::InBatchMode() && !g_emu_thread->isRunningFullscreenUI())
if (!isRenderingToMain() && isHidden() && !Host::InBatchMode() && !g_emu_thread->isRunningFullscreenUI())
updateWindowState(true);
// Clear the VM valid state early. That way we can't do anything in the UI if we take a while to shut down.
@@ -2060,7 +2060,7 @@ void MainWindow::onVMStopped()
updateInputRecordingActions(false);
// If we're closing or in batch mode, quit the whole application now.
if (m_is_closing || QtHost::InBatchMode())
if (m_is_closing || Host::InBatchMode())
{
quit();
return;

View File

@@ -602,7 +602,7 @@ void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
bool EmuThread::shouldRenderToMain() const
{
return !Host::GetBoolSettingValue("UI", "RenderToSeparateWindow", false) && !QtHost::InNoGUIMode();
return !Host::GetBoolSettingValue("UI", "RenderToSeparateWindow", false) && !Host::InNoGUIMode();
}
void EmuThread::toggleSoftwareRendering()
@@ -1268,7 +1268,7 @@ void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool def
// This will probably call shutdownVM() again, but by the time it runs, we'll have already shut down
// and it'll be a noop.
if (QtHost::InBatchMode())
if (Host::InBatchMode())
QMetaObject::invokeMethod(g_main_window, "requestExit", Qt::QueuedConnection, Q_ARG(bool, false));
}
}
@@ -1437,12 +1437,12 @@ void Host::CommitBaseSettingChanges()
}
}
bool QtHost::InBatchMode()
bool Host::InBatchMode()
{
return s_batch_mode;
}
bool QtHost::InNoGUIMode()
bool Host::InNoGUIMode()
{
return s_nogui_mode;
}

View File

@@ -245,12 +245,6 @@ namespace QtHost
/// Sets the icon theme, based on the current style (light/dark).
void SetIconThemeFromStyle();
/// Sets batch mode (exit after game shutdown).
bool InBatchMode();
/// Sets NoGUI mode (implys batch mode, does not display main window, exits on shutdown).
bool InNoGUIMode();
/// Returns true if the calling thread is the UI thread.
bool IsOnUIThread();

View File

@@ -3167,7 +3167,7 @@ void GSRendererHW::Draw()
}
}
if (no_rt && ds->m_TEX0.TBP0 != m_cached_ctx.ZBUF.Block())
if (no_rt && ds && ds->m_TEX0.TBP0 != m_cached_ctx.ZBUF.Block())
{
const GSLocalMemory::psm_t& zbuf_psm = GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM];
int vertical_offset = ((static_cast<int>(m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) / 32) / std::max(static_cast<int>(ds->m_TEX0.TBW), 1)) * zbuf_psm.pgs.y; // I know I could just not shift it..

View File

@@ -629,6 +629,8 @@ void GSTextureCache::DirtyRectByPage(u32 sbp, u32 spsm, u32 sbw, Target* t, GSVe
{
RGBAMask rgba;
rgba._u32 = GSUtil::GetChannelMask(spsm);
// FIXME: This could be a problem if used when the valid area is smaller than dirty area and it needs the data during expansion on a later draw.
// This happens on Kamen Rider - Seigi no Keifu if the invalidatevideomem function was to use this function for depth clearing.
AddDirtyRectTarget(t, t->m_valid, t->m_TEX0.PSM, t->m_TEX0.TBW, rgba);
return;
}
@@ -4363,7 +4365,9 @@ void GSTextureCache::InvalidateVideoMem(const GSOffset& off, const GSVector4i& r
InvalidateTemporaryZ();
}
if (GSLocalMemory::m_psm[psm].depth)
// If we're dealing with quadrant draws, we need to position them correctly (Final Fantasy X).
if (GSLocalMemory::m_psm[psm].depth &&
r.width() <= (GSLocalMemory::m_psm[psm].pgs.x >> 1) && r.height() <= (GSLocalMemory::m_psm[psm].pgs.y >> 1))
DirtyRectByPage(bp, psm, bw, t, r);
else
AddDirtyRectTarget(t, r, psm, bw, rgba);
@@ -4774,6 +4778,11 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
}
bool req_resize = false;
// Save for later in case of page copy.
const u32 start_SBP = SBP;
const u32 start_DBP = DBP;
if (m_expected_src_bp == static_cast<int>(SBP) && m_expected_dst_bp == static_cast<int>(DBP))
{
// Get the new position so we can work out the offset.
@@ -4789,12 +4798,13 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
SBP = m_remembered_src_bp;
DBP = m_remembered_dst_bp;
m_expected_src_bp = -1;
m_remembered_src_bp = -1;
m_expected_dst_bp = -1;
m_remembered_dst_bp = -1;
}
m_expected_src_bp = -1;
m_remembered_src_bp = -1;
m_expected_dst_bp = -1;
m_remembered_dst_bp = -1;
// Look for an exact match on the targets.
GSTextureCache::Target* src = GetExactTarget(SBP, SBW, spsm_s.depth ? DepthStencil : RenderTarget, SBP);
GSTextureCache::Target* dst = GetExactTarget(DBP, DBW, dpsm_s.depth ? DepthStencil : RenderTarget, DBP);
@@ -4858,7 +4868,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
// If we have an offset, adjust the base positions
if (src->m_TEX0.TBP0 != SBP)
{
GSVector4i offset = TranslateAlignedRectByPage(dst, SBP, SPSM, SBW, GSVector4i(0, 1).xxyy(), false);
const GSVector4i offset = TranslateAlignedRectByPage(src, SBP, SPSM, SBW, GSVector4i(0, 1).xxyy(), false);
sx += offset.x;
sy += offset.y;
@@ -4866,7 +4876,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
if (dst->m_TEX0.TBP0 != DBP)
{
GSVector4i offset = TranslateAlignedRectByPage(dst, DBP, DPSM, DBW, GSVector4i(0, 1).xxyy(), false);
const GSVector4i offset = TranslateAlignedRectByPage(dst, DBP, DPSM, DBW, GSVector4i(0, 1).xxyy(), false);
dx += offset.x;
dy += offset.y;
@@ -5044,18 +5054,26 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
u32 page_mask = GSLocalMemory::IsPageAlignedMasked(src->m_TEX0.PSM, GSVector4i(sx, sy, sx + w, sy + h));
if (((page_mask & 0x0f0f) == 0x0f0f || (page_mask & 0xf0f0) == 0xf0f0) && (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x || h == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.y))
{
// Vertical Strips
if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x)
// Page copy
if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x && h == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.y)
{
m_expected_src_bp = start_SBP + BLOCKS_PER_PAGE;
m_expected_dst_bp = start_DBP + BLOCKS_PER_PAGE;
}
// Vertical Strips.
else if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x)
{
m_expected_src_bp = GSLocalMemory::GetStartBlockAddress(src->m_TEX0.TBP0, src->m_TEX0.TBW, src->m_TEX0.PSM, GSVector4i(sx + w, 0, sx + w + w, h));
m_expected_dst_bp = GSLocalMemory::GetStartBlockAddress(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, GSVector4i(dx + w, 0, dx + w + w, h));
}
// Horizontal Strips.
else
{
m_expected_src_bp = GSLocalMemory::GetStartBlockAddress(src->m_TEX0.TBP0, src->m_TEX0.TBW, src->m_TEX0.PSM, GSVector4i(0, sy + h, w, sy + h + h));
m_expected_dst_bp = GSLocalMemory::GetStartBlockAddress(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, GSVector4i(0, dy + h, w, dy + h + h));
}
// Only check the source, the destination might need expanding.
if (static_cast<u32>(m_expected_src_bp) < src->UnwrappedEndBlock() && static_cast<u32>(m_expected_src_bp) >= src->m_TEX0.TBP0)
{
m_remembered_src_bp = src->m_TEX0.TBP0;

View File

@@ -67,6 +67,12 @@ namespace Host
bool ConfirmMessage(const std::string_view title, const std::string_view message);
bool ConfirmFormattedMessage(const std::string_view title, const char* format, ...);
/// Sets batch mode (exit after game shutdown).
bool InBatchMode();
/// Sets NoGUI mode (implys batch mode, does not display main window, exits on shutdown).
bool InNoGUIMode();
/// Opens a URL, using the default application.
void OpenURL(const std::string_view url);

View File

@@ -1602,7 +1602,7 @@ void FullscreenUI::DrawExitWindow()
ImGui::PushStyleColor(ImGuiCol_Text, UIBackgroundTextColor);
if (BeginHorizontalMenu("exit_window", menu_pos, menu_size, 3))
if (BeginHorizontalMenu("exit_window", menu_pos, menu_size, (Host::InNoGUIMode()) ? 2 : 3))
{
ResetFocusHere();
@@ -1621,10 +1621,13 @@ void FullscreenUI::DrawExitWindow()
DoRequestExit();
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/desktop-mode.png"), FSUI_CSTR("Desktop Mode"),
FSUI_CSTR("Exits Big Picture mode, returning to the desktop interface.")))
if (!Host::InNoGUIMode())
{
DoDesktopMode();
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/desktop-mode.png"), FSUI_CSTR("Desktop Mode"),
FSUI_CSTR("Exits Big Picture mode, returning to the desktop interface.")))
{
DoDesktopMode();
}
}
}
EndHorizontalMenu();

View File

@@ -56,6 +56,16 @@ void Host::OpenURL(const std::string_view url)
{
}
bool Host::InBatchMode()
{
return false;
}
bool Host::InNoGUIMode()
{
return false;
}
bool Host::CopyTextToClipboard(const std::string_view text)
{
return false;