Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIO/MCD: hugely improved memcard swapping + reinsertion + Fix per game cards #9033

Merged
merged 2 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
253 changes: 124 additions & 129 deletions pcsx2-qt/Translations/pcsx2-qt_en.ts

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pcsx2/CDVD/CDVD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "IopHw.h"
#include "IopDma.h"
#include "VMManager.h"
#include "Sio.h"

#include <cctype>
#include <ctime>
Expand Down Expand Up @@ -1528,6 +1529,7 @@ void cdvdVsync()
cdvd.RTCcount = 0;

cdvdUpdateTrayState();
AutoEject::CountDownTicks();

cdvd.RTC.second++;
if (cdvd.RTC.second < 60)
Expand Down
50 changes: 36 additions & 14 deletions pcsx2/MemoryCardFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "MemoryCardFile.h"
#include "MemoryCardFolder.h"
#include "Sio.h"

#include "System.h"
#include "Config.h"
Expand Down Expand Up @@ -292,14 +293,11 @@ void FileMemoryCard::Open()
cont = true;
}

if (EmuConfig.Mcd[slot].Type != MemoryCardType::File)
{
str = "[is not memcard file]";
if (EmuConfig.Mcd[slot].Type == MemoryCardType::File)
Console.WriteLn(cont ? Color_Gray : Color_Green, fmt::format("McdSlot {} [File]: {}", slot, str));
else
cont = true;
}

Console.WriteLn(cont ? Color_Gray : Color_Green, "McdSlot %u [File]: %.*s", slot,
static_cast<int>(str.size()), str.data());
if (cont)
continue;

Expand Down Expand Up @@ -622,11 +620,8 @@ uint FileMcd_ConvertToSlot(uint port, uint slot)
return slot + 4; // multitap 2
}

void FileMcd_EmuOpen()
void FileMcd_SetType()
{
if(FileMcd_Open)
return;
FileMcd_Open = true;
// detect inserted memory card types
for (uint slot = 0; slot < 8; ++slot)
{
Expand All @@ -645,6 +640,14 @@ void FileMcd_EmuOpen()
EmuConfig.Mcd[slot].Type = type;
}
}
}

void FileMcd_EmuOpen()
{
if(FileMcd_Open)
return;
FileMcd_Open = true;


Mcd::impl.Open();
Mcd::implFolder.SetFiltering(EmuConfig.McdFolderAutoManage);
Expand All @@ -660,6 +663,20 @@ void FileMcd_EmuClose()
Mcd::impl.Close();
}

void FileMcd_CancelEject()
{
AutoEject::ClearAll();
}

void FileMcd_Reopen(std::string new_serial)
{
Console.WriteLn("Reopening memory cards...");
FileMcd_EmuClose();
FileMcd_SetType();
sioSetGameSerial(new_serial);
FileMcd_EmuOpen();
}

s32 FileMcd_IsPresent(uint port, uint slot)
{
const uint combinedSlot = FileMcd_ConvertToSlot(port, slot);
Expand Down Expand Up @@ -776,20 +793,25 @@ void FileMcd_NextFrame(uint port, uint slot)
}
}

bool FileMcd_ReIndex(uint port, uint slot, const std::string& filter)
int FileMcd_ReIndex(uint port, uint slot, const std::string& filter)
{
const uint combinedSlot = FileMcd_ConvertToSlot(port, slot);
const int combinedSlot = FileMcd_ConvertToSlot(port, slot);

switch (EmuConfig.Mcd[combinedSlot].Type)
{
//case MemoryCardType::File:
// return Mcd::impl.ReIndex( combinedSlot, filter );
// break;
case MemoryCardType::Folder:
return Mcd::implFolder.ReIndex(combinedSlot, EmuConfig.McdFolderAutoManage, filter);
if (!Mcd::implFolder.ReIndex(combinedSlot, EmuConfig.McdFolderAutoManage, filter))
return -1;
break;
default:
return false;
return -1;
break;
}

return combinedSlot;
}

// --------------------------------------------------------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion pcsx2/MemoryCardFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ extern bool FileMcd_IsMultitapSlot(uint slot);
extern std::string FileMcd_GetDefaultName(uint slot);

uint FileMcd_ConvertToSlot(uint port, uint slot);
void FileMcd_SetType();
void FileMcd_EmuOpen();
void FileMcd_EmuClose();
void FileMcd_CancelEject();
void FileMcd_Reopen(std::string new_serial);
s32 FileMcd_IsPresent(uint port, uint slot);
void FileMcd_GetSizeInfo(uint port, uint slot, McdSizeInfo* outways);
bool FileMcd_IsPSX(uint port, uint slot);
Expand All @@ -55,7 +58,7 @@ s32 FileMcd_Save(uint port, uint slot, const u8* src, u32 adr, int size);
s32 FileMcd_EraseBlock(uint port, uint slot, u32 adr);
u64 FileMcd_GetCRC(uint port, uint slot);
void FileMcd_NextFrame(uint port, uint slot);
bool FileMcd_ReIndex(uint port, uint slot, const std::string& filter);
int FileMcd_ReIndex(uint port, uint slot, const std::string& filter);

std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards);
std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view& name);
Expand Down
3 changes: 3 additions & 0 deletions pcsx2/MemoryCardFolder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ void FolderMemoryCard::Close(bool flush)
m_oldDataCache.clear();
m_lastAccessedFile.CloseAll();
m_fileMetadataQuickAccess.clear();
m_isEnabled = false;
}

bool FolderMemoryCard::ReIndex(bool enableFiltering, const std::string& filter)
Expand Down Expand Up @@ -2394,5 +2395,7 @@ bool FolderMemoryCardAggregator::ReIndex(uint slot, const bool enableFiltering,
return true;
}

SetFiltering(enableFiltering);
m_lastKnownFilter = filter;
return false;
}
1 change: 0 additions & 1 deletion pcsx2/Pcsx2Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,6 @@ Pcsx2Config::Pcsx2Config()
{
Mcd[slot].Enabled = !FileMcd_IsMultitapSlot(slot); // enables main 2 slots
Mcd[slot].Filename = FileMcd_GetDefaultName(slot);

// Folder memory card is autodetected later.
Mcd[slot].Type = MemoryCardType::File;
}
Expand Down
50 changes: 27 additions & 23 deletions pcsx2/Sio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,6 @@ void Sio0::SetTxData(u8 value)
if (mcd->autoEjectTicks)
{
SetRxData(0x00);
mcd->autoEjectTicks--;

if (mcd->autoEjectTicks == 0)
{
Host::AddKeyedOSDMessage(fmt::format("AutoEjectSlotClear{}{}", port, slot),
fmt::format(TRANSLATE_SV("MemoryCard", "Memory Card in port %d / slot %d reinserted"),
port + 1, slot + 1),
Host::OSD_INFO_DURATION);
}

return;
}
Expand Down Expand Up @@ -585,16 +576,6 @@ void Sio2::Memcard()
fifoOut.push_back(0x00);
}

mcd->autoEjectTicks--;

if (mcd->autoEjectTicks == 0)
{
Host::AddKeyedOSDMessage(fmt::format("AutoEjectSlotClear{}{}", port, slot),
fmt::format(
TRANSLATE_SV("MemoryCard", "Memory Card in port {} / slot {} reinserted."), port + 1, slot + 1),
Host::OSD_INFO_DURATION);
}

return;
}

Expand Down Expand Up @@ -833,7 +814,8 @@ void sioNextFrame() {
void sioSetGameSerial( const std::string& serial ) {
for ( uint port = 0; port < 2; ++port ) {
for ( uint slot = 0; slot < 4; ++slot ) {
if ( mcds[port][slot].ReIndex( serial ) ) {
if ( int index = mcds[port][slot].ReIndex( serial ) >= 0 ) {
Console.WriteLn("Ejecting Memory Card %u (port %u slot %u) due to source change. Reinsert in 1 second.", index, port, slot);
AutoEject::Set( port, slot );
}
}
Expand Down Expand Up @@ -915,11 +897,33 @@ bool sioPortAndSlotIsMultitap(u32 port, u32 slot)
return (slot != 0);
}

void AutoEject::CountDownTicks()
{
bool reinserted = false;
for (size_t port = 0; port < SIO::PORTS; port++)
{
for (size_t slot = 0; slot < SIO::SLOTS; slot++)
{
if (mcds[port][slot].autoEjectTicks > 0)
{
if (--mcds[port][slot].autoEjectTicks == 0)
{
Host::AddKeyedOSDMessage(fmt::format("AutoEjectSlotClear{}{}", port, slot),
fmt::format(TRANSLATE_SV("MemoryCard", "Memory card in port {} / slot {} reinserted"),
port + 1, slot + 1),
Host::OSD_INFO_DURATION);
}
}
}
}
}

void AutoEject::Set(size_t port, size_t slot)
{
if (EmuConfig.McdEnableEjection)
if (EmuConfig.McdEnableEjection && mcds[port][slot].autoEjectTicks == 0)
{
mcds[port][slot].autoEjectTicks = 60;
mcds[port][slot].autoEjectTicks = 1; // 1 second is enough.
mcds[port][slot].term = 0x55; // Reset terminator to default (0x55), forces the PS2 to recheck the memcard.
}
}

Expand All @@ -931,7 +935,7 @@ void AutoEject::Clear(size_t port, size_t slot)
void AutoEject::SetAll()
{
Host::AddIconOSDMessage("AutoEjectAllSet", ICON_FA_SD_CARD,
TRANSLATE_SV("MemoryCard", "Force ejecting all Memory Cards."), Host::OSD_INFO_DURATION);
TRANSLATE_SV("MemoryCard", "Force ejecting all Memory Cards. Reinserting in 1 second."), Host::OSD_INFO_DURATION);

for (size_t port = 0; port < SIO::PORTS; port++)
{
Expand Down
3 changes: 2 additions & 1 deletion pcsx2/Sio.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct _mcd
FileMcd_NextFrame( port, slot );
}

bool ReIndex(const std::string& filter) {
int ReIndex(const std::string& filter) {
return FileMcd_ReIndex(port, slot, filter);
}
};
Expand Down Expand Up @@ -243,6 +243,7 @@ extern void sioSetGameSerial(const std::string& serial);

namespace AutoEject
{
extern void CountDownTicks();
extern void Set(size_t port, size_t slot);
extern void Clear(size_t port, size_t slot);
extern void SetAll();
Expand Down
43 changes: 20 additions & 23 deletions pcsx2/VMManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,9 +627,16 @@ void VMManager::Internal::UpdateEmuFolders()

if (EmuFolders::MemoryCards != old_memcards_directory)
{
FileMcd_EmuClose();
FileMcd_EmuOpen();
std::string memcardFilters = "";
if (const GameDatabaseSchema::GameEntry* game = GameDatabase::findGame(s_disc_serial))
{
memcardFilters = game->memcardFiltersAsString();
}

AutoEject::SetAll();

if(!GSDumpReplayer::IsReplayingDump())
FileMcd_Reopen(memcardFilters.empty() ? s_disc_serial : memcardFilters);
}

if (EmuFolders::Textures != old_textures_directory)
Expand Down Expand Up @@ -882,13 +889,6 @@ void VMManager::UpdateDiscDetails(bool booting)
Console.WriteLn(Color_StrongGreen, fmt::format(" Version: {}", s_disc_version));
Console.WriteLn(Color_StrongGreen, fmt::format(" CRC: {:08X}", s_disc_crc));

sioSetGameSerial(memcardFilters.empty() ? s_disc_serial : memcardFilters);

// If we don't reset the timer here, when using folder memcards the reindex will cause an eject,
// which a bunch of games don't like since they access the memory card on boot.
if (booting)
AutoEject::ClearAll();

UpdateGameSettingsLayer();
ApplySettings();

Expand All @@ -903,6 +903,9 @@ void VMManager::UpdateDiscDetails(bool booting)
Achievements::GameChanged(s_disc_crc, s_current_crc);
ReloadPINE();
UpdateDiscordPresence(Achievements::GetRichPresenceString());

if (!GSDumpReplayer::IsReplayingDump())
FileMcd_Reopen(memcardFilters.empty() ? s_disc_serial : memcardFilters);
}

void VMManager::ClearDiscDetails()
Expand Down Expand Up @@ -1145,17 +1148,11 @@ bool VMManager::Initialize(VMBootParameters boot_params)
}
ScopedGuard close_cdvd(&DoCDVDclose);

// Must be before updating serial because of folder memcards.
if (!GSDumpReplayer::IsReplayingDump())
{
Console.WriteLn("Opening Memory cards...");
FileMcd_EmuOpen();
}
ScopedGuard close_memcards(&FileMcd_EmuClose);

// Figure out which game we're running! This also loads game settings.
UpdateDiscDetails(true);

ScopedGuard close_memcards(&FileMcd_EmuClose);

// Read fast boot setting late so it can be overridden per-game.
// ELFs must be fast booted, and GS dumps are never fast booted.
s_fast_boot_requested =
Expand Down Expand Up @@ -1958,7 +1955,9 @@ void VMManager::Internal::EntryPointCompilingOnCPUThread()
HandleELFChange(true);

Patch::ApplyLoadedPatches(Patch::PPT_ONCE_ON_LOAD);

// If the config changes at this point, it's a reset, so the game doesn't currently know about the memcard
// so there's no need to leave the eject running.
FileMcd_CancelEject();
// Toss all the recs, we're going to be executing new code.
SysClearExecutionCache();
}
Expand Down Expand Up @@ -2113,9 +2112,6 @@ void VMManager::CheckForMemoryCardConfigChanges(const Pcsx2Config& old_config)

Console.WriteLn("Updating memory card configuration");

FileMcd_EmuClose();
FileMcd_EmuOpen();

// force card eject when files change
for (u32 port = 0; port < 2; port++)
{
Expand All @@ -2130,7 +2126,6 @@ void VMManager::CheckForMemoryCardConfigChanges(const Pcsx2Config& old_config)
}
}
}

// force reindexing, mc folder code is janky
std::string sioSerial;
{
Expand All @@ -2140,7 +2135,9 @@ void VMManager::CheckForMemoryCardConfigChanges(const Pcsx2Config& old_config)
if (sioSerial.empty())
sioSerial = s_disc_serial;
}
sioSetGameSerial(sioSerial);

if (!GSDumpReplayer::IsReplayingDump())
FileMcd_Reopen(sioSerial);
}

void VMManager::CheckForMiscConfigChanges(const Pcsx2Config& old_config)
Expand Down