mirror of https://github.com/PCSX2/pcsx2.git
cdvdgigaherz: Get disc info when disc is first ready
Also set the disc speed at the correct time - CDROM SET SPEED only stays in effect till the disc is removed. Also fix a memleak in CDVDopen when the drive cannot be accessed.
This commit is contained in:
parent
95b98c5a38
commit
1834b7d0f9
|
@ -225,10 +225,10 @@ s32 CALLBACK CDVDopen(const char *pTitleFilename)
|
||||||
printf(" * CDVD: Opening drive '%s'...\n", csrc);
|
printf(" * CDVD: Opening drive '%s'...\n", csrc);
|
||||||
|
|
||||||
// open device file
|
// open device file
|
||||||
src = new IOCtlSrc(csrc);
|
try {
|
||||||
|
src = new IOCtlSrc(csrc);
|
||||||
if (!src->IsOK()) {
|
} catch (std::runtime_error &ex) {
|
||||||
printf(" * CDVD: Error opening source.\n");
|
fputs(ex.what(), stdout);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,7 @@ class IOCtlSrc
|
||||||
|
|
||||||
HANDLE m_device = INVALID_HANDLE_VALUE;
|
HANDLE m_device = INVALID_HANDLE_VALUE;
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
bool OpenOK;
|
|
||||||
|
|
||||||
bool m_disc_ready = false;
|
|
||||||
s32 m_media_type = 0;
|
s32 m_media_type = 0;
|
||||||
u32 m_sectors = 0;
|
u32 m_sectors = 0;
|
||||||
u32 m_layer_break = 0;
|
u32 m_layer_break = 0;
|
||||||
|
@ -66,25 +64,20 @@ class IOCtlSrc
|
||||||
|
|
||||||
bool ReadDVDInfo();
|
bool ReadDVDInfo();
|
||||||
bool ReadCDInfo();
|
bool ReadCDInfo();
|
||||||
bool RefreshDiscInfo();
|
bool Reopen();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IOCtlSrc(const char *filename);
|
IOCtlSrc(const char *filename);
|
||||||
~IOCtlSrc();
|
~IOCtlSrc();
|
||||||
|
|
||||||
u32 GetSectorCount();
|
u32 GetSectorCount() const;
|
||||||
const std::vector<toc_entry> &ReadTOC();
|
const std::vector<toc_entry> &ReadTOC() const;
|
||||||
s32 ReadSectors2048(u32 sector, u32 count, char *buffer);
|
s32 ReadSectors2048(u32 sector, u32 count, char *buffer);
|
||||||
s32 ReadSectors2352(u32 sector, u32 count, char *buffer);
|
s32 ReadSectors2352(u32 sector, u32 count, char *buffer);
|
||||||
u32 GetLayerBreakAddress();
|
u32 GetLayerBreakAddress() const;
|
||||||
|
s32 GetMediaType() const;
|
||||||
s32 GetMediaType();
|
void SetSpindleSpeed(bool restore_defaults) const;
|
||||||
void SetSpindleSpeed(bool restore_defaults);
|
bool DiscReady();
|
||||||
|
|
||||||
s32 IsOK();
|
|
||||||
s32 Reopen();
|
|
||||||
|
|
||||||
s32 DiscChanged();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern IOCtlSrc *src;
|
extern IOCtlSrc *src;
|
||||||
|
|
|
@ -107,22 +107,9 @@ void cdvdCallNewDiscCB()
|
||||||
|
|
||||||
bool cdvdUpdateDiscStatus()
|
bool cdvdUpdateDiscStatus()
|
||||||
{
|
{
|
||||||
int change = src->DiscChanged();
|
bool ready = src->DiscReady();
|
||||||
|
|
||||||
if (change == -1) { //error getting status (no disc in drive?)
|
if (!ready) {
|
||||||
//try to recreate the device
|
|
||||||
src->Reopen();
|
|
||||||
|
|
||||||
if (src->IsOK()) {
|
|
||||||
change = 1;
|
|
||||||
} else {
|
|
||||||
curDiskType = CDVD_TYPE_NODISC;
|
|
||||||
curTrayStatus = CDVD_TRAY_OPEN;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (change == 1) {
|
|
||||||
if (!disc_has_changed) {
|
if (!disc_has_changed) {
|
||||||
disc_has_changed = true;
|
disc_has_changed = true;
|
||||||
curDiskType = CDVD_TYPE_NODISC;
|
curDiskType = CDVD_TYPE_NODISC;
|
||||||
|
@ -134,15 +121,12 @@ bool cdvdUpdateDiscStatus()
|
||||||
curDiskType = CDVD_TYPE_NODISC;
|
curDiskType = CDVD_TYPE_NODISC;
|
||||||
curTrayStatus = CDVD_TRAY_CLOSE;
|
curTrayStatus = CDVD_TRAY_CLOSE;
|
||||||
|
|
||||||
// just a test
|
|
||||||
src->Reopen();
|
|
||||||
|
|
||||||
disc_has_changed = false;
|
disc_has_changed = false;
|
||||||
cdvdRefreshData();
|
cdvdRefreshData();
|
||||||
cdvdCallNewDiscCB();
|
cdvdCallNewDiscCB();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (change != 0);
|
return !ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD CALLBACK cdvdThread(PVOID param)
|
DWORD CALLBACK cdvdThread(PVOID param)
|
||||||
|
@ -150,9 +134,6 @@ DWORD CALLBACK cdvdThread(PVOID param)
|
||||||
printf(" * CDVD: IO thread started...\n");
|
printf(" * CDVD: IO thread started...\n");
|
||||||
|
|
||||||
while (cdvd_is_open) {
|
while (cdvd_is_open) {
|
||||||
if (!src)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (cdvdUpdateDiscStatus()) {
|
if (cdvdUpdateDiscStatus()) {
|
||||||
// Need to sleep some to avoid an aggressive spin that sucks the cpu dry.
|
// Need to sleep some to avoid an aggressive spin that sucks the cpu dry.
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
|
|
|
@ -28,46 +28,49 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
IOCtlSrc::IOCtlSrc(const char *filename)
|
IOCtlSrc::IOCtlSrc(const char *filename)
|
||||||
: m_filename(filename)
|
: m_filename(filename)
|
||||||
{
|
{
|
||||||
Reopen();
|
if (!Reopen())
|
||||||
SetSpindleSpeed(false);
|
throw std::runtime_error(" * CDVD: Error opening source.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
IOCtlSrc::~IOCtlSrc()
|
IOCtlSrc::~IOCtlSrc()
|
||||||
{
|
{
|
||||||
if (OpenOK) {
|
if (m_device != INVALID_HANDLE_VALUE) {
|
||||||
SetSpindleSpeed(true);
|
SetSpindleSpeed(true);
|
||||||
CloseHandle(m_device);
|
CloseHandle(m_device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 IOCtlSrc::Reopen()
|
// If a new disc is inserted, ReadFile will fail unless the device is closed
|
||||||
|
// and reopened.
|
||||||
|
bool IOCtlSrc::Reopen()
|
||||||
{
|
{
|
||||||
if (m_device != INVALID_HANDLE_VALUE)
|
if (m_device != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(m_device);
|
CloseHandle(m_device);
|
||||||
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
OpenOK = false;
|
|
||||||
// SPTI only works if the device is opened with GENERIC_WRITE access.
|
// SPTI only works if the device is opened with GENERIC_WRITE access.
|
||||||
m_device = CreateFile(m_filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
m_device = CreateFile(m_filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||||
FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
|
FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
|
||||||
if (m_device == INVALID_HANDLE_VALUE)
|
if (m_device == INVALID_HANDLE_VALUE)
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
|
DWORD unused;
|
||||||
// Required to read from layer 1 of Dual layer DVDs
|
// Required to read from layer 1 of Dual layer DVDs
|
||||||
DeviceIoControl(m_device, FSCTL_ALLOW_EXTENDED_DASD_IO, nullptr, 0, nullptr, 0, &size, nullptr);
|
DeviceIoControl(m_device, FSCTL_ALLOW_EXTENDED_DASD_IO, nullptr, 0, nullptr,
|
||||||
|
0, &unused, nullptr);
|
||||||
|
|
||||||
m_disc_ready = false;
|
if (ReadDVDInfo() || ReadCDInfo())
|
||||||
OpenOK = true;
|
SetSpindleSpeed(false);
|
||||||
return 0;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOCtlSrc::SetSpindleSpeed(bool restore_defaults)
|
void IOCtlSrc::SetSpindleSpeed(bool restore_defaults) const
|
||||||
{
|
{
|
||||||
|
|
||||||
DWORD dontcare;
|
DWORD dontcare;
|
||||||
|
@ -112,38 +115,23 @@ void IOCtlSrc::SetSpindleSpeed(bool restore_defaults)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 IOCtlSrc::GetSectorCount()
|
u32 IOCtlSrc::GetSectorCount() const
|
||||||
{
|
{
|
||||||
if (!m_disc_ready)
|
|
||||||
RefreshDiscInfo();
|
|
||||||
|
|
||||||
return m_sectors;
|
return m_sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 IOCtlSrc::GetLayerBreakAddress()
|
u32 IOCtlSrc::GetLayerBreakAddress() const
|
||||||
{
|
{
|
||||||
if (!m_disc_ready)
|
|
||||||
RefreshDiscInfo();
|
|
||||||
|
|
||||||
if (GetMediaType() < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return m_layer_break;
|
return m_layer_break;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 IOCtlSrc::GetMediaType()
|
s32 IOCtlSrc::GetMediaType() const
|
||||||
{
|
{
|
||||||
if (!m_disc_ready)
|
|
||||||
RefreshDiscInfo();
|
|
||||||
|
|
||||||
return m_media_type;
|
return m_media_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<toc_entry> &IOCtlSrc::ReadTOC()
|
const std::vector<toc_entry> &IOCtlSrc::ReadTOC() const
|
||||||
{
|
{
|
||||||
if (!m_disc_ready)
|
|
||||||
RefreshDiscInfo();
|
|
||||||
|
|
||||||
return m_toc;
|
return m_toc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,9 +141,6 @@ s32 IOCtlSrc::ReadSectors2048(u32 sector, u32 count, char *buffer)
|
||||||
|
|
||||||
DWORD size = 0;
|
DWORD size = 0;
|
||||||
|
|
||||||
if (!OpenOK)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
rri.DiskOffset.QuadPart = sector * (u64)2048;
|
rri.DiskOffset.QuadPart = sector * (u64)2048;
|
||||||
rri.SectorCount = count;
|
rri.SectorCount = count;
|
||||||
|
|
||||||
|
@ -179,9 +164,6 @@ s32 IOCtlSrc::ReadSectors2048(u32 sector, u32 count, char *buffer)
|
||||||
|
|
||||||
s32 IOCtlSrc::ReadSectors2352(u32 sector, u32 count, char *buffer)
|
s32 IOCtlSrc::ReadSectors2352(u32 sector, u32 count, char *buffer)
|
||||||
{
|
{
|
||||||
if (!OpenOK)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
struct sptdinfo
|
struct sptdinfo
|
||||||
{
|
{
|
||||||
SCSI_PASS_THROUGH_DIRECT info;
|
SCSI_PASS_THROUGH_DIRECT info;
|
||||||
|
@ -332,43 +314,21 @@ bool IOCtlSrc::ReadCDInfo()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOCtlSrc::RefreshDiscInfo()
|
bool IOCtlSrc::DiscReady()
|
||||||
{
|
{
|
||||||
if (m_disc_ready)
|
if (m_device == INVALID_HANDLE_VALUE)
|
||||||
return true;
|
|
||||||
|
|
||||||
m_media_type = 0;
|
|
||||||
m_layer_break = 0;
|
|
||||||
m_sectors = 0;
|
|
||||||
|
|
||||||
if (!OpenOK)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ReadDVDInfo() || ReadCDInfo())
|
DWORD unused;
|
||||||
m_disc_ready = true;
|
if (DeviceIoControl(m_device, IOCTL_STORAGE_CHECK_VERIFY, nullptr, 0,
|
||||||
|
nullptr, 0, &unused, nullptr)) {
|
||||||
return m_disc_ready;
|
if (!m_sectors)
|
||||||
}
|
Reopen();
|
||||||
|
} else {
|
||||||
s32 IOCtlSrc::DiscChanged()
|
m_sectors = 0;
|
||||||
{
|
m_layer_break = 0;
|
||||||
DWORD size = 0;
|
m_media_type = 0;
|
||||||
|
|
||||||
if (!OpenOK)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int ret = DeviceIoControl(m_device, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, NULL, 0, &size, NULL);
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
m_disc_ready = false;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return !!m_sectors;
|
||||||
}
|
|
||||||
|
|
||||||
s32 IOCtlSrc::IsOK()
|
|
||||||
{
|
|
||||||
return OpenOK;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue