Use config changed callback to detect SD insertion/ejection

This saves the GUI from having to manually call SDIO_EventNotify.
With that out of the way, we can let users change the
"Insert SD Card" setting on Android while a game is running.
This commit is contained in:
JosJuice 2022-01-25 22:04:58 +01:00
parent db0ca3fc96
commit 90c576e075
6 changed files with 40 additions and 31 deletions

View File

@ -228,7 +228,6 @@ public enum BooleanSetting implements AbstractBooleanSetting
MAIN_CPU_THREAD,
MAIN_ENABLE_CHEATS,
MAIN_OVERRIDE_REGION_SETTINGS,
MAIN_WII_SD_CARD, // Can actually be changed, but specialized code is required
MAIN_MMU,
MAIN_DSP_JIT,
};

View File

@ -63,7 +63,6 @@ static std::unique_ptr<EmulationKernel> s_ios;
constexpr u64 ENQUEUE_REQUEST_FLAG = 0x100000000ULL;
static CoreTiming::EventType* s_event_enqueue;
static CoreTiming::EventType* s_event_sdio_notify;
static CoreTiming::EventType* s_event_finish_ppc_bootstrap;
static CoreTiming::EventType* s_event_finish_ios_boot;
@ -789,14 +788,6 @@ void Kernel::UpdateWantDeterminism(const bool new_want_determinism)
device.second->UpdateWantDeterminism(new_want_determinism);
}
void Kernel::SDIO_EventNotify()
{
// TODO: Potential race condition: If IsRunning() becomes false after
// it's checked, an event may be scheduled after CoreTiming shuts down.
if (SConfig::GetInstance().bWii && Core::IsRunning())
CoreTiming::ScheduleEvent(0, s_event_sdio_notify, 0, CoreTiming::FromThread::NON_CPU);
}
void Kernel::DoState(PointerWrap& p)
{
p.Do(m_request_queue);
@ -886,16 +877,6 @@ void Init()
s_ios->HandleIPCEvent(userdata);
});
s_event_sdio_notify = CoreTiming::RegisterEvent("SDIO_EventNotify", [](u64, s64) {
if (!s_ios)
return;
auto sdio_slot0 = s_ios->GetDeviceByName("/dev/sdio/slot0");
auto device = static_cast<SDIOSlot0Device*>(sdio_slot0.get());
if (device)
device->EventNotify();
});
ESDevice::InitializeEmulationState();
s_event_finish_ppc_bootstrap =

View File

@ -125,8 +125,6 @@ public:
std::shared_ptr<FSDevice> GetFSDevice();
std::shared_ptr<ESDevice> GetES();
void SDIO_EventNotify();
void EnqueueIPCRequest(u32 address);
void EnqueueIPCReply(const Request& request, s32 return_value, s64 cycles_in_future = 0,
CoreTiming::FromThread from = CoreTiming::FromThread::CPU);

View File

@ -14,8 +14,10 @@
#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
#include "Common/SDCardUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/IOS.h"
#include "Core/IOS/VersionInfo.h"
@ -27,6 +29,29 @@ SDIOSlot0Device::SDIOSlot0Device(Kernel& ios, const std::string& device_name)
{
if (!Config::Get(Config::MAIN_ALLOW_SD_WRITES))
INFO_LOG_FMT(IOS_SD, "Writes to SD card disabled by user");
m_config_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); });
m_sd_card_inserted = Config::Get(Config::MAIN_WII_SD_CARD);
}
SDIOSlot0Device::~SDIOSlot0Device()
{
Config::RemoveConfigChangedCallback(m_config_callback_id);
}
void SDIOSlot0Device::RefreshConfig()
{
if (m_sd_card_inserted != Config::Get(Config::MAIN_WII_SD_CARD))
{
Core::RunAsCPUThread([this] {
const bool sd_card_inserted = Config::Get(Config::MAIN_WII_SD_CARD);
if (m_sd_card_inserted != sd_card_inserted)
{
m_sd_card_inserted = sd_card_inserted;
EventNotify();
}
});
}
}
void SDIOSlot0Device::DoState(PointerWrap& p)
@ -49,10 +74,14 @@ void SDIOSlot0Device::EventNotify()
if (!m_event)
return;
const bool sd_card_inserted = Config::Get(Config::MAIN_WII_SD_CARD);
if ((sd_card_inserted && m_event->type == EVENT_INSERT) ||
(!sd_card_inserted && m_event->type == EVENT_REMOVE))
if ((m_sd_card_inserted && m_event->type == EVENT_INSERT) ||
(!m_sd_card_inserted && m_event->type == EVENT_REMOVE))
{
if (m_sd_card_inserted)
INFO_LOG_FMT(IOS_SD, "Notifying PPC of SD card insertion");
else
INFO_LOG_FMT(IOS_SD, "Notifying PPC of SD card removal");
m_ios.EnqueueIPCReply(m_event->request, m_event->type);
m_event.reset();
}

View File

@ -22,6 +22,7 @@ class SDIOSlot0Device : public Device
{
public:
SDIOSlot0Device(Kernel& ios, const std::string& device_name);
~SDIOSlot0Device() override;
void DoState(PointerWrap& p) override;
@ -30,8 +31,6 @@ public:
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
void EventNotify();
private:
// SD Host Controller Registers
enum
@ -124,6 +123,10 @@ private:
Request request;
};
void RefreshConfig();
void EventNotify();
IPCReply WriteHCRegister(const IOCtlRequest& request);
IPCReply ReadHCRegister(const IOCtlRequest& request);
IPCReply ResetCard(const IOCtlRequest& request);
@ -162,5 +165,8 @@ private:
std::array<u32, 0x200 / sizeof(u32)> m_registers{};
File::IOFile m_card;
size_t m_config_callback_id;
bool m_sd_card_inserted = false;
};
} // namespace IOS::HLE

View File

@ -705,10 +705,6 @@ void Settings::SetSDCardInserted(bool inserted)
{
Config::SetBaseOrCurrent(Config::MAIN_WII_SD_CARD, inserted);
emit SDCardInsertionChanged(inserted);
auto* ios = IOS::HLE::GetIOS();
if (ios)
ios->SDIO_EventNotify();
}
}