mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 15:19:42 -06:00
Merge pull request #4241 from JosJuice/remove-getvolume
Remove DVDInterface::GetVolume
This commit is contained in:
@ -37,25 +37,35 @@
|
|||||||
#include "DiscIO/Enums.h"
|
#include "DiscIO/Enums.h"
|
||||||
#include "DiscIO/NANDContentLoader.h"
|
#include "DiscIO/NANDContentLoader.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
#include "DiscIO/VolumeCreator.h"
|
||||||
|
|
||||||
bool CBoot::DVDRead(u64 dvd_offset, u32 output_address, u32 length, bool decrypt)
|
// Inserts a disc into the emulated disc drive and returns a pointer to it.
|
||||||
|
// The returned pointer must only be used while we are still booting,
|
||||||
|
// because DVDThread can do whatever it wants to the disc after that.
|
||||||
|
static const DiscIO::IVolume* SetDisc(std::unique_ptr<DiscIO::IVolume> volume)
|
||||||
|
{
|
||||||
|
const DiscIO::IVolume* pointer = volume.get();
|
||||||
|
DVDInterface::SetDisc(std::move(volume));
|
||||||
|
return pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBoot::DVDRead(const DiscIO::IVolume& volume, u64 dvd_offset, u32 output_address, u32 length,
|
||||||
|
bool decrypt)
|
||||||
{
|
{
|
||||||
std::vector<u8> buffer(length);
|
std::vector<u8> buffer(length);
|
||||||
if (!DVDInterface::GetVolume().Read(dvd_offset, length, buffer.data(), decrypt))
|
if (!volume.Read(dvd_offset, length, buffer.data(), decrypt))
|
||||||
return false;
|
return false;
|
||||||
Memory::CopyToEmu(output_address, buffer.data(), length);
|
Memory::CopyToEmu(output_address, buffer.data(), length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBoot::Load_FST(bool is_wii)
|
void CBoot::Load_FST(bool is_wii, const DiscIO::IVolume* volume)
|
||||||
{
|
{
|
||||||
if (!DVDInterface::IsDiscInside())
|
if (!volume)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const DiscIO::IVolume& volume = DVDInterface::GetVolume();
|
|
||||||
|
|
||||||
// copy first 32 bytes of disc to start of Mem 1
|
// copy first 32 bytes of disc to start of Mem 1
|
||||||
DVDRead(/*offset*/ 0, /*address*/ 0, /*length*/ 0x20, false);
|
DVDRead(*volume, /*offset*/ 0, /*address*/ 0, /*length*/ 0x20, false);
|
||||||
|
|
||||||
// copy of game id
|
// copy of game id
|
||||||
Memory::Write_U32(Memory::Read_U32(0x0000), 0x3180);
|
Memory::Write_U32(Memory::Read_U32(0x0000), 0x3180);
|
||||||
@ -68,15 +78,15 @@ void CBoot::Load_FST(bool is_wii)
|
|||||||
u32 fst_size = 0;
|
u32 fst_size = 0;
|
||||||
u32 max_fst_size = 0;
|
u32 max_fst_size = 0;
|
||||||
|
|
||||||
volume.ReadSwapped(0x0424, &fst_offset, is_wii);
|
volume->ReadSwapped(0x0424, &fst_offset, is_wii);
|
||||||
volume.ReadSwapped(0x0428, &fst_size, is_wii);
|
volume->ReadSwapped(0x0428, &fst_size, is_wii);
|
||||||
volume.ReadSwapped(0x042c, &max_fst_size, is_wii);
|
volume->ReadSwapped(0x042c, &max_fst_size, is_wii);
|
||||||
|
|
||||||
u32 arena_high = Common::AlignDown(0x817FFFFF - (max_fst_size << shift), 0x20);
|
u32 arena_high = Common::AlignDown(0x817FFFFF - (max_fst_size << shift), 0x20);
|
||||||
Memory::Write_U32(arena_high, 0x00000034);
|
Memory::Write_U32(arena_high, 0x00000034);
|
||||||
|
|
||||||
// load FST
|
// load FST
|
||||||
DVDRead(fst_offset << shift, arena_high, fst_size << shift, is_wii);
|
DVDRead(*volume, fst_offset << shift, arena_high, fst_size << shift, is_wii);
|
||||||
Memory::Write_U32(arena_high, 0x00000038);
|
Memory::Write_U32(arena_high, 0x00000038);
|
||||||
Memory::Write_U32(max_fst_size << shift, 0x0000003c);
|
Memory::Write_U32(max_fst_size << shift, 0x0000003c);
|
||||||
|
|
||||||
@ -277,22 +287,22 @@ bool CBoot::BootUp()
|
|||||||
{
|
{
|
||||||
case SConfig::BOOT_ISO:
|
case SConfig::BOOT_ISO:
|
||||||
{
|
{
|
||||||
DVDInterface::SetVolumeName(_StartupPara.m_strFilename);
|
const DiscIO::IVolume* volume =
|
||||||
if (!DVDInterface::IsDiscInside())
|
SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strFilename));
|
||||||
|
|
||||||
|
if (!volume)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const DiscIO::IVolume& pVolume = DVDInterface::GetVolume();
|
if ((volume->GetVolumeType() == DiscIO::Platform::WII_DISC) != _StartupPara.bWii)
|
||||||
|
|
||||||
if ((pVolume.GetVolumeType() == DiscIO::Platform::WII_DISC) != _StartupPara.bWii)
|
|
||||||
{
|
{
|
||||||
PanicAlertT("Warning - starting ISO in wrong console mode!");
|
PanicAlertT("Warning - starting ISO in wrong console mode!");
|
||||||
}
|
}
|
||||||
|
|
||||||
_StartupPara.bWii = pVolume.GetVolumeType() == DiscIO::Platform::WII_DISC;
|
_StartupPara.bWii = volume->GetVolumeType() == DiscIO::Platform::WII_DISC;
|
||||||
|
|
||||||
// We HLE the bootrom if requested or if LLEing it fails
|
// We HLE the bootrom if requested or if LLEing it fails
|
||||||
if (_StartupPara.bHLE_BS2 || !Load_BS2(_StartupPara.m_strBootROM))
|
if (_StartupPara.bHLE_BS2 || !Load_BS2(_StartupPara.m_strBootROM))
|
||||||
EmulatedBS2(_StartupPara.bWii);
|
EmulatedBS2(_StartupPara.bWii, volume);
|
||||||
|
|
||||||
PatchEngine::LoadPatches();
|
PatchEngine::LoadPatches();
|
||||||
|
|
||||||
@ -330,28 +340,28 @@ bool CBoot::BootUp()
|
|||||||
PanicAlertT("Warning - starting DOL in wrong console mode!");
|
PanicAlertT("Warning - starting DOL in wrong console mode!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DiscIO::IVolume* volume = nullptr;
|
||||||
if (!_StartupPara.m_strDVDRoot.empty())
|
if (!_StartupPara.m_strDVDRoot.empty())
|
||||||
{
|
{
|
||||||
NOTICE_LOG(BOOT, "Setting DVDRoot %s", _StartupPara.m_strDVDRoot.c_str());
|
NOTICE_LOG(BOOT, "Setting DVDRoot %s", _StartupPara.m_strDVDRoot.c_str());
|
||||||
DVDInterface::SetVolumeDirectory(_StartupPara.m_strDVDRoot, dolWii,
|
volume = SetDisc(DiscIO::CreateVolumeFromDirectory(_StartupPara.m_strDVDRoot, dolWii,
|
||||||
_StartupPara.m_strApploader, _StartupPara.m_strFilename);
|
_StartupPara.m_strApploader,
|
||||||
|
_StartupPara.m_strFilename));
|
||||||
}
|
}
|
||||||
else if (!_StartupPara.m_strDefaultISO.empty())
|
else if (!_StartupPara.m_strDefaultISO.empty())
|
||||||
{
|
{
|
||||||
NOTICE_LOG(BOOT, "Loading default ISO %s", _StartupPara.m_strDefaultISO.c_str());
|
NOTICE_LOG(BOOT, "Loading default ISO %s", _StartupPara.m_strDefaultISO.c_str());
|
||||||
DVDInterface::SetVolumeName(_StartupPara.m_strDefaultISO);
|
volume = SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strDefaultISO));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EmulatedBS2(dolWii))
|
if (!EmulatedBS2(dolWii, volume))
|
||||||
{
|
{
|
||||||
if (dolWii)
|
if (dolWii)
|
||||||
HID4.SBE = 1;
|
HID4.SBE = 1;
|
||||||
SetupBAT(dolWii);
|
SetupBAT(dolWii);
|
||||||
|
|
||||||
// Because there is no TMD to get the requested system (IOS) version from,
|
|
||||||
// we default to IOS58, which is the version used by the Homebrew Channel.
|
|
||||||
if (dolWii)
|
if (dolWii)
|
||||||
SetupWiiMemory(0x000000010000003a);
|
SetupWiiMemory(volume, 0x000000010000003a);
|
||||||
|
|
||||||
dolLoader.Load();
|
dolLoader.Load();
|
||||||
PC = dolLoader.GetEntryPoint();
|
PC = dolLoader.GetEntryPoint();
|
||||||
@ -365,16 +375,19 @@ bool CBoot::BootUp()
|
|||||||
|
|
||||||
case SConfig::BOOT_ELF:
|
case SConfig::BOOT_ELF:
|
||||||
{
|
{
|
||||||
|
const DiscIO::IVolume* volume = nullptr;
|
||||||
|
|
||||||
// load image or create virtual drive from directory
|
// load image or create virtual drive from directory
|
||||||
if (!_StartupPara.m_strDVDRoot.empty())
|
if (!_StartupPara.m_strDVDRoot.empty())
|
||||||
{
|
{
|
||||||
NOTICE_LOG(BOOT, "Setting DVDRoot %s", _StartupPara.m_strDVDRoot.c_str());
|
NOTICE_LOG(BOOT, "Setting DVDRoot %s", _StartupPara.m_strDVDRoot.c_str());
|
||||||
DVDInterface::SetVolumeDirectory(_StartupPara.m_strDVDRoot, _StartupPara.bWii);
|
volume =
|
||||||
|
SetDisc(DiscIO::CreateVolumeFromDirectory(_StartupPara.m_strDVDRoot, _StartupPara.bWii));
|
||||||
}
|
}
|
||||||
else if (!_StartupPara.m_strDefaultISO.empty())
|
else if (!_StartupPara.m_strDefaultISO.empty())
|
||||||
{
|
{
|
||||||
NOTICE_LOG(BOOT, "Loading default ISO %s", _StartupPara.m_strDefaultISO.c_str());
|
NOTICE_LOG(BOOT, "Loading default ISO %s", _StartupPara.m_strDefaultISO.c_str());
|
||||||
DVDInterface::SetVolumeName(_StartupPara.m_strDefaultISO);
|
volume = SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strDefaultISO));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poor man's bootup
|
// Poor man's bootup
|
||||||
@ -382,14 +395,14 @@ bool CBoot::BootUp()
|
|||||||
{
|
{
|
||||||
// Because there is no TMD to get the requested system (IOS) version from,
|
// Because there is no TMD to get the requested system (IOS) version from,
|
||||||
// we default to IOS58, which is the version used by the Homebrew Channel.
|
// we default to IOS58, which is the version used by the Homebrew Channel.
|
||||||
SetupWiiMemory(0x000000010000003a);
|
SetupWiiMemory(volume, 0x000000010000003a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmulatedBS2_GC(true);
|
EmulatedBS2_GC(volume, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Load_FST(_StartupPara.bWii);
|
Load_FST(_StartupPara.bWii, volume);
|
||||||
if (!Boot_ELF(_StartupPara.m_strFilename))
|
if (!Boot_ELF(_StartupPara.m_strFilename))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -411,9 +424,9 @@ bool CBoot::BootUp()
|
|||||||
|
|
||||||
// load default image or create virtual drive from directory
|
// load default image or create virtual drive from directory
|
||||||
if (!_StartupPara.m_strDVDRoot.empty())
|
if (!_StartupPara.m_strDVDRoot.empty())
|
||||||
DVDInterface::SetVolumeDirectory(_StartupPara.m_strDVDRoot, true);
|
SetDisc(DiscIO::CreateVolumeFromDirectory(_StartupPara.m_strDVDRoot, true));
|
||||||
else if (!_StartupPara.m_strDefaultISO.empty())
|
else if (!_StartupPara.m_strDefaultISO.empty())
|
||||||
DVDInterface::SetVolumeName(_StartupPara.m_strDefaultISO);
|
SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strDefaultISO));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -9,6 +9,11 @@
|
|||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
namespace DiscIO
|
||||||
|
{
|
||||||
|
class IVolume;
|
||||||
|
}
|
||||||
|
|
||||||
struct RegionSetting
|
struct RegionSetting
|
||||||
{
|
{
|
||||||
const std::string area;
|
const std::string area;
|
||||||
@ -40,7 +45,8 @@ public:
|
|||||||
static bool LoadMapFromFilename();
|
static bool LoadMapFromFilename();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool DVDRead(u64 dvd_offset, u32 output_address, u32 length, bool decrypt);
|
static bool DVDRead(const DiscIO::IVolume& volume, u64 dvd_offset, u32 output_address, u32 length,
|
||||||
|
bool decrypt);
|
||||||
static void RunFunction(u32 address);
|
static void RunFunction(u32 address);
|
||||||
|
|
||||||
static void UpdateDebugger_MapLoaded();
|
static void UpdateDebugger_MapLoaded();
|
||||||
@ -49,12 +55,12 @@ private:
|
|||||||
static bool Boot_WiiWAD(const std::string& filename);
|
static bool Boot_WiiWAD(const std::string& filename);
|
||||||
|
|
||||||
static void SetupBAT(bool is_wii);
|
static void SetupBAT(bool is_wii);
|
||||||
static bool RunApploader(bool is_wii);
|
static bool RunApploader(bool is_wii, const DiscIO::IVolume& volume);
|
||||||
static bool EmulatedBS2_GC(bool skip_app_loader = false);
|
static bool EmulatedBS2_GC(const DiscIO::IVolume* volume, bool skip_app_loader = false);
|
||||||
static bool EmulatedBS2_Wii();
|
static bool EmulatedBS2_Wii(const DiscIO::IVolume* volume);
|
||||||
static bool EmulatedBS2(bool is_wii);
|
static bool EmulatedBS2(bool is_wii, const DiscIO::IVolume* volume);
|
||||||
static bool Load_BS2(const std::string& boot_rom_filename);
|
static bool Load_BS2(const std::string& boot_rom_filename);
|
||||||
static void Load_FST(bool is_wii);
|
static void Load_FST(bool is_wii, const DiscIO::IVolume* volume);
|
||||||
|
|
||||||
static bool SetupWiiMemory(u64 ios_title_id);
|
static bool SetupWiiMemory(const DiscIO::IVolume* volume, u64 ios_title_id);
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HLE/HLE.h"
|
#include "Core/HLE/HLE.h"
|
||||||
#include "Core/HW/DVD/DVDInterface.h"
|
|
||||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/IOS/ES/ES.h"
|
#include "Core/IOS/ES/ES.h"
|
||||||
@ -78,11 +77,10 @@ void CBoot::SetupBAT(bool is_wii)
|
|||||||
PowerPC::IBATUpdated();
|
PowerPC::IBATUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBoot::RunApploader(bool is_wii)
|
bool CBoot::RunApploader(bool is_wii, const DiscIO::IVolume& volume)
|
||||||
{
|
{
|
||||||
// Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc,
|
// Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc,
|
||||||
// but the size can differ between discs. Compare with YAGCD chap 13.
|
// but the size can differ between discs. Compare with YAGCD chap 13.
|
||||||
const DiscIO::IVolume& volume = DVDInterface::GetVolume();
|
|
||||||
const u32 apploader_offset = 0x2440;
|
const u32 apploader_offset = 0x2440;
|
||||||
u32 apploader_entry = 0;
|
u32 apploader_entry = 0;
|
||||||
u32 apploader_size = 0;
|
u32 apploader_size = 0;
|
||||||
@ -95,7 +93,7 @@ bool CBoot::RunApploader(bool is_wii)
|
|||||||
INFO_LOG(BOOT, "Invalid apploader. Your disc image is probably corrupted.");
|
INFO_LOG(BOOT, "Invalid apploader. Your disc image is probably corrupted.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DVDRead(apploader_offset + 0x20, 0x01200000, apploader_size + apploader_trailer, is_wii);
|
DVDRead(volume, apploader_offset + 0x20, 0x01200000, apploader_size + apploader_trailer, is_wii);
|
||||||
|
|
||||||
// TODO - Make Apploader(or just RunFunction()) debuggable!!!
|
// TODO - Make Apploader(or just RunFunction()) debuggable!!!
|
||||||
|
|
||||||
@ -134,7 +132,7 @@ bool CBoot::RunApploader(bool is_wii)
|
|||||||
|
|
||||||
INFO_LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset,
|
INFO_LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset,
|
||||||
iRamAddress, iLength);
|
iRamAddress, iLength);
|
||||||
DVDRead(iDVDOffset, iRamAddress, iLength, is_wii);
|
DVDRead(volume, iDVDOffset, iRamAddress, iLength, is_wii);
|
||||||
|
|
||||||
} while (PowerPC::ppcState.gpr[3] != 0x00);
|
} while (PowerPC::ppcState.gpr[3] != 0x00);
|
||||||
|
|
||||||
@ -153,7 +151,7 @@ bool CBoot::RunApploader(bool is_wii)
|
|||||||
// GameCube Bootstrap 2 HLE:
|
// GameCube Bootstrap 2 HLE:
|
||||||
// copy the apploader to 0x81200000
|
// copy the apploader to 0x81200000
|
||||||
// execute the apploader, function by function, using the above utility.
|
// execute the apploader, function by function, using the above utility.
|
||||||
bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
bool CBoot::EmulatedBS2_GC(const DiscIO::IVolume* volume, bool skip_app_loader)
|
||||||
{
|
{
|
||||||
INFO_LOG(BOOT, "Faking GC BS2...");
|
INFO_LOG(BOOT, "Faking GC BS2...");
|
||||||
|
|
||||||
@ -164,8 +162,8 @@ bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
|||||||
// to 0x80000000 according to YAGCD 4.2.
|
// to 0x80000000 according to YAGCD 4.2.
|
||||||
|
|
||||||
// It's possible to boot DOL and ELF files without a disc inserted
|
// It's possible to boot DOL and ELF files without a disc inserted
|
||||||
if (DVDInterface::IsDiscInside())
|
if (volume)
|
||||||
DVDRead(/*offset*/ 0x00000000, /*address*/ 0x00000000, 0x20, false); // write disc info
|
DVDRead(*volume, /*offset*/ 0x00000000, /*address*/ 0x00000000, 0x20, false);
|
||||||
|
|
||||||
// Booted from bootrom. 0xE5207C22 = booted from jtag
|
// Booted from bootrom. 0xE5207C22 = booted from jtag
|
||||||
PowerPC::HostWrite_U32(0x0D15EA5E, 0x80000020);
|
PowerPC::HostWrite_U32(0x0D15EA5E, 0x80000020);
|
||||||
@ -196,7 +194,7 @@ bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
|||||||
// HIO checks this
|
// HIO checks this
|
||||||
// PowerPC::HostWrite_U16(0x8200, 0x000030e6); // Console type
|
// PowerPC::HostWrite_U16(0x8200, 0x000030e6); // Console type
|
||||||
|
|
||||||
if (!DVDInterface::IsDiscInside())
|
if (!volume)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Setup pointers like real BS2 does
|
// Setup pointers like real BS2 does
|
||||||
@ -211,10 +209,10 @@ bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
|||||||
if (skip_app_loader)
|
if (skip_app_loader)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return RunApploader(/*is_wii*/ false);
|
return RunApploader(/*is_wii*/ false, *volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBoot::SetupWiiMemory(u64 ios_title_id)
|
bool CBoot::SetupWiiMemory(const DiscIO::IVolume* volume, u64 ios_title_id)
|
||||||
{
|
{
|
||||||
static const std::map<DiscIO::Region, const RegionSetting> region_settings = {
|
static const std::map<DiscIO::Region, const RegionSetting> region_settings = {
|
||||||
{DiscIO::Region::NTSC_J, {"JPN", "NTSC", "JP", "LJ"}},
|
{DiscIO::Region::NTSC_J, {"JPN", "NTSC", "JP", "LJ"}},
|
||||||
@ -281,8 +279,8 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// When booting a WAD or the system menu, there will probably not be a disc inserted
|
// When booting a WAD or the system menu, there will probably not be a disc inserted
|
||||||
if (DVDInterface::IsDiscInside())
|
if (volume)
|
||||||
DVDRead(0x00000000, 0x00000000, 0x20, false); // Game Code
|
DVDRead(*volume, 0x00000000, 0x00000000, 0x20, false); // Game Code
|
||||||
|
|
||||||
Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
|
Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
|
||||||
Memory::Write_U32(0x00000001, 0x00000024); // Unknown
|
Memory::Write_U32(0x00000001, 0x00000024); // Unknown
|
||||||
@ -328,25 +326,25 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id)
|
|||||||
// Wii Bootstrap 2 HLE:
|
// Wii Bootstrap 2 HLE:
|
||||||
// copy the apploader to 0x81200000
|
// copy the apploader to 0x81200000
|
||||||
// execute the apploader
|
// execute the apploader
|
||||||
bool CBoot::EmulatedBS2_Wii()
|
bool CBoot::EmulatedBS2_Wii(const DiscIO::IVolume* volume)
|
||||||
{
|
{
|
||||||
INFO_LOG(BOOT, "Faking Wii BS2...");
|
INFO_LOG(BOOT, "Faking Wii BS2...");
|
||||||
if (!DVDInterface::IsDiscInside())
|
if (!volume)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (DVDInterface::GetVolume().GetVolumeType() != DiscIO::Platform::WII_DISC)
|
if (volume->GetVolumeType() != DiscIO::Platform::WII_DISC)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const IOS::ES::TMDReader tmd = DVDInterface::GetVolume().GetTMD();
|
const IOS::ES::TMDReader tmd = volume->GetTMD();
|
||||||
|
|
||||||
if (!SetupWiiMemory(tmd.GetIOSId()))
|
if (!SetupWiiMemory(volume, tmd.GetIOSId()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// This is some kind of consistency check that is compared to the 0x00
|
// This is some kind of consistency check that is compared to the 0x00
|
||||||
// values as the game boots. This location keeps the 4 byte ID for as long
|
// values as the game boots. This location keeps the 4 byte ID for as long
|
||||||
// as the game is running. The 6 byte ID at 0x00 is overwritten sometime
|
// as the game is running. The 6 byte ID at 0x00 is overwritten sometime
|
||||||
// after this check during booting.
|
// after this check during booting.
|
||||||
DVDRead(0, 0x3180, 4, true);
|
DVDRead(*volume, 0, 0x3180, 4, true);
|
||||||
|
|
||||||
SetupBAT(/*is_wii*/ true);
|
SetupBAT(/*is_wii*/ true);
|
||||||
|
|
||||||
@ -356,16 +354,20 @@ bool CBoot::EmulatedBS2_Wii()
|
|||||||
|
|
||||||
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
|
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
|
||||||
|
|
||||||
if (!RunApploader(/*is_wii*/ true))
|
if (!RunApploader(/*is_wii*/ true, *volume))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
IOS::HLE::Device::ES::DIVerify(tmd, DVDInterface::GetVolume().GetTicket());
|
// Warning: This call will set incorrect running game metadata if our volume parameter
|
||||||
|
// doesn't point to the same disc as the one that's inserted in the emulated disc drive!
|
||||||
|
IOS::HLE::Device::ES::DIVerify(tmd, volume->GetTicket());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if apploader has run successfully
|
// Returns true if apploader has run successfully.
|
||||||
bool CBoot::EmulatedBS2(bool is_wii)
|
// If is_wii is true and volume is not nullptr, the disc that volume
|
||||||
|
// point to must currently be inserted into the emulated disc drive.
|
||||||
|
bool CBoot::EmulatedBS2(bool is_wii, const DiscIO::IVolume* volume)
|
||||||
{
|
{
|
||||||
return is_wii ? EmulatedBS2_Wii() : EmulatedBS2_GC();
|
return is_wii ? EmulatedBS2_Wii(volume) : EmulatedBS2_GC(volume);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
|
|||||||
IOS::HLE::CreateVirtualFATFilesystem();
|
IOS::HLE::CreateVirtualFATFilesystem();
|
||||||
// setup Wii memory
|
// setup Wii memory
|
||||||
|
|
||||||
if (!SetupWiiMemory(ContentLoader.GetTMD().GetIOSId()))
|
if (!SetupWiiMemory(nullptr, ContentLoader.GetTMD().GetIOSId()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
IOS::HLE::Device::ES::LoadWAD(_pFilename);
|
IOS::HLE::Device::ES::LoadWAD(_pFilename);
|
||||||
|
@ -761,21 +761,12 @@ void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd)
|
|||||||
// the disc header instead of the TMD. They can differ.
|
// the disc header instead of the TMD. They can differ.
|
||||||
// (IOS HLE ES calls us with a TMDReader rather than a volume when launching
|
// (IOS HLE ES calls us with a TMDReader rather than a volume when launching
|
||||||
// a disc game, because ES has no reason to be accessing the disc directly.)
|
// a disc game, because ES has no reason to be accessing the disc directly.)
|
||||||
if (DVDInterface::IsDiscInside())
|
if (!DVDThread::UpdateRunningGameMetadata(tmd_title_id))
|
||||||
{
|
{
|
||||||
DVDThread::WaitUntilIdle();
|
|
||||||
const DiscIO::IVolume& volume = DVDInterface::GetVolume();
|
|
||||||
u64 volume_title_id;
|
|
||||||
if (volume.GetTitleID(&volume_title_id) && volume_title_id == tmd_title_id)
|
|
||||||
{
|
|
||||||
SetRunningGameMetadata(volume.GetGameID(), volume_title_id, volume.GetRevision());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not launching a disc game, just read everything from the TMD.
|
// If not launching a disc game, just read everything from the TMD.
|
||||||
SetRunningGameMetadata(tmd.GetGameID(), tmd_title_id, tmd.GetTitleVersion());
|
SetRunningGameMetadata(tmd.GetGameID(), tmd_title_id, tmd.GetTitleVersion());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SConfig::SetRunningGameMetadata(const std::string& game_id, u64 title_id, u16 revision)
|
void SConfig::SetRunningGameMetadata(const std::string& game_id, u64 title_id, u16 revision)
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "Core/HW/DVD/DVDInterface.h"
|
#include "Core/HW/DVD/DVDInterface.h"
|
||||||
#include "Core/HW/DVD/DVDMath.h"
|
#include "Core/HW/DVD/DVDMath.h"
|
||||||
#include "Core/HW/DVD/DVDThread.h"
|
#include "Core/HW/DVD/DVDThread.h"
|
||||||
#include "Core/HW/DVD/FileMonitor.h"
|
|
||||||
#include "Core/HW/MMIO.h"
|
#include "Core/HW/MMIO.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/HW/ProcessorInterface.h"
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
@ -195,8 +194,6 @@ union UDICFG
|
|||||||
UDICFG(u32 _hex) { Hex = _hex; }
|
UDICFG(u32 _hex) { Hex = _hex; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<DiscIO::IVolume> s_inserted_volume;
|
|
||||||
|
|
||||||
// STATE_TO_SAVE
|
// STATE_TO_SAVE
|
||||||
|
|
||||||
// Hardware registers
|
// Hardware registers
|
||||||
@ -255,8 +252,6 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
|
|||||||
|
|
||||||
void DoState(PointerWrap& p)
|
void DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
bool disc_inside = IsDiscInside();
|
|
||||||
|
|
||||||
p.DoPOD(s_DISR);
|
p.DoPOD(s_DISR);
|
||||||
p.DoPOD(s_DICVR);
|
p.DoPOD(s_DICVR);
|
||||||
p.DoArray(s_DICMDBUF);
|
p.DoArray(s_DICMDBUF);
|
||||||
@ -276,7 +271,6 @@ void DoState(PointerWrap& p)
|
|||||||
p.Do(s_pending_samples);
|
p.Do(s_pending_samples);
|
||||||
|
|
||||||
p.Do(s_error_code);
|
p.Do(s_error_code);
|
||||||
p.Do(disc_inside);
|
|
||||||
|
|
||||||
p.Do(s_read_buffer_start_time);
|
p.Do(s_read_buffer_start_time);
|
||||||
p.Do(s_read_buffer_end_time);
|
p.Do(s_read_buffer_end_time);
|
||||||
@ -286,24 +280,6 @@ void DoState(PointerWrap& p)
|
|||||||
p.Do(s_disc_path_to_insert);
|
p.Do(s_disc_path_to_insert);
|
||||||
|
|
||||||
DVDThread::DoState(p);
|
DVDThread::DoState(p);
|
||||||
|
|
||||||
// s_inserted_volume isn't savestated (because it points to
|
|
||||||
// files on the local system). Instead, we check that the
|
|
||||||
// savestated disc_inside matches our IsDiscInside(). This
|
|
||||||
// won't catch cases of having the wrong disc inserted, though.
|
|
||||||
// TODO: Check the game ID, disc number, revision?
|
|
||||||
if (disc_inside != IsDiscInside())
|
|
||||||
{
|
|
||||||
if (disc_inside)
|
|
||||||
{
|
|
||||||
PanicAlertT("An inserted disc was expected but not found.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_inserted_volume.reset();
|
|
||||||
FileMonitor::SetFileSystem(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ProcessDTKSamples(std::vector<s16>* temp_pcm, const std::vector<u8>& audio_data)
|
static size_t ProcessDTKSamples(std::vector<s16>* temp_pcm, const std::vector<u8>& audio_data)
|
||||||
@ -452,39 +428,17 @@ void Reset()
|
|||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
DVDThread::Stop();
|
DVDThread::Stop();
|
||||||
s_inserted_volume.reset();
|
|
||||||
FileMonitor::SetFileSystem(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DiscIO::IVolume& GetVolume()
|
void SetDisc(std::unique_ptr<DiscIO::IVolume> disc)
|
||||||
{
|
{
|
||||||
_assert_(IsDiscInside());
|
DVDThread::SetDisc(std::move(disc));
|
||||||
return *s_inserted_volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SetVolumeName(const std::string& disc_path)
|
|
||||||
{
|
|
||||||
DVDThread::WaitUntilIdle();
|
|
||||||
s_inserted_volume = DiscIO::CreateVolumeFromFilename(disc_path);
|
|
||||||
FileMonitor::SetFileSystem(s_inserted_volume.get());
|
|
||||||
SetLidOpen();
|
SetLidOpen();
|
||||||
return IsDiscInside();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SetVolumeDirectory(const std::string& full_path, bool is_wii,
|
|
||||||
const std::string& apploader_path, const std::string& DOL_path)
|
|
||||||
{
|
|
||||||
DVDThread::WaitUntilIdle();
|
|
||||||
s_inserted_volume =
|
|
||||||
DiscIO::CreateVolumeFromDirectory(full_path, is_wii, apploader_path, DOL_path);
|
|
||||||
FileMonitor::SetFileSystem(s_inserted_volume.get());
|
|
||||||
SetLidOpen();
|
|
||||||
return IsDiscInside();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDiscInside()
|
bool IsDiscInside()
|
||||||
{
|
{
|
||||||
return s_inserted_volume != nullptr;
|
return DVDThread::HasDisc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take care of all logic of "swapping discs"
|
// Take care of all logic of "swapping discs"
|
||||||
@ -493,26 +447,20 @@ bool IsDiscInside()
|
|||||||
// that the userdata string exists when called
|
// that the userdata string exists when called
|
||||||
static void EjectDiscCallback(u64 userdata, s64 cyclesLate)
|
static void EjectDiscCallback(u64 userdata, s64 cyclesLate)
|
||||||
{
|
{
|
||||||
DVDThread::WaitUntilIdle();
|
SetDisc(nullptr);
|
||||||
s_inserted_volume.reset();
|
|
||||||
FileMonitor::SetFileSystem(s_inserted_volume.get());
|
|
||||||
SetLidOpen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InsertDiscCallback(u64 userdata, s64 cyclesLate)
|
static void InsertDiscCallback(u64 userdata, s64 cyclesLate)
|
||||||
{
|
{
|
||||||
const std::string& old_path = SConfig::GetInstance().m_strFilename;
|
std::unique_ptr<DiscIO::IVolume> new_volume =
|
||||||
|
DiscIO::CreateVolumeFromFilename(s_disc_path_to_insert);
|
||||||
|
|
||||||
if (!SetVolumeName(s_disc_path_to_insert))
|
if (new_volume)
|
||||||
{
|
SetDisc(std::move(new_volume));
|
||||||
// Put back the old one
|
else
|
||||||
SetVolumeName(old_path);
|
|
||||||
PanicAlertT("The disc that was about to be inserted couldn't be found.");
|
PanicAlertT("The disc that was about to be inserted couldn't be found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
s_disc_path_to_insert.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can only be called by the host thread
|
// Can only be called by the host thread
|
||||||
void ChangeDiscAsHost(const std::string& new_path)
|
void ChangeDiscAsHost(const std::string& new_path)
|
||||||
{
|
{
|
||||||
@ -550,10 +498,7 @@ void SetLidOpen()
|
|||||||
|
|
||||||
bool ChangePartition(u64 offset)
|
bool ChangePartition(u64 offset)
|
||||||
{
|
{
|
||||||
DVDThread::WaitUntilIdle();
|
return DVDThread::ChangePartition(offset);
|
||||||
const bool success = s_inserted_volume->ChangePartition(offset);
|
|
||||||
FileMonitor::SetFileSystem(s_inserted_volume.get());
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
@ -1165,7 +1110,7 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
|
|||||||
|
|
||||||
const u64 current_time = CoreTiming::GetTicks();
|
const u64 current_time = CoreTiming::GetTicks();
|
||||||
const u32 ticks_per_second = SystemTimers::GetTicksPerSecond();
|
const u32 ticks_per_second = SystemTimers::GetTicksPerSecond();
|
||||||
const bool wii_disc = s_inserted_volume->GetVolumeType() == DiscIO::Platform::WII_DISC;
|
const bool wii_disc = DVDThread::GetDiscType() == DiscIO::Platform::WII_DISC;
|
||||||
|
|
||||||
// Where the DVD read head is (usually parked at the end of the buffer,
|
// Where the DVD read head is (usually parked at the end of the buffer,
|
||||||
// unless we've interrupted it mid-buffer-read).
|
// unless we've interrupted it mid-buffer-read).
|
||||||
@ -1181,7 +1126,7 @@ void ScheduleReads(u64 offset, u32 length, bool decrypt, u32 output_address, Rep
|
|||||||
// It's rounded to a whole ECC block and never uses Wii partition addressing.
|
// It's rounded to a whole ECC block and never uses Wii partition addressing.
|
||||||
u64 dvd_offset = offset;
|
u64 dvd_offset = offset;
|
||||||
if (decrypt)
|
if (decrypt)
|
||||||
dvd_offset = s_inserted_volume->PartitionOffsetToRawOffset(offset);
|
dvd_offset = DVDThread::PartitionOffsetToRawOffset(offset);
|
||||||
dvd_offset = Common::AlignDown(dvd_offset, DVD_ECC_BLOCK_SIZE);
|
dvd_offset = Common::AlignDown(dvd_offset, DVD_ECC_BLOCK_SIZE);
|
||||||
|
|
||||||
if (SConfig::GetInstance().bFastDiscSpeed)
|
if (SConfig::GetInstance().bFastDiscSpeed)
|
||||||
|
@ -108,11 +108,7 @@ void DoState(PointerWrap& p);
|
|||||||
|
|
||||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
|
|
||||||
// Disc access (don't call GetVolume unless you know that IsDiscInside() == true)
|
void SetDisc(std::unique_ptr<DiscIO::IVolume> disc);
|
||||||
const DiscIO::IVolume& GetVolume();
|
|
||||||
bool SetVolumeName(const std::string& disc_path);
|
|
||||||
bool SetVolumeDirectory(const std::string& disc_path, bool is_wii,
|
|
||||||
const std::string& apploader_path = "", const std::string& DOL_path = "");
|
|
||||||
bool IsDiscInside();
|
bool IsDiscInside();
|
||||||
void ChangeDiscAsHost(const std::string& new_path); // Can only be called by the host thread
|
void ChangeDiscAsHost(const std::string& new_path); // Can only be called by the host thread
|
||||||
void ChangeDiscAsCPU(const std::string& new_path); // Can only be called by the CPU thread
|
void ChangeDiscAsCPU(const std::string& new_path); // Can only be called by the CPU thread
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#include "Common/Thread.h"
|
#include "Common/Thread.h"
|
||||||
#include "Common/Timer.h"
|
#include "Common/Timer.h"
|
||||||
|
|
||||||
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
#include "Core/HW/DVD/DVDInterface.h"
|
#include "Core/HW/DVD/DVDInterface.h"
|
||||||
@ -26,7 +28,9 @@
|
|||||||
#include "Core/HW/DVD/FileMonitor.h"
|
#include "Core/HW/DVD/FileMonitor.h"
|
||||||
#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 "DiscIO/Enums.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
|
||||||
namespace DVDThread
|
namespace DVDThread
|
||||||
@ -61,6 +65,7 @@ static void StartDVDThread();
|
|||||||
static void StopDVDThread();
|
static void StopDVDThread();
|
||||||
|
|
||||||
static void DVDThread();
|
static void DVDThread();
|
||||||
|
static void WaitUntilIdle();
|
||||||
|
|
||||||
static void StartReadInternal(bool copy_to_ram, u32 output_address, u64 dvd_offset, u32 length,
|
static void StartReadInternal(bool copy_to_ram, u32 output_address, u64 dvd_offset, u32 length,
|
||||||
bool decrypt, DVDInterface::ReplyType reply_type,
|
bool decrypt, DVDInterface::ReplyType reply_type,
|
||||||
@ -80,6 +85,8 @@ static Common::FifoQueue<ReadRequest, false> s_request_queue;
|
|||||||
static Common::FifoQueue<ReadResult, false> s_result_queue;
|
static Common::FifoQueue<ReadResult, false> s_result_queue;
|
||||||
static std::map<u64, ReadResult> s_result_map;
|
static std::map<u64, ReadResult> s_result_map;
|
||||||
|
|
||||||
|
static std::unique_ptr<DiscIO::IVolume> s_disc;
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
s_finish_read = CoreTiming::RegisterEvent("FinishReadDVDThread", FinishRead);
|
s_finish_read = CoreTiming::RegisterEvent("FinishReadDVDThread", FinishRead);
|
||||||
@ -106,6 +113,8 @@ static void StartDVDThread()
|
|||||||
void Stop()
|
void Stop()
|
||||||
{
|
{
|
||||||
StopDVDThread();
|
StopDVDThread();
|
||||||
|
s_disc.reset();
|
||||||
|
FileMonitor::SetFileSystem(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StopDVDThread()
|
static void StopDVDThread()
|
||||||
@ -123,24 +132,42 @@ static void StopDVDThread()
|
|||||||
|
|
||||||
void DoState(PointerWrap& p)
|
void DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
// By waiting for the DVD thread to be done working, we ensure that
|
// By waiting for the DVD thread to be done working, we ensure
|
||||||
// there are no pending requests. The DVD thread won't be touching
|
// that s_request_queue will be empty and that the DVD thread
|
||||||
// s_result_queue, and everything we need to save will be in either
|
// won't be touching anything while this function runs.
|
||||||
// s_result_queue or s_result_map (other than s_next_id).
|
|
||||||
WaitUntilIdle();
|
WaitUntilIdle();
|
||||||
|
|
||||||
// Move everything from s_result_queue to s_result_map because
|
// Move all results from s_result_queue to s_result_map because
|
||||||
// PointerWrap::Do supports std::map but not Common::FifoQueue.
|
// PointerWrap::Do supports std::map but not Common::FifoQueue.
|
||||||
// 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 (s_result_queue.Pop(result))
|
||||||
s_result_map.emplace(result.first.id, std::move(result));
|
s_result_map.emplace(result.first.id, std::move(result));
|
||||||
|
|
||||||
// Everything is now in s_result_map, so we simply savestate that.
|
// Both queues are now empty, so we don't need to savestate them.
|
||||||
// We also savestate s_next_id to avoid ID collisions.
|
|
||||||
p.Do(s_result_map);
|
p.Do(s_result_map);
|
||||||
p.Do(s_next_id);
|
p.Do(s_next_id);
|
||||||
|
|
||||||
|
// s_disc isn't savestated (because it points to files on the
|
||||||
|
// local system). Instead, we check that the status of the disc
|
||||||
|
// is the same as when the savestate was made. This won't catch
|
||||||
|
// cases of having the wrong disc inserted, though.
|
||||||
|
// TODO: Check the game ID, disc number, revision?
|
||||||
|
bool had_disc = HasDisc();
|
||||||
|
p.Do(had_disc);
|
||||||
|
if (had_disc != HasDisc())
|
||||||
|
{
|
||||||
|
if (had_disc)
|
||||||
|
{
|
||||||
|
PanicAlertT("An inserted disc was expected but not found.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_disc.reset();
|
||||||
|
FileMonitor::SetFileSystem(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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,
|
||||||
// but instead get re-read from the disc when loading the savestate.
|
// but instead get re-read from the disc when loading the savestate.
|
||||||
|
|
||||||
@ -152,6 +179,82 @@ void DoState(PointerWrap& p)
|
|||||||
// was made. Handling that properly may be more effort than it's worth.
|
// was made. Handling that properly may be more effort than it's worth.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDisc(std::unique_ptr<DiscIO::IVolume> disc)
|
||||||
|
{
|
||||||
|
WaitUntilIdle();
|
||||||
|
s_disc = std::move(disc);
|
||||||
|
FileMonitor::SetFileSystem(s_disc.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasDisc()
|
||||||
|
{
|
||||||
|
return s_disc != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 PartitionOffsetToRawOffset(u64 offset)
|
||||||
|
{
|
||||||
|
// This is thread-safe as long as the partition currently isn't being changed,
|
||||||
|
// and that isn't supposed to be happening while running this function, because both
|
||||||
|
// this function and ChangePartition are only supposed to be called on the CPU thread.
|
||||||
|
_assert_(Core::IsCPUThread());
|
||||||
|
return s_disc->PartitionOffsetToRawOffset(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscIO::Platform GetDiscType()
|
||||||
|
{
|
||||||
|
// GetVolumeType is thread-safe, so calling WaitUntilIdle isn't necessary.
|
||||||
|
return s_disc->GetVolumeType();
|
||||||
|
}
|
||||||
|
|
||||||
|
IOS::ES::TMDReader GetTMD()
|
||||||
|
{
|
||||||
|
WaitUntilIdle();
|
||||||
|
return s_disc->GetTMD();
|
||||||
|
}
|
||||||
|
|
||||||
|
IOS::ES::TicketReader GetTicket()
|
||||||
|
{
|
||||||
|
WaitUntilIdle();
|
||||||
|
return s_disc->GetTicket();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChangePartition(u64 offset)
|
||||||
|
{
|
||||||
|
WaitUntilIdle();
|
||||||
|
const bool success = s_disc->ChangePartition(offset);
|
||||||
|
FileMonitor::SetFileSystem(s_disc.get());
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateRunningGameMetadata(u64 title_id)
|
||||||
|
{
|
||||||
|
if (!s_disc)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WaitUntilIdle();
|
||||||
|
|
||||||
|
u64 volume_title_id;
|
||||||
|
if (!s_disc->GetTitleID(&volume_title_id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (volume_title_id != title_id)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SConfig::GetInstance().SetRunningGameMetadata(*s_disc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateRunningGameMetadata()
|
||||||
|
{
|
||||||
|
if (!s_disc)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DVDThread::WaitUntilIdle();
|
||||||
|
|
||||||
|
SConfig::GetInstance().SetRunningGameMetadata(*s_disc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void WaitUntilIdle()
|
void WaitUntilIdle()
|
||||||
{
|
{
|
||||||
_assert_(Core::IsCPUThread());
|
_assert_(Core::IsCPUThread());
|
||||||
@ -281,8 +384,7 @@ static void DVDThread()
|
|||||||
FileMonitor::Log(request.dvd_offset, request.decrypt);
|
FileMonitor::Log(request.dvd_offset, request.decrypt);
|
||||||
|
|
||||||
std::vector<u8> buffer(request.length);
|
std::vector<u8> buffer(request.length);
|
||||||
const DiscIO::IVolume& volume = DVDInterface::GetVolume();
|
if (!s_disc->Read(request.dvd_offset, request.length, buffer.data(), request.decrypt))
|
||||||
if (!volume.Read(request.dvd_offset, request.length, buffer.data(), request.decrypt))
|
|
||||||
buffer.resize(0);
|
buffer.resize(0);
|
||||||
|
|
||||||
request.realtime_done_us = Common::Timer::GetTimeUs();
|
request.realtime_done_us = Common::Timer::GetTimeUs();
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
@ -11,6 +14,19 @@ namespace DVDInterface
|
|||||||
{
|
{
|
||||||
enum class ReplyType : u32;
|
enum class ReplyType : u32;
|
||||||
}
|
}
|
||||||
|
namespace DiscIO
|
||||||
|
{
|
||||||
|
enum class Platform;
|
||||||
|
class IVolume;
|
||||||
|
}
|
||||||
|
namespace IOS
|
||||||
|
{
|
||||||
|
namespace ES
|
||||||
|
{
|
||||||
|
class TMDReader;
|
||||||
|
class TicketReader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace DVDThread
|
namespace DVDThread
|
||||||
{
|
{
|
||||||
@ -18,7 +34,21 @@ void Start();
|
|||||||
void Stop();
|
void Stop();
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
|
|
||||||
void WaitUntilIdle();
|
void SetDisc(std::unique_ptr<DiscIO::IVolume> disc);
|
||||||
|
bool HasDisc();
|
||||||
|
|
||||||
|
u64 PartitionOffsetToRawOffset(u64 offset);
|
||||||
|
DiscIO::Platform GetDiscType();
|
||||||
|
IOS::ES::TMDReader GetTMD();
|
||||||
|
IOS::ES::TicketReader GetTicket();
|
||||||
|
bool ChangePartition(u64 offset);
|
||||||
|
// If a disc is inserted and its title ID is equal to the title_id argument, returns true and
|
||||||
|
// calls SConfig::SetRunningGameMetadata(IVolume&). Otherwise, returns false.
|
||||||
|
bool UpdateRunningGameMetadata(u64 title_id);
|
||||||
|
// If a disc is inserted, returns true and calls
|
||||||
|
// SConfig::SetRunningGameMetadata(IVolume&). Otherwise, returns false.
|
||||||
|
bool UpdateRunningGameMetadata();
|
||||||
|
|
||||||
void StartRead(u64 dvd_offset, u32 length, bool decrypt, DVDInterface::ReplyType reply_type,
|
void StartRead(u64 dvd_offset, u32 length, bool decrypt, DVDInterface::ReplyType reply_type,
|
||||||
s64 ticks_until_completion);
|
s64 ticks_until_completion);
|
||||||
void StartReadToEmulatedRAM(u32 output_address, u64 dvd_offset, u32 length, bool decrypt,
|
void StartReadToEmulatedRAM(u32 output_address, u64 dvd_offset, u32 length, bool decrypt,
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Core/HW/DVD/DVDInterface.h"
|
#include "Core/HW/DVD/DVDInterface.h"
|
||||||
|
#include "Core/HW/DVD/DVDThread.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/IOS/DI/DI.h"
|
#include "Core/IOS/DI/DI.h"
|
||||||
#include "Core/IOS/ES/ES.h"
|
#include "Core/IOS/ES/ES.h"
|
||||||
@ -106,10 +107,10 @@ IPCCommandResult DI::IOCtlV(const IOCtlVRequest& request)
|
|||||||
INFO_LOG(IOS_DI, "DVDLowOpenPartition: partition_offset 0x%016" PRIx64, partition_offset);
|
INFO_LOG(IOS_DI, "DVDLowOpenPartition: partition_offset 0x%016" PRIx64, partition_offset);
|
||||||
|
|
||||||
// Read TMD to the buffer
|
// Read TMD to the buffer
|
||||||
const IOS::ES::TMDReader tmd = DVDInterface::GetVolume().GetTMD();
|
const IOS::ES::TMDReader tmd = DVDThread::GetTMD();
|
||||||
const std::vector<u8> raw_tmd = tmd.GetRawTMD();
|
const std::vector<u8> raw_tmd = tmd.GetRawTMD();
|
||||||
Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());
|
Memory::CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());
|
||||||
ES::DIVerify(tmd, DVDInterface::GetVolume().GetTicket());
|
ES::DIVerify(tmd, DVDThread::GetTicket());
|
||||||
|
|
||||||
return_value = 1;
|
return_value = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -120,13 +120,6 @@ static void ReinitHardware()
|
|||||||
SystemTimers::ChangePPCClock(SystemTimers::Mode::GC);
|
SystemTimers::ChangePPCClock(SystemTimers::Mode::GC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateRunningGame()
|
|
||||||
{
|
|
||||||
DVDThread::WaitUntilIdle();
|
|
||||||
SConfig::GetInstance().m_BootType = SConfig::BOOT_MIOS;
|
|
||||||
SConfig::GetInstance().SetRunningGameMetadata(DVDInterface::GetVolume());
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr u32 ADDRESS_INIT_SEMAPHORE = 0x30f8;
|
constexpr u32 ADDRESS_INIT_SEMAPHORE = 0x30f8;
|
||||||
|
|
||||||
bool Load()
|
bool Load()
|
||||||
@ -176,7 +169,8 @@ bool Load()
|
|||||||
|
|
||||||
Memory::Write_U32(0x00000000, ADDRESS_INIT_SEMAPHORE);
|
Memory::Write_U32(0x00000000, ADDRESS_INIT_SEMAPHORE);
|
||||||
NOTICE_LOG(IOS, "IPL ready.");
|
NOTICE_LOG(IOS, "IPL ready.");
|
||||||
UpdateRunningGame();
|
SConfig::GetInstance().m_BootType = SConfig::BOOT_MIOS;
|
||||||
|
DVDThread::UpdateRunningGameMetadata();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // namespace MIOS
|
} // namespace MIOS
|
||||||
|
@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||||||
static std::thread g_save_thread;
|
static std::thread g_save_thread;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
static const u32 STATE_VERSION = 84; // Last changed in PR 5354
|
static const u32 STATE_VERSION = 85; // Last changed in PR 4241
|
||||||
|
|
||||||
// Maps savestate versions to Dolphin versions.
|
// Maps savestate versions to Dolphin versions.
|
||||||
// Versions after 42 don't need to be added to this list,
|
// Versions after 42 don't need to be added to this list,
|
||||||
|
Reference in New Issue
Block a user