mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b625e2c47a | ||
|
|
97300d59a9 | ||
|
|
f45840a29f | ||
|
|
bfff6ed406 | ||
|
|
ad6f5fd6af |
4
.github/workflows/release_cut_new.yml
vendored
4
.github/workflows/release_cut_new.yml
vendored
@@ -68,7 +68,7 @@ jobs:
|
||||
mv ./release-notes.md ${GITHUB_WORKSPACE}/release-notes.md
|
||||
|
||||
- name: Create a GitHub Release (Manual)
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
|
||||
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631
|
||||
if: steps.tag_version.outputs.new_tag && github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
body_path: ./release-notes.md
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
tag_name: ${{ steps.tag_version.outputs.new_tag }}
|
||||
|
||||
- name: Create a GitHub Release (Push)
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
|
||||
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631
|
||||
if: steps.tag_version.outputs.new_tag && github.event_name != 'workflow_dispatch'
|
||||
with:
|
||||
body_path: ./release-notes.md
|
||||
|
||||
@@ -2819,7 +2819,7 @@ QString MainWindow::getDiscDevicePath(const QString& title)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MainWindow::startGameListEntry(const GameList::Entry* entry, std::optional<s32> save_slot, std::optional<bool> fast_boot)
|
||||
void MainWindow::startGameListEntry(const GameList::Entry* entry, std::optional<s32> save_slot, std::optional<bool> fast_boot, bool load_backup)
|
||||
{
|
||||
std::shared_ptr<VMBootParameters> params = std::make_shared<VMBootParameters>();
|
||||
params->fast_boot = fast_boot;
|
||||
@@ -2828,7 +2828,7 @@ void MainWindow::startGameListEntry(const GameList::Entry* entry, std::optional<
|
||||
|
||||
if (save_slot.has_value() && !entry->serial.empty())
|
||||
{
|
||||
std::string state_filename = VMManager::GetSaveStateFileName(entry->serial.c_str(), entry->crc, save_slot.value());
|
||||
std::string state_filename = VMManager::GetSaveStateFileName(entry->serial.c_str(), entry->crc, save_slot.value(), load_backup);
|
||||
if (!FileSystem::FileExists(state_filename.c_str()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("This save state does not exist."));
|
||||
@@ -2953,12 +2953,12 @@ std::optional<bool> MainWindow::promptForResumeState(const QString& save_state_p
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void MainWindow::loadSaveStateSlot(s32 slot)
|
||||
void MainWindow::loadSaveStateSlot(s32 slot, bool load_backup)
|
||||
{
|
||||
if (s_vm_valid)
|
||||
{
|
||||
// easy when we're running
|
||||
g_emu_thread->loadStateFromSlot(slot);
|
||||
g_emu_thread->loadStateFromSlot(slot, load_backup);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -2968,7 +2968,7 @@ void MainWindow::loadSaveStateSlot(s32 slot)
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
startGameListEntry(entry, slot, std::nullopt);
|
||||
startGameListEntry(entry, slot, std::nullopt, load_backup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3015,15 +3015,6 @@ void MainWindow::populateLoadStateMenu(QMenu* menu, const QString& filename, con
|
||||
|
||||
QAction* delete_save_states_action = menu->addAction(tr("Delete Save States..."));
|
||||
|
||||
// don't include undo in the right click menu
|
||||
if (!is_right_click_menu)
|
||||
{
|
||||
QAction* load_undo_state = menu->addAction(tr("Undo Load State"));
|
||||
load_undo_state->setEnabled(false); // CanUndoLoadState()
|
||||
// connect(load_undo_state, &QAction::triggered, this, &QtHostInterface::undoLoadState);
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
const QByteArray game_serial_utf8(serial.toUtf8());
|
||||
std::string state_filename;
|
||||
FILESYSTEM_STAT_DATA sd;
|
||||
@@ -3053,6 +3044,18 @@ void MainWindow::populateLoadStateMenu(QMenu* menu, const QString& filename, con
|
||||
has_any_states = true;
|
||||
}
|
||||
|
||||
for (s32 i = 1; i <= VMManager::NUM_SAVE_STATE_SLOTS; i++)
|
||||
{
|
||||
FILESYSTEM_STAT_DATA sd;
|
||||
state_filename = VMManager::GetSaveStateFileName(game_serial_utf8.constData(), crc, i, true);
|
||||
if (!FileSystem::StatFile(state_filename.c_str(), &sd))
|
||||
continue;
|
||||
|
||||
action = menu->addAction(tr("Load Backup Slot %1 (%2)").arg(i).arg(formatTimestampForSaveStateMenu(sd.ModificationTime)));
|
||||
connect(action, &QAction::triggered, [this, i]() { loadSaveStateSlot(i, true); });
|
||||
has_any_states = true;
|
||||
}
|
||||
|
||||
delete_save_states_action->setEnabled(has_any_states);
|
||||
if (has_any_states)
|
||||
{
|
||||
|
||||
@@ -267,13 +267,13 @@ private:
|
||||
QString getDiscDevicePath(const QString& title);
|
||||
|
||||
void startGameListEntry(
|
||||
const GameList::Entry* entry, std::optional<s32> save_slot = std::nullopt, std::optional<bool> fast_boot = std::nullopt);
|
||||
const GameList::Entry* entry, std::optional<s32> save_slot = std::nullopt, std::optional<bool> fast_boot = std::nullopt, bool load_backup = false);
|
||||
void setGameListEntryCoverImage(const GameList::Entry* entry);
|
||||
void clearGameListEntryPlayTime(const GameList::Entry* entry);
|
||||
void goToWikiPage(const GameList::Entry* entry);
|
||||
|
||||
std::optional<bool> promptForResumeState(const QString& save_state_path);
|
||||
void loadSaveStateSlot(s32 slot);
|
||||
void loadSaveStateSlot(s32 slot, bool load_backup = false);
|
||||
void loadSaveStateFile(const QString& filename, const QString& state_filename);
|
||||
void populateLoadStateMenu(QMenu* menu, const QString& filename, const QString& serial, quint32 crc);
|
||||
void populateSaveStateMenu(QMenu* menu, const QString& serial, quint32 crc);
|
||||
|
||||
@@ -320,18 +320,18 @@ void EmuThread::loadState(const QString& filename)
|
||||
VMManager::LoadState(filename.toUtf8().constData());
|
||||
}
|
||||
|
||||
void EmuThread::loadStateFromSlot(qint32 slot)
|
||||
void EmuThread::loadStateFromSlot(qint32 slot, bool load_backup)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "loadStateFromSlot", Qt::QueuedConnection, Q_ARG(qint32, slot));
|
||||
QMetaObject::invokeMethod(this, "loadStateFromSlot", Qt::QueuedConnection, Q_ARG(qint32, slot), Q_ARG(bool, load_backup));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::LoadStateFromSlot(slot);
|
||||
VMManager::LoadStateFromSlot(slot, load_backup);
|
||||
}
|
||||
|
||||
void EmuThread::saveState(const QString& filename)
|
||||
|
||||
@@ -87,7 +87,7 @@ public Q_SLOTS:
|
||||
void setVMPaused(bool paused);
|
||||
void shutdownVM(bool save_state = true);
|
||||
void loadState(const QString& filename);
|
||||
void loadStateFromSlot(qint32 slot);
|
||||
void loadStateFromSlot(qint32 slot, bool load_backup = false);
|
||||
void saveState(const QString& filename);
|
||||
void saveStateToSlot(qint32 slot);
|
||||
void toggleFullscreen();
|
||||
|
||||
@@ -1240,13 +1240,8 @@ void GraphicsSettingsWidget::populateUpscaleMultipliers(u32 max_upscale_multipli
|
||||
{
|
||||
static constexpr std::pair<const char*, float> templates[] = {
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Native (PS2) (Default)"), 1.0f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "1.25x Native (~450px)"), 1.25f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "1.5x Native (~540px)"), 1.5f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "1.75x Native (~630px)"), 1.75f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "2x Native (~720px/HD)"), 2.0f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "2.5x Native (~900px/HD+)"), 2.5f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "3x Native (~1080px/FHD)"), 3.0f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "3.5x Native (~1260px)"), 3.5f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "4x Native (~1440px/QHD)"), 4.0f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "5x Native (~1800px/QHD+)"), 5.0f},
|
||||
{QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "6x Native (~2160px/4K UHD)"), 6.0f},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1637,7 +1637,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
((t->m_TEX0.TBW < (horz_page_offset + ((block_boundary_rect.z + GSLocalMemory::m_psm[psm].pgs.x - 1) / GSLocalMemory::m_psm[psm].pgs.x)) ||
|
||||
(t->m_TEX0.TBW != bw && block_boundary_rect.w > GSLocalMemory::m_psm[psm].pgs.y))))
|
||||
{
|
||||
DevCon.Warning("BP %x - 16bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
|
||||
DbgCon.Warning("BP %x - 16bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
|
||||
continue;
|
||||
}
|
||||
// Keep note that 2 bw is basically 1 normal page, as bw is in 64 pixels, and 8bit pages are 128 pixels wide, aka 2 bw.
|
||||
@@ -1646,12 +1646,12 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
(!(block_boundary_rect.w <= GSLocalMemory::m_psm[psm].pgs.y && ((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) <= t->m_TEX0.TBW) &&
|
||||
!(((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) == rt_tbw)))
|
||||
{
|
||||
DevCon.Warning("BP %x - 8bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
|
||||
DbgCon.Warning("BP %x - 8bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
|
||||
continue;
|
||||
}
|
||||
else if (!possible_shuffle && GSLocalMemory::m_psm[psm].bpp <= 8 && TEX0.TBW == 1)
|
||||
{
|
||||
DevCon.Warning("Too small for relocation, skipping");
|
||||
DbgCon.Warning("Too small for relocation, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1683,7 +1683,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
||||
{
|
||||
if (!region.HasEither() && GSLocalMemory::m_psm[psm].bpp == 32 && (t->m_TEX0.TBW - (((bp - t->m_TEX0.TBP0) >> 5) % rt_tbw)) < static_cast<u32>((block_boundary_rect.width() + 63) / 64))
|
||||
{
|
||||
DevCon.Warning("Bad alignmenet");
|
||||
DbgCon.Warning("Bad alignmenet");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2729,7 +2729,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
t->m_texture = nullptr;
|
||||
}
|
||||
|
||||
DevCon.Warning("Deleting Z draw %d", GSState::s_n);
|
||||
GL_CACHE("Deleting Z draw %d", GSState::s_n);
|
||||
InvalidateSourcesFromTarget(t);
|
||||
i = rev_list.erase(i);
|
||||
delete t;
|
||||
@@ -3060,7 +3060,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
|
||||
|
||||
dst->UpdateValidity(GSVector4i::loadh(valid_size));
|
||||
|
||||
if (!is_frame && !preload && !(src && src->m_TEX0.TBP0 == dst->m_TEX0.TBP0))
|
||||
if (!is_frame && !preload/* && !(src && src->m_TEX0.TBP0 == dst->m_TEX0.TBP0)*/)
|
||||
{
|
||||
if ((preserve_target || !draw_rect.eq(GSVector4i::loadh(valid_size))) && GSRendererHW::GetInstance()->m_draw_transfers.size() > 0)
|
||||
{
|
||||
@@ -4277,13 +4277,18 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
|
||||
|
||||
const GSVector4i draw_rect = (t->readbacks_since_draw > 1) ? t->m_drawn_since_read : targetr.rintersect(t->m_drawn_since_read);
|
||||
const GSVector4i dirty_rect = t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size);
|
||||
|
||||
// Getaway (J) stores a Z texture at 0x2800 which it uses and the next frame it stores the reflection map in
|
||||
// 0x2800, so this will misdetect. So if it's not expecting a Z, check for RT's too.
|
||||
z_found = read_start >= t->m_TEX0.TBP0 && read_end <= t->m_end_block && GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth;
|
||||
|
||||
// Recently made this section dirty, no need to read it.
|
||||
if (draw_rect.rintersect(dirty_rect).eq(draw_rect))
|
||||
if (z_found && draw_rect.rintersect(dirty_rect).eq(draw_rect))
|
||||
return;
|
||||
|
||||
if (t->m_drawn_since_read.eq(GSVector4i::zero()))
|
||||
{
|
||||
if (draw_rect.rintersect(t->m_valid).eq(draw_rect))
|
||||
if (z_found && draw_rect.rintersect(t->m_valid).eq(draw_rect))
|
||||
return;
|
||||
else
|
||||
continue;
|
||||
@@ -4297,10 +4302,6 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
|
||||
|
||||
Read(t, draw_rect);
|
||||
|
||||
// Getaway (J) stores a Z texture at 0x2800 which it uses and the next frame it stores the reflection map in
|
||||
// 0x2800, so this will misdetect. So if it's not expecting a Z, check for RT's too.
|
||||
z_found = read_start >= t->m_TEX0.TBP0 && read_end <= t->m_end_block && GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth;
|
||||
|
||||
if (draw_rect.rintersect(t->m_drawn_since_read).eq(t->m_drawn_since_read))
|
||||
t->m_drawn_since_read = GSVector4i::zero();
|
||||
}
|
||||
|
||||
@@ -244,6 +244,11 @@ DEFINE_HOTKEY("LoadStateFromSlot", TRANSLATE_NOOP("Hotkeys", "Save States"),
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
SaveStateSelectorUI::LoadCurrentSlot();
|
||||
})
|
||||
DEFINE_HOTKEY("LoadBackupStateFromSlot", TRANSLATE_NOOP("Hotkeys", "Save States"),
|
||||
TRANSLATE_NOOP("Hotkeys", "Load Backup State From Selected Slot"), [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
SaveStateSelectorUI::LoadCurrentBackupSlot();
|
||||
})
|
||||
DEFINE_HOTKEY("SaveStateAndSelectNextSlot", TRANSLATE_NOOP("Hotkeys", "Save States"),
|
||||
TRANSLATE_NOOP("Hotkeys", "Save State and Select Next Slot"), [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
|
||||
@@ -446,7 +446,7 @@ namespace FullscreenUI
|
||||
|
||||
static void InitializePlaceholderSaveStateListEntry(SaveStateListEntry* li, s32 slot);
|
||||
static bool InitializeSaveStateListEntry(
|
||||
SaveStateListEntry* li, const std::string& title, const std::string& serial, u32 crc, s32 slot);
|
||||
SaveStateListEntry* li, const std::string& title, const std::string& serial, u32 crc, s32 slot, bool backup = false);
|
||||
static void ClearSaveStateEntryList();
|
||||
static u32 PopulateSaveStateListEntries(const std::string& title, const std::string& serial, u32 crc);
|
||||
static bool OpenLoadStateSelectorForGame(const std::string& game_path);
|
||||
@@ -3931,13 +3931,8 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
};
|
||||
static const char* s_resolution_options[] = {
|
||||
FSUI_NSTR("Native (PS2)"),
|
||||
FSUI_NSTR("1.25x Native (~450px)"),
|
||||
FSUI_NSTR("1.5x Native (~540px)"),
|
||||
FSUI_NSTR("1.75x Native (~630px)"),
|
||||
FSUI_NSTR("2x Native (~720px/HD)"),
|
||||
FSUI_NSTR("2.5x Native (~900px/HD+)"),
|
||||
FSUI_NSTR("3x Native (~1080px/FHD)"),
|
||||
FSUI_NSTR("3.5x Native (~1260px)"),
|
||||
FSUI_NSTR("4x Native (~1440px/QHD)"),
|
||||
FSUI_NSTR("5x Native (~1800px/QHD+)"),
|
||||
FSUI_NSTR("6x Native (~2160px/4K UHD)"),
|
||||
@@ -3950,13 +3945,8 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
};
|
||||
static const char* s_resolution_values[] = {
|
||||
"1",
|
||||
"1.25",
|
||||
"1.5",
|
||||
"1.75",
|
||||
"2",
|
||||
"2.5",
|
||||
"3",
|
||||
"3.5",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
@@ -5671,9 +5661,9 @@ void FullscreenUI::InitializePlaceholderSaveStateListEntry(SaveStateListEntry* l
|
||||
}
|
||||
|
||||
bool FullscreenUI::InitializeSaveStateListEntry(
|
||||
SaveStateListEntry* li, const std::string& title, const std::string& serial, u32 crc, s32 slot)
|
||||
SaveStateListEntry* li, const std::string& title, const std::string& serial, u32 crc, s32 slot, bool backup)
|
||||
{
|
||||
std::string filename(VMManager::GetSaveStateFileName(serial.c_str(), crc, slot));
|
||||
std::string filename(VMManager::GetSaveStateFileName(serial.c_str(), crc, slot, backup));
|
||||
FILESYSTEM_STAT_DATA sd;
|
||||
if (filename.empty() || !FileSystem::StatFile(filename.c_str(), &sd))
|
||||
{
|
||||
@@ -5681,7 +5671,7 @@ bool FullscreenUI::InitializeSaveStateListEntry(
|
||||
return false;
|
||||
}
|
||||
|
||||
li->title = fmt::format("{}##game_slot_{}", TinyString::from_format(FSUI_FSTR("Save Slot {0}"), slot), slot);
|
||||
li->title = fmt::format("{}##game_slot_{}", TinyString::from_format(FSUI_FSTR("{0} Slot {1}"), backup ? "Backup Save" : "Save", slot), slot);
|
||||
li->summary = fmt::format(FSUI_FSTR("Saved {}"), TimeToPrintableString(sd.ModificationTime));
|
||||
li->slot = slot;
|
||||
li->timestamp = sd.ModificationTime;
|
||||
@@ -5726,6 +5716,10 @@ u32 FullscreenUI::PopulateSaveStateListEntries(const std::string& title, const s
|
||||
SaveStateListEntry li;
|
||||
if (InitializeSaveStateListEntry(&li, title, serial, crc, i) || !s_save_state_selector_loading)
|
||||
s_save_state_selector_slots.push_back(std::move(li));
|
||||
|
||||
SaveStateListEntry bli;
|
||||
if (InitializeSaveStateListEntry(&bli, title, serial, crc, i, true) || !s_save_state_selector_loading)
|
||||
s_save_state_selector_slots.push_back(std::move(bli));
|
||||
}
|
||||
|
||||
return static_cast<u32>(s_save_state_selector_slots.size());
|
||||
@@ -7854,6 +7848,7 @@ TRANSLATE_NOOP("FullscreenUI", "{} unlabelled patch codes found but not enabled.
|
||||
TRANSLATE_NOOP("FullscreenUI", "This Session: {}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "All Time: {}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Save Slot {0}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{0} Slot {1}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Saved {}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} does not exist.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} deleted.");
|
||||
|
||||
@@ -1107,6 +1107,14 @@ void SaveStateSelectorUI::LoadCurrentSlot()
|
||||
Close();
|
||||
}
|
||||
|
||||
void SaveStateSelectorUI::LoadCurrentBackupSlot()
|
||||
{
|
||||
Host::RunOnCPUThread([slot = GetCurrentSlot()]() {
|
||||
VMManager::LoadStateFromSlot(slot, true);
|
||||
});
|
||||
Close();
|
||||
}
|
||||
|
||||
void SaveStateSelectorUI::SaveCurrentSlot()
|
||||
{
|
||||
Host::RunOnCPUThread([slot = GetCurrentSlot()]() {
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace SaveStateSelectorUI
|
||||
|
||||
s32 GetCurrentSlot();
|
||||
void LoadCurrentSlot();
|
||||
void LoadCurrentBackupSlot();
|
||||
void SaveCurrentSlot();
|
||||
} // namespace SaveStateSelectorUI
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace VMManager
|
||||
static bool HasValidOrInitializingVM();
|
||||
static void PrecacheCDVDFile();
|
||||
|
||||
static std::string GetCurrentSaveStateFileName(s32 slot);
|
||||
static std::string GetCurrentSaveStateFileName(s32 slot, bool backup = false);
|
||||
static bool DoLoadState(const char* filename);
|
||||
static bool DoSaveState(const char* filename, s32 slot_for_message, bool zip_on_thread, bool backup_old_state);
|
||||
static void ZipSaveState(std::unique_ptr<ArchiveEntryList> elist,
|
||||
@@ -1762,13 +1762,15 @@ bool SaveStateBase::vmFreeze()
|
||||
return IsOkay();
|
||||
}
|
||||
|
||||
std::string VMManager::GetSaveStateFileName(const char* game_serial, u32 game_crc, s32 slot)
|
||||
std::string VMManager::GetSaveStateFileName(const char* game_serial, u32 game_crc, s32 slot, bool backup)
|
||||
{
|
||||
std::string filename;
|
||||
if (std::strlen(game_serial) > 0)
|
||||
{
|
||||
if (slot < 0)
|
||||
filename = fmt::format("{} ({:08X}).resume.p2s", game_serial, game_crc);
|
||||
else if (backup)
|
||||
filename = fmt::format("{} ({:08X}).{:02d}.p2s.backup", game_serial, game_crc, slot);
|
||||
else
|
||||
filename = fmt::format("{} ({:08X}).{:02d}.p2s", game_serial, game_crc, slot);
|
||||
|
||||
@@ -1778,7 +1780,7 @@ std::string VMManager::GetSaveStateFileName(const char* game_serial, u32 game_cr
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string VMManager::GetSaveStateFileName(const char* filename, s32 slot)
|
||||
std::string VMManager::GetSaveStateFileName(const char* filename, s32 slot, bool backup)
|
||||
{
|
||||
pxAssertRel(!HasValidVM(), "Should not have a VM when calling the non-gamelist GetSaveStateFileName()");
|
||||
|
||||
@@ -1786,7 +1788,7 @@ std::string VMManager::GetSaveStateFileName(const char* filename, s32 slot)
|
||||
std::string serial;
|
||||
u32 crc;
|
||||
if (GameList::GetSerialAndCRCForFilename(filename, &serial, &crc))
|
||||
ret = GetSaveStateFileName(serial.c_str(), crc, slot);
|
||||
ret = GetSaveStateFileName(serial.c_str(), crc, slot, backup);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1797,10 +1799,10 @@ bool VMManager::HasSaveStateInSlot(const char* game_serial, u32 game_crc, s32 sl
|
||||
return (!filename.empty() && FileSystem::FileExists(filename.c_str()));
|
||||
}
|
||||
|
||||
std::string VMManager::GetCurrentSaveStateFileName(s32 slot)
|
||||
std::string VMManager::GetCurrentSaveStateFileName(s32 slot, bool backup)
|
||||
{
|
||||
std::unique_lock lock(s_info_mutex);
|
||||
return GetSaveStateFileName(s_disc_serial.c_str(), s_disc_crc, slot);
|
||||
return GetSaveStateFileName(s_disc_serial.c_str(), s_disc_crc, slot, backup);
|
||||
}
|
||||
|
||||
bool VMManager::DoLoadState(const char* filename)
|
||||
@@ -1840,7 +1842,7 @@ bool VMManager::DoSaveState(const char* filename, s32 slot_for_message, bool zip
|
||||
if (!elist)
|
||||
{
|
||||
Host::AddIconOSDMessage(std::move(osd_key), ICON_FA_EXCLAMATION_TRIANGLE,
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Failed to save save state: {}."), error.GetDescription()),
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Failed to save state: {}."), error.GetDescription()),
|
||||
Host::OSD_ERROR_DURATION);
|
||||
return false;
|
||||
}
|
||||
@@ -1895,7 +1897,7 @@ void VMManager::ZipSaveState(std::unique_ptr<ArchiveEntryList> elist,
|
||||
else
|
||||
{
|
||||
Host::AddIconOSDMessage(std::move(osd_key), ICON_FA_EXCLAMATION_TRIANGLE,
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Failed to save save state to slot {}."), slot_for_message,
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Failed to save state to slot {}."), slot_for_message,
|
||||
Host::OSD_ERROR_DURATION));
|
||||
}
|
||||
|
||||
@@ -1987,13 +1989,13 @@ bool VMManager::LoadState(const char* filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VMManager::LoadStateFromSlot(s32 slot)
|
||||
bool VMManager::LoadStateFromSlot(s32 slot, bool backup)
|
||||
{
|
||||
const std::string filename = GetCurrentSaveStateFileName(slot);
|
||||
const std::string filename = GetCurrentSaveStateFileName(slot, backup);
|
||||
if (filename.empty() || !FileSystem::FileExists(filename.c_str()))
|
||||
{
|
||||
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE,
|
||||
fmt::format(TRANSLATE_FS("VMManager", "There is no save state in slot {}."), slot),
|
||||
fmt::format(TRANSLATE_FS("VMManager", "There is no saved {} in slot {}."), backup ? TRANSLATE("VMManager", "backup state") : "state", slot),
|
||||
Host::OSD_QUICK_DURATION);
|
||||
return false;
|
||||
}
|
||||
@@ -2011,13 +2013,13 @@ bool VMManager::LoadStateFromSlot(s32 slot)
|
||||
if (MemcardBusy::IsBusy())
|
||||
{
|
||||
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_EXCLAMATION_TRIANGLE,
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Failed to load state from slot {} (Memory card is busy)"), slot),
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Failed to load {} from slot {} (Memory card is busy)"), backup ? TRANSLATE("VMManager", "backup state") : TRANSLATE("VMManager", "state"), slot),
|
||||
Host::OSD_QUICK_DURATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
Host::AddIconOSDMessage("LoadStateFromSlot", ICON_FA_FOLDER_OPEN,
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Loading state from slot {}..."), slot), Host::OSD_QUICK_DURATION);
|
||||
fmt::format(TRANSLATE_FS("VMManager", "Loading {} from slot {}..."), backup ? TRANSLATE("VMManager", "backup state") : TRANSLATE("VMManager", "state"), slot), Host::OSD_QUICK_DURATION);
|
||||
return DoLoadState(filename.c_str());
|
||||
}
|
||||
|
||||
@@ -2594,7 +2596,7 @@ void VMManager::ShutdownCPUProviders()
|
||||
#else
|
||||
// See the comment in the InitializeCPUProviders for an explaination why we
|
||||
// still need to manage the MTVU thread.
|
||||
if(vu1Thread.IsOpen())
|
||||
if (vu1Thread.IsOpen())
|
||||
vu1Thread.WaitVU();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -118,10 +118,10 @@ namespace VMManager
|
||||
void ReloadInputBindings(bool force = false);
|
||||
|
||||
/// Returns the save state filename for the given game serial/crc.
|
||||
std::string GetSaveStateFileName(const char* game_serial, u32 game_crc, s32 slot);
|
||||
std::string GetSaveStateFileName(const char* game_serial, u32 game_crc, s32 slot, bool backup = false);
|
||||
|
||||
/// Returns the path to save state for the specified disc/elf.
|
||||
std::string GetSaveStateFileName(const char* filename, s32 slot);
|
||||
std::string GetSaveStateFileName(const char* filename, s32 slot, bool backup = false);
|
||||
|
||||
/// Returns true if there is a save state in the specified slot.
|
||||
bool HasSaveStateInSlot(const char* game_serial, u32 game_crc, s32 slot);
|
||||
@@ -130,7 +130,7 @@ namespace VMManager
|
||||
bool LoadState(const char* filename);
|
||||
|
||||
/// Loads state from the specified slot.
|
||||
bool LoadStateFromSlot(s32 slot);
|
||||
bool LoadStateFromSlot(s32 slot, bool backup = false);
|
||||
|
||||
/// Saves state to the specified filename.
|
||||
bool SaveState(const char* filename, bool zip_on_thread = true, bool backup_old_state = false);
|
||||
|
||||
Reference in New Issue
Block a user