mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65a92470d3 | ||
|
|
10dc1a2da2 | ||
|
|
aad2128c32 | ||
|
|
2640678cac | ||
|
|
8b90e2d53d | ||
|
|
f87175dc7f | ||
|
|
b30444c0d0 | ||
|
|
c1da0caf15 | ||
|
|
c4a8fc5b71 | ||
|
|
8eb46b5a4c | ||
|
|
8be16d1039 |
55
.github/workflows/cron_publish_flatpak.yml
vendored
55
.github/workflows/cron_publish_flatpak.yml
vendored
@@ -6,36 +6,43 @@ on:
|
||||
workflow_dispatch: # As well as manually.
|
||||
|
||||
jobs:
|
||||
check:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Check if release is needed"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
outputs:
|
||||
PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
|
||||
FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
|
||||
steps:
|
||||
- name: Get latest tag and Flathub release
|
||||
id: getinfo
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
PCSX2_RELEASE=$(gh api -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/PCSX2/pcsx2/releases | jq -r '.[0].tag_name')
|
||||
FLATHUB_RELEASE=$(curl -L -s https://flathub.org/api/v2/appstream/net.pcsx2.PCSX2 | jq -r '.releases | max_by(.version) | .version')
|
||||
echo "Latest PCSX2 release is: '${PCSX2_RELEASE}'"
|
||||
echo "Latest Flathub release is: '${FLATHUB_RELEASE}'"
|
||||
PCSX2_RELEASE=$(echo $PCSX2_RELEASE | sed 's/[^0-9]*//g')
|
||||
FLATHUB_RELEASE=$(echo $FLATHUB_RELEASE | sed 's/[^0-9]*//g')
|
||||
echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# check is disabled as the flathub api does not give us beta repository information
|
||||
# Alternatively we can "flatpak remote-info or parse the appstream directly for the beta repo"
|
||||
# Maybe in the future if we don't want to publish the same version twice if we get no commits
|
||||
# for 24 hours.
|
||||
|
||||
# check:
|
||||
# if: github.repository == 'PCSX2/pcsx2'
|
||||
# name: "Check if release is needed"
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 180
|
||||
# outputs:
|
||||
# PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
|
||||
# FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
|
||||
# steps:
|
||||
# - name: Get latest tag and Flathub release
|
||||
# id: getinfo
|
||||
# env:
|
||||
# GH_TOKEN: ${{ github.token }}
|
||||
# run: |
|
||||
# PCSX2_RELEASE=$(gh api -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/PCSX2/pcsx2/releases | jq -r '.[0].tag_name')
|
||||
# FLATHUB_RELEASE=$(curl -L -s https://flathub.org/api/v2/appstream/net.pcsx2.PCSX2 | jq -r '.releases | max_by(.version) | .version')
|
||||
# echo "Latest PCSX2 release is: '${PCSX2_RELEASE}'"
|
||||
# echo "Latest Flathub release is: '${FLATHUB_RELEASE}'"
|
||||
# PCSX2_RELEASE=$(echo $PCSX2_RELEASE | sed 's/[^0-9]*//g')
|
||||
# FLATHUB_RELEASE=$(echo $FLATHUB_RELEASE | sed 's/[^0-9]*//g')
|
||||
# echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
# echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build:
|
||||
needs: check
|
||||
# needs: check
|
||||
# outputs are automatically compared as strings. This doesn't work in our favour
|
||||
# Use fromJson() to convert them to proper integers...
|
||||
# see: https://github.com/github/docs/pull/25870
|
||||
# and: https://github.com/orgs/community/discussions/57480
|
||||
#if: fromJson(needs.check.outputs.FLATHUB_RELEASE) < fromJson(needs.check.outputs.PCSX2_RELEASE)
|
||||
|
||||
# if: fromJson(needs.check.outputs.FLATHUB_RELEASE) < fromJson(needs.check.outputs.PCSX2_RELEASE)
|
||||
name: "Build and publish Flatpak"
|
||||
uses: ./.github/workflows/linux_build_flatpak.yml
|
||||
with:
|
||||
|
||||
13
.github/workflows/linux_build_flatpak.yml
vendored
13
.github/workflows/linux_build_flatpak.yml
vendored
@@ -54,19 +54,16 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
set-safe-directory: ${{ env.GITHUB_WORKSPACE }}
|
||||
# 10 here, since the odds of having 10 untagged commits in a row should be slim to none
|
||||
# This is required for the tagging logic in generate-metainfo.sh
|
||||
fetch-depth: 10
|
||||
fetch-tags: true
|
||||
|
||||
# Work around container ownership issue
|
||||
- name: Set Safe Directory
|
||||
shell: bash
|
||||
run: git config --global --add safe.directory "*"
|
||||
|
||||
# Hackity hack. When running the workflow on a schedule, we don't have the tag,
|
||||
# it doesn't fetch tags, therefore we don't get a version. So grab them manually.
|
||||
# actions/checkout elides tags, fetch them primarily for releases
|
||||
- name: Fetch tags
|
||||
if: ${{ inputs.fetchTags }}
|
||||
run: git fetch --tags --no-recurse-submodules
|
||||
|
||||
- name: Add stable release identifier file
|
||||
if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }}
|
||||
shell: bash
|
||||
@@ -125,7 +122,7 @@ jobs:
|
||||
cache: true
|
||||
restore-cache: true
|
||||
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
|
||||
|
||||
|
||||
#- name: Validate build
|
||||
# run: |
|
||||
# flatpak-builder-lint repo repo
|
||||
|
||||
@@ -12,12 +12,24 @@ GIT_DATE=$(git log -1 --pretty=%cd --date=iso8601)
|
||||
GIT_VERSION=$(git tag --points-at HEAD)
|
||||
GIT_HASH=$(git rev-parse HEAD)
|
||||
|
||||
if [[ "${GIT_VERSION}" == "" ]]; then
|
||||
# In the odd event that we run this script before the release gets tagged.
|
||||
GIT_VERSION=$(git describe --tags)
|
||||
if [[ "${GIT_VERSION}" == "" ]]; then
|
||||
GIT_VERSION=$(git rev-parse HEAD)
|
||||
fi
|
||||
if [[ -z "${GIT_VERSION}" ]]; then
|
||||
if git branch -r --contains HEAD | grep -q 'origin/master'; then
|
||||
# Our master doesn't have a tagged commit
|
||||
# This happens when the commit is "ci skip"
|
||||
# abbrev so we have just the latest tag
|
||||
# ie v2.3.420 (Yes, that's the current master at the time of writing)
|
||||
GIT_VERSION=$(git describe --tags --abbrev=0)
|
||||
else
|
||||
# We are probably building a PR
|
||||
# Keep the short SHA in the version
|
||||
# ie v2.3.420-1-g10dc1a2da
|
||||
GIT_VERSION=$(git describe --tags)
|
||||
fi
|
||||
|
||||
if [[ -z "${GIT_VERSION}" ]]; then
|
||||
# Fallback to raw commit hash
|
||||
GIT_VERSION=$(git rev-parse HEAD)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "GIT_DATE: ${GIT_DATE}"
|
||||
|
||||
@@ -419,6 +419,16 @@ void Host::OnCreateMemoryCardOpenRequested()
|
||||
// noop
|
||||
}
|
||||
|
||||
bool Host::InBatchMode()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Host::InNoGUIMode()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Host::ShouldPreferHostFileSelector()
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -92,7 +92,7 @@ public Q_SLOTS:
|
||||
void refreshGridCovers();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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..
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <cstring>
|
||||
#include <fmt/format.h>
|
||||
#include <sys/stat.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -928,12 +929,6 @@ namespace R3000A
|
||||
{
|
||||
int Kprintf_HLE()
|
||||
{
|
||||
// Using sprintf here is a bit nasty, but it has a large buffer..
|
||||
// Don't feel like rewriting it.
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
// Emulate the expected Kprintf functionality:
|
||||
iopMemWrite32(sp, a0);
|
||||
@@ -956,7 +951,7 @@ namespace R3000A
|
||||
char tmp[max_len], tmp2[max_len];
|
||||
char* ptmp = tmp;
|
||||
unsigned int printed_bytes = 0;
|
||||
unsigned int remaining_buf = max_len - 1;
|
||||
int remaining_buf = max_len - 1;
|
||||
int n = 1, i = 0, j = 0;
|
||||
|
||||
while (fmt[i])
|
||||
@@ -1000,7 +995,7 @@ namespace R3000A
|
||||
{
|
||||
case 'f':
|
||||
case 'F':
|
||||
printed_bytes = snprintf(ptmp, remaining_buf, tmp2, (float)iopMemRead32(sp + n * 4));
|
||||
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (float)iopMemRead32(sp + n * 4)));
|
||||
remaining_buf -= printed_bytes;
|
||||
ptmp += printed_bytes;
|
||||
n++;
|
||||
@@ -1012,7 +1007,7 @@ namespace R3000A
|
||||
case 'E':
|
||||
case 'g':
|
||||
case 'G':
|
||||
printed_bytes = snprintf(ptmp, remaining_buf, tmp2, (double)iopMemRead32(sp + n * 4));
|
||||
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (double)iopMemRead32(sp + n * 4)));
|
||||
remaining_buf -= printed_bytes;
|
||||
ptmp += printed_bytes;
|
||||
n++;
|
||||
@@ -1028,14 +1023,14 @@ namespace R3000A
|
||||
case 'X':
|
||||
case 'u':
|
||||
case 'U':
|
||||
printed_bytes = snprintf(ptmp, remaining_buf, tmp2, (u32)iopMemRead32(sp + n * 4));
|
||||
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (u32)iopMemRead32(sp + n * 4)));
|
||||
remaining_buf -= printed_bytes;
|
||||
ptmp += printed_bytes;
|
||||
n++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printed_bytes = snprintf(ptmp, remaining_buf, tmp2, (u8)iopMemRead32(sp + n * 4));
|
||||
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, (u8)iopMemRead32(sp + n * 4)));
|
||||
remaining_buf -= printed_bytes;
|
||||
ptmp += printed_bytes;
|
||||
n++;
|
||||
@@ -1044,7 +1039,7 @@ namespace R3000A
|
||||
case 's':
|
||||
{
|
||||
std::string s = iopMemReadString(iopMemRead32(sp + n * 4));
|
||||
printed_bytes = snprintf(ptmp, remaining_buf, tmp2, s.data());
|
||||
printed_bytes = std::min(remaining_buf, snprintf(ptmp, remaining_buf, tmp2, s.data()));
|
||||
remaining_buf -= printed_bytes;
|
||||
ptmp += printed_bytes;
|
||||
n++;
|
||||
@@ -1070,10 +1065,6 @@ namespace R3000A
|
||||
iopConLog(ShiftJIS_ConvertString(tmp, 1023));
|
||||
|
||||
return 1;
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
} // namespace sysmem
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user