Merge pull request #11029 from AdmiralCurtiss/global-state-dvd
HW: Move DVD variables to Core::System.
This commit is contained in:
commit
74851fe94a
File diff suppressed because it is too large
Load Diff
|
@ -23,6 +23,23 @@ class Mapping;
|
||||||
|
|
||||||
namespace DVDInterface
|
namespace DVDInterface
|
||||||
{
|
{
|
||||||
|
class DVDInterfaceState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DVDInterfaceState();
|
||||||
|
DVDInterfaceState(const DVDInterfaceState&) = delete;
|
||||||
|
DVDInterfaceState(DVDInterfaceState&&) = delete;
|
||||||
|
DVDInterfaceState& operator=(const DVDInterfaceState&) = delete;
|
||||||
|
DVDInterfaceState& operator=(DVDInterfaceState&&) = delete;
|
||||||
|
~DVDInterfaceState();
|
||||||
|
|
||||||
|
struct Data;
|
||||||
|
Data& GetData() { return *m_data; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Data> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
enum class DICommand : u8
|
enum class DICommand : u8
|
||||||
{
|
{
|
||||||
Inquiry = 0x12,
|
Inquiry = 0x12,
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
#include "Core/IOS/ES/Formats.h"
|
#include "Core/IOS/ES/Formats.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#include "DiscIO/Enums.h"
|
#include "DiscIO/Enums.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
@ -61,8 +62,8 @@ struct ReadRequest
|
||||||
|
|
||||||
using ReadResult = std::pair<ReadRequest, std::vector<u8>>;
|
using ReadResult = std::pair<ReadRequest, std::vector<u8>>;
|
||||||
|
|
||||||
static void StartDVDThread();
|
static void StartDVDThread(DVDThreadState::Data& state);
|
||||||
static void StopDVDThread();
|
static void StopDVDThread(DVDThreadState::Data& state);
|
||||||
|
|
||||||
static void DVDThread();
|
static void DVDThread();
|
||||||
static void WaitUntilIdle();
|
static void WaitUntilIdle();
|
||||||
|
@ -72,82 +73,97 @@ static void StartReadInternal(bool copy_to_ram, u32 output_address, u64 dvd_offs
|
||||||
DVDInterface::ReplyType reply_type, s64 ticks_until_completion);
|
DVDInterface::ReplyType reply_type, s64 ticks_until_completion);
|
||||||
|
|
||||||
static void FinishRead(u64 id, s64 cycles_late);
|
static void FinishRead(u64 id, s64 cycles_late);
|
||||||
static CoreTiming::EventType* s_finish_read;
|
|
||||||
|
|
||||||
static u64 s_next_id = 0;
|
struct DVDThreadState::Data
|
||||||
|
{
|
||||||
|
CoreTiming::EventType* finish_read;
|
||||||
|
|
||||||
static std::thread s_dvd_thread;
|
u64 next_id = 0;
|
||||||
static Common::Event s_request_queue_expanded; // Is set by CPU thread
|
|
||||||
static Common::Event s_result_queue_expanded; // Is set by DVD thread
|
|
||||||
static Common::Flag s_dvd_thread_exiting(false); // Is set by CPU thread
|
|
||||||
|
|
||||||
static Common::SPSCQueue<ReadRequest, false> s_request_queue;
|
std::thread dvd_thread;
|
||||||
static Common::SPSCQueue<ReadResult, false> s_result_queue;
|
Common::Event request_queue_expanded; // Is set by CPU thread
|
||||||
static std::map<u64, ReadResult> s_result_map;
|
Common::Event result_queue_expanded; // Is set by DVD thread
|
||||||
|
Common::Flag dvd_thread_exiting = Common::Flag(false); // Is set by CPU thread
|
||||||
|
|
||||||
static std::unique_ptr<DiscIO::Volume> s_disc;
|
Common::SPSCQueue<ReadRequest, false> request_queue;
|
||||||
|
Common::SPSCQueue<ReadResult, false> result_queue;
|
||||||
|
std::map<u64, ReadResult> result_map;
|
||||||
|
|
||||||
|
std::unique_ptr<DiscIO::Volume> disc;
|
||||||
|
};
|
||||||
|
|
||||||
|
DVDThreadState::DVDThreadState() : m_data(std::make_unique<Data>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DVDThreadState::~DVDThreadState() = default;
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
s_finish_read = CoreTiming::RegisterEvent("FinishReadDVDThread", FinishRead);
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
s_request_queue_expanded.Reset();
|
state.finish_read = CoreTiming::RegisterEvent("FinishReadDVDThread", FinishRead);
|
||||||
s_result_queue_expanded.Reset();
|
|
||||||
s_request_queue.Clear();
|
state.request_queue_expanded.Reset();
|
||||||
s_result_queue.Clear();
|
state.result_queue_expanded.Reset();
|
||||||
|
state.request_queue.Clear();
|
||||||
|
state.result_queue.Clear();
|
||||||
|
|
||||||
// This is reset on every launch for determinism, but it doesn't matter
|
// This is reset on every launch for determinism, but it doesn't matter
|
||||||
// much, because this will never get exposed to the emulated game.
|
// much, because this will never get exposed to the emulated game.
|
||||||
s_next_id = 0;
|
state.next_id = 0;
|
||||||
|
|
||||||
StartDVDThread();
|
StartDVDThread(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartDVDThread()
|
static void StartDVDThread(DVDThreadState::Data& state)
|
||||||
{
|
{
|
||||||
ASSERT(!s_dvd_thread.joinable());
|
ASSERT(!state.dvd_thread.joinable());
|
||||||
s_dvd_thread_exiting.Clear();
|
state.dvd_thread_exiting.Clear();
|
||||||
s_dvd_thread = std::thread(DVDThread);
|
state.dvd_thread = std::thread(DVDThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stop()
|
void Stop()
|
||||||
{
|
{
|
||||||
StopDVDThread();
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
s_disc.reset();
|
StopDVDThread(state);
|
||||||
|
state.disc.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StopDVDThread()
|
static void StopDVDThread(DVDThreadState::Data& state)
|
||||||
{
|
{
|
||||||
ASSERT(s_dvd_thread.joinable());
|
ASSERT(state.dvd_thread.joinable());
|
||||||
|
|
||||||
// By setting s_DVD_thread_exiting, we ask the DVD thread to cleanly exit.
|
// By setting dvd_thread_exiting, we ask the DVD thread to cleanly exit.
|
||||||
// In case the request queue is empty, we need to set s_request_queue_expanded
|
// In case the request queue is empty, we need to set request_queue_expanded
|
||||||
// so that the DVD thread will wake up and check s_DVD_thread_exiting.
|
// so that the DVD thread will wake up and check dvd_thread_exiting.
|
||||||
s_dvd_thread_exiting.Set();
|
state.dvd_thread_exiting.Set();
|
||||||
s_request_queue_expanded.Set();
|
state.request_queue_expanded.Set();
|
||||||
|
|
||||||
s_dvd_thread.join();
|
state.dvd_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoState(PointerWrap& p)
|
void DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
// By waiting for the DVD thread to be done working, we ensure
|
// By waiting for the DVD thread to be done working, we ensure
|
||||||
// that s_request_queue will be empty and that the DVD thread
|
// that request_queue will be empty and that the DVD thread
|
||||||
// won't be touching anything while this function runs.
|
// won't be touching anything while this function runs.
|
||||||
WaitUntilIdle();
|
WaitUntilIdle();
|
||||||
|
|
||||||
// Move all results from s_result_queue to s_result_map because
|
// Move all results from result_queue to result_map because
|
||||||
// PointerWrap::Do supports std::map but not Common::SPSCQueue.
|
// PointerWrap::Do supports std::map but not Common::SPSCQueue.
|
||||||
// This won't affect the behavior of FinishRead.
|
// This won't affect the behavior of FinishRead.
|
||||||
ReadResult result;
|
ReadResult result;
|
||||||
while (s_result_queue.Pop(result))
|
while (state.result_queue.Pop(result))
|
||||||
s_result_map.emplace(result.first.id, std::move(result));
|
state.result_map.emplace(result.first.id, std::move(result));
|
||||||
|
|
||||||
// Both queues are now empty, so we don't need to savestate them.
|
// Both queues are now empty, so we don't need to savestate them.
|
||||||
p.Do(s_result_map);
|
p.Do(state.result_map);
|
||||||
p.Do(s_next_id);
|
p.Do(state.next_id);
|
||||||
|
|
||||||
// s_disc isn't savestated (because it points to files on the
|
// state.disc isn't savestated (because it points to files on the
|
||||||
// local system). Instead, we check that the status of the disc
|
// local system). Instead, we check that the status of the disc
|
||||||
// is the same as when the savestate was made. This won't catch
|
// is the same as when the savestate was made. This won't catch
|
||||||
// cases of having the wrong disc inserted, though.
|
// cases of having the wrong disc inserted, though.
|
||||||
|
@ -159,7 +175,7 @@ void DoState(PointerWrap& p)
|
||||||
if (had_disc)
|
if (had_disc)
|
||||||
PanicAlertFmtT("An inserted disc was expected but not found.");
|
PanicAlertFmtT("An inserted disc was expected but not found.");
|
||||||
else
|
else
|
||||||
s_disc.reset();
|
state.disc.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Savestates can be smaller if the buffers of results aren't saved,
|
// TODO: Savestates can be smaller if the buffers of results aren't saved,
|
||||||
|
@ -175,70 +191,82 @@ void DoState(PointerWrap& p)
|
||||||
|
|
||||||
void SetDisc(std::unique_ptr<DiscIO::Volume> disc)
|
void SetDisc(std::unique_ptr<DiscIO::Volume> disc)
|
||||||
{
|
{
|
||||||
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
WaitUntilIdle();
|
WaitUntilIdle();
|
||||||
s_disc = std::move(disc);
|
state.disc = std::move(disc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasDisc()
|
bool HasDisc()
|
||||||
{
|
{
|
||||||
return s_disc != nullptr;
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
return state.disc != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasWiiHashes()
|
bool HasWiiHashes()
|
||||||
{
|
{
|
||||||
// HasWiiHashes is thread-safe, so calling WaitUntilIdle isn't necessary.
|
// HasWiiHashes is thread-safe, so calling WaitUntilIdle isn't necessary.
|
||||||
return s_disc->HasWiiHashes();
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
return state.disc->HasWiiHashes();
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscIO::Platform GetDiscType()
|
DiscIO::Platform GetDiscType()
|
||||||
{
|
{
|
||||||
// GetVolumeType is thread-safe, so calling WaitUntilIdle isn't necessary.
|
// GetVolumeType is thread-safe, so calling WaitUntilIdle isn't necessary.
|
||||||
return s_disc->GetVolumeType();
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
return state.disc->GetVolumeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 PartitionOffsetToRawOffset(u64 offset, const DiscIO::Partition& partition)
|
u64 PartitionOffsetToRawOffset(u64 offset, const DiscIO::Partition& partition)
|
||||||
{
|
{
|
||||||
// PartitionOffsetToRawOffset is thread-safe, so calling WaitUntilIdle isn't necessary.
|
// PartitionOffsetToRawOffset is thread-safe, so calling WaitUntilIdle isn't necessary.
|
||||||
return s_disc->PartitionOffsetToRawOffset(offset, partition);
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
return state.disc->PartitionOffsetToRawOffset(offset, partition);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOS::ES::TMDReader GetTMD(const DiscIO::Partition& partition)
|
IOS::ES::TMDReader GetTMD(const DiscIO::Partition& partition)
|
||||||
{
|
{
|
||||||
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
WaitUntilIdle();
|
WaitUntilIdle();
|
||||||
return s_disc->GetTMD(partition);
|
return state.disc->GetTMD(partition);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOS::ES::TicketReader GetTicket(const DiscIO::Partition& partition)
|
IOS::ES::TicketReader GetTicket(const DiscIO::Partition& partition)
|
||||||
{
|
{
|
||||||
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
WaitUntilIdle();
|
WaitUntilIdle();
|
||||||
return s_disc->GetTicket(partition);
|
return state.disc->GetTicket(partition);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsInsertedDiscRunning()
|
bool IsInsertedDiscRunning()
|
||||||
{
|
{
|
||||||
if (!s_disc)
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
|
if (!state.disc)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WaitUntilIdle();
|
WaitUntilIdle();
|
||||||
|
|
||||||
return SConfig::GetInstance().GetGameID() == s_disc->GetGameID();
|
return SConfig::GetInstance().GetGameID() == state.disc->GetGameID();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdateRunningGameMetadata(const DiscIO::Partition& partition, std::optional<u64> title_id)
|
bool UpdateRunningGameMetadata(const DiscIO::Partition& partition, std::optional<u64> title_id)
|
||||||
{
|
{
|
||||||
if (!s_disc)
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
|
if (!state.disc)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WaitUntilIdle();
|
WaitUntilIdle();
|
||||||
|
|
||||||
if (title_id)
|
if (title_id)
|
||||||
{
|
{
|
||||||
const std::optional<u64> volume_title_id = s_disc->GetTitleID(partition);
|
const std::optional<u64> volume_title_id = state.disc->GetTitleID(partition);
|
||||||
if (!volume_title_id || *volume_title_id != *title_id)
|
if (!volume_title_id || *volume_title_id != *title_id)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SConfig::GetInstance().SetRunningGameMetadata(*s_disc, partition);
|
SConfig::GetInstance().SetRunningGameMetadata(*state.disc, partition);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,11 +274,13 @@ void WaitUntilIdle()
|
||||||
{
|
{
|
||||||
ASSERT(Core::IsCPUThread());
|
ASSERT(Core::IsCPUThread());
|
||||||
|
|
||||||
while (!s_request_queue.Empty())
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
s_result_queue_expanded.Wait();
|
|
||||||
|
|
||||||
StopDVDThread();
|
while (!state.request_queue.Empty())
|
||||||
StartDVDThread();
|
state.result_queue_expanded.Wait();
|
||||||
|
|
||||||
|
StopDVDThread(state);
|
||||||
|
StartDVDThread(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartRead(u64 dvd_offset, u32 length, const DiscIO::Partition& partition,
|
void StartRead(u64 dvd_offset, u32 length, const DiscIO::Partition& partition,
|
||||||
|
@ -273,6 +303,8 @@ static void StartReadInternal(bool copy_to_ram, u32 output_address, u64 dvd_offs
|
||||||
{
|
{
|
||||||
ASSERT(Core::IsCPUThread());
|
ASSERT(Core::IsCPUThread());
|
||||||
|
|
||||||
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
ReadRequest request;
|
ReadRequest request;
|
||||||
|
|
||||||
request.copy_to_ram = copy_to_ram;
|
request.copy_to_ram = copy_to_ram;
|
||||||
|
@ -282,21 +314,23 @@ static void StartReadInternal(bool copy_to_ram, u32 output_address, u64 dvd_offs
|
||||||
request.partition = partition;
|
request.partition = partition;
|
||||||
request.reply_type = reply_type;
|
request.reply_type = reply_type;
|
||||||
|
|
||||||
u64 id = s_next_id++;
|
u64 id = state.next_id++;
|
||||||
request.id = id;
|
request.id = id;
|
||||||
|
|
||||||
request.time_started_ticks = CoreTiming::GetTicks();
|
request.time_started_ticks = CoreTiming::GetTicks();
|
||||||
request.realtime_started_us = Common::Timer::NowUs();
|
request.realtime_started_us = Common::Timer::NowUs();
|
||||||
|
|
||||||
s_request_queue.Push(std::move(request));
|
state.request_queue.Push(std::move(request));
|
||||||
s_request_queue_expanded.Set();
|
state.request_queue_expanded.Set();
|
||||||
|
|
||||||
CoreTiming::ScheduleEvent(ticks_until_completion, s_finish_read, id);
|
CoreTiming::ScheduleEvent(ticks_until_completion, state.finish_read, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FinishRead(u64 id, s64 cycles_late)
|
static void FinishRead(u64 id, s64 cycles_late)
|
||||||
{
|
{
|
||||||
// We can't simply pop s_result_queue and always get the ReadResult
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
|
// We can't simply pop result_queue and always get the ReadResult
|
||||||
// we want, because the DVD thread may add ReadResults to the queue
|
// we want, because the DVD thread may add ReadResults to the queue
|
||||||
// in a different order than we want to get them. What we do instead
|
// in a different order than we want to get them. What we do instead
|
||||||
// is to pop the queue until we find the ReadResult we want (the one
|
// is to pop the queue until we find the ReadResult we want (the one
|
||||||
|
@ -307,23 +341,23 @@ static void FinishRead(u64 id, s64 cycles_late)
|
||||||
// When this function is called again later, it will check the map for
|
// When this function is called again later, it will check the map for
|
||||||
// the wanted ReadResult before it starts searching through the queue.
|
// the wanted ReadResult before it starts searching through the queue.
|
||||||
ReadResult result;
|
ReadResult result;
|
||||||
auto it = s_result_map.find(id);
|
auto it = state.result_map.find(id);
|
||||||
if (it != s_result_map.end())
|
if (it != state.result_map.end())
|
||||||
{
|
{
|
||||||
result = std::move(it->second);
|
result = std::move(it->second);
|
||||||
s_result_map.erase(it);
|
state.result_map.erase(it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
while (!s_result_queue.Pop(result))
|
while (!state.result_queue.Pop(result))
|
||||||
s_result_queue_expanded.Wait();
|
state.result_queue_expanded.Wait();
|
||||||
|
|
||||||
if (result.first.id == id)
|
if (result.first.id == id)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
s_result_map.emplace(result.first.id, std::move(result));
|
state.result_map.emplace(result.first.id, std::move(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We have now obtained the right ReadResult.
|
// We have now obtained the right ReadResult.
|
||||||
|
@ -363,30 +397,32 @@ static void FinishRead(u64 id, s64 cycles_late)
|
||||||
|
|
||||||
static void DVDThread()
|
static void DVDThread()
|
||||||
{
|
{
|
||||||
|
auto& state = Core::System::GetInstance().GetDVDThreadState().GetData();
|
||||||
|
|
||||||
Common::SetCurrentThreadName("DVD thread");
|
Common::SetCurrentThreadName("DVD thread");
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
s_request_queue_expanded.Wait();
|
state.request_queue_expanded.Wait();
|
||||||
|
|
||||||
if (s_dvd_thread_exiting.IsSet())
|
if (state.dvd_thread_exiting.IsSet())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ReadRequest request;
|
ReadRequest request;
|
||||||
while (s_request_queue.Pop(request))
|
while (state.request_queue.Pop(request))
|
||||||
{
|
{
|
||||||
FileMonitor::Log(*s_disc, request.partition, request.dvd_offset);
|
FileMonitor::Log(*state.disc, request.partition, request.dvd_offset);
|
||||||
|
|
||||||
std::vector<u8> buffer(request.length);
|
std::vector<u8> buffer(request.length);
|
||||||
if (!s_disc->Read(request.dvd_offset, request.length, buffer.data(), request.partition))
|
if (!state.disc->Read(request.dvd_offset, request.length, buffer.data(), request.partition))
|
||||||
buffer.resize(0);
|
buffer.resize(0);
|
||||||
|
|
||||||
request.realtime_done_us = Common::Timer::NowUs();
|
request.realtime_done_us = Common::Timer::NowUs();
|
||||||
|
|
||||||
s_result_queue.Push(ReadResult(std::move(request), std::move(buffer)));
|
state.result_queue.Push(ReadResult(std::move(request), std::move(buffer)));
|
||||||
s_result_queue_expanded.Set();
|
state.result_queue_expanded.Set();
|
||||||
|
|
||||||
if (s_dvd_thread_exiting.IsSet())
|
if (state.dvd_thread_exiting.IsSet())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,23 @@ class TicketReader;
|
||||||
|
|
||||||
namespace DVDThread
|
namespace DVDThread
|
||||||
{
|
{
|
||||||
|
class DVDThreadState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DVDThreadState();
|
||||||
|
DVDThreadState(const DVDThreadState&) = delete;
|
||||||
|
DVDThreadState(DVDThreadState&&) = delete;
|
||||||
|
DVDThreadState& operator=(const DVDThreadState&) = delete;
|
||||||
|
DVDThreadState& operator=(DVDThreadState&&) = delete;
|
||||||
|
~DVDThreadState();
|
||||||
|
|
||||||
|
struct Data;
|
||||||
|
Data& GetData() { return *m_data; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Data> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "AudioCommon/SoundStream.h"
|
#include "AudioCommon/SoundStream.h"
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
|
#include "Core/HW/DVD/DVDInterface.h"
|
||||||
|
#include "Core/HW/DVD/DVDThread.h"
|
||||||
|
|
||||||
namespace Core
|
namespace Core
|
||||||
{
|
{
|
||||||
|
@ -15,6 +17,9 @@ struct System::Impl
|
||||||
std::unique_ptr<SoundStream> m_sound_stream;
|
std::unique_ptr<SoundStream> m_sound_stream;
|
||||||
bool m_sound_stream_running = false;
|
bool m_sound_stream_running = false;
|
||||||
bool m_audio_dump_started = false;
|
bool m_audio_dump_started = false;
|
||||||
|
|
||||||
|
DVDInterface::DVDInterfaceState m_dvd_interface_state;
|
||||||
|
DVDThread::DVDThreadState m_dvd_thread_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
System::System() : m_impl{std::make_unique<Impl>()}
|
System::System() : m_impl{std::make_unique<Impl>()}
|
||||||
|
@ -58,4 +63,14 @@ void System::SetAudioDumpStarted(bool started)
|
||||||
{
|
{
|
||||||
m_impl->m_audio_dump_started = started;
|
m_impl->m_audio_dump_started = started;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DVDInterface::DVDInterfaceState& System::GetDVDInterfaceState() const
|
||||||
|
{
|
||||||
|
return m_impl->m_dvd_interface_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
DVDThread::DVDThreadState& System::GetDVDThreadState() const
|
||||||
|
{
|
||||||
|
return m_impl->m_dvd_thread_state;
|
||||||
|
}
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -7,6 +7,15 @@
|
||||||
|
|
||||||
class SoundStream;
|
class SoundStream;
|
||||||
|
|
||||||
|
namespace DVDInterface
|
||||||
|
{
|
||||||
|
class DVDInterfaceState;
|
||||||
|
}
|
||||||
|
namespace DVDThread
|
||||||
|
{
|
||||||
|
class DVDThreadState;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Core
|
namespace Core
|
||||||
{
|
{
|
||||||
// Central class that encapsulates the running system.
|
// Central class that encapsulates the running system.
|
||||||
|
@ -40,6 +49,9 @@ public:
|
||||||
bool IsAudioDumpStarted() const;
|
bool IsAudioDumpStarted() const;
|
||||||
void SetAudioDumpStarted(bool started);
|
void SetAudioDumpStarted(bool started);
|
||||||
|
|
||||||
|
DVDInterface::DVDInterfaceState& GetDVDInterfaceState() const;
|
||||||
|
DVDThread::DVDThreadState& GetDVDThreadState() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
System();
|
System();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue