From 029461c5ae98199ed925db09b401129caa316224 Mon Sep 17 00:00:00 2001 From: Filjo Abraham Date: Wed, 1 Jul 2020 21:11:42 -0500 Subject: [PATCH] CDVD: merging and removing remnants of plugin --- PCSX2_suite.sln | 27 +- cmake/SelectPcsx2Plugins.cmake | 20 - common/include/PS2Edefs.h | 152 +----- common/include/PluginCallbacks.h | 2 - pcsx2/CDVD/CDVD.cpp | 4 +- pcsx2/CDVD/CDVD.h | 2 +- pcsx2/CDVD/CDVDaccess.cpp | 19 +- pcsx2/CDVD/CDVDaccess.h | 100 +++- pcsx2/CDVD/CDVDdiscReader.cpp | 444 ++++++++++++++- pcsx2/CDVD/CDVDdiscReader.h | 91 +++ pcsx2/CDVD/CDVDdiscThread.cpp | 406 ++++++++++++++ pcsx2/CDVD/CdRom.h | 2 +- pcsx2/CDVD/Unix/DriveUtility.cpp | 76 +++ pcsx2/CDVD/Unix/IOCtlSrc.cpp | 216 ++++++++ pcsx2/CDVD/Windows/DriveUtility.cpp | 64 +++ pcsx2/CDVD/Windows/IOCtlSrc.cpp | 303 ++++++++++ pcsx2/CMakeLists.txt | 19 +- pcsx2/Config.h | 1 - pcsx2/PluginManager.cpp | 136 ----- pcsx2/Plugins.h | 4 +- pcsx2/System.h | 2 +- pcsx2/System/SysCoreThread.cpp | 2 + pcsx2/gui/App.h | 2 +- pcsx2/gui/AppConfig.cpp | 22 +- pcsx2/gui/AppConfig.h | 2 + pcsx2/gui/AppCoreThread.cpp | 4 +- pcsx2/gui/AppInit.cpp | 6 +- pcsx2/gui/AppMain.cpp | 9 +- pcsx2/gui/Dialogs/DriveSelectorDialog.cpp | 34 +- pcsx2/gui/Dialogs/ModalPopups.h | 2 +- pcsx2/gui/MainFrame.cpp | 1 - pcsx2/gui/MainFrame.h | 5 +- pcsx2/gui/MainMenuClicks.cpp | 131 ++++- pcsx2/gui/SysState.cpp | 1 - pcsx2/windows/VCprojects/pcsx2.vcxproj | 17 + .../windows/VCprojects/pcsx2.vcxproj.filters | 21 + plugins/CDVDnull/CDVD.cpp | 148 ----- plugins/CDVDnull/CDVD.h | 42 -- plugins/CDVDnull/CMakeLists.txt | 44 -- plugins/CDVDnull/ReadMe.txt | 39 -- plugins/CDVDnull/Windows/CDVDnull.def | 29 - plugins/CDVDnull/Windows/CDVDnull.vcxproj | 98 ---- .../CDVDnull/Windows/CDVDnull.vcxproj.filters | 24 - plugins/CDVDnull/Windows/ProjectRootDir.props | 15 - plugins/CDVDnull/Windows/plugin.def | 21 - plugins/CMakeLists.txt | 8 - plugins/cdvdGigaherz/src/CDVD.cpp | 516 ------------------ plugins/cdvdGigaherz/src/CDVD.h | 136 ----- plugins/cdvdGigaherz/src/CMakeLists.txt | 53 -- plugins/cdvdGigaherz/src/ReadThread.cpp | 398 -------------- plugins/cdvdGigaherz/src/Settings.cpp | 126 ----- plugins/cdvdGigaherz/src/Settings.h | 41 -- plugins/cdvdGigaherz/src/TocStuff.cpp | 62 --- plugins/cdvdGigaherz/src/Unix/GtkGui.cpp | 56 -- plugins/cdvdGigaherz/src/Unix/LinuxConfig.cpp | 77 --- .../cdvdGigaherz/src/Unix/LinuxIOCtlSrc.cpp | 212 ------- plugins/cdvdGigaherz/src/Windows/IOCtlSrc.cpp | 298 ---------- .../cdvdGigaherz/src/Windows/cdvdGigaherz.rc | 102 ---- .../src/Windows/cdvdGigaherz.vcxproj | 85 --- .../src/Windows/cdvdGigaherz.vcxproj.filters | 76 --- plugins/cdvdGigaherz/src/Windows/config.cpp | 127 ----- plugins/cdvdGigaherz/src/Windows/plugin.def | 25 - plugins/cdvdGigaherz/src/Windows/resource.h | 42 -- 63 files changed, 1921 insertions(+), 3328 deletions(-) create mode 100644 pcsx2/CDVD/CDVDdiscThread.cpp create mode 100644 pcsx2/CDVD/Unix/DriveUtility.cpp create mode 100644 pcsx2/CDVD/Unix/IOCtlSrc.cpp create mode 100644 pcsx2/CDVD/Windows/DriveUtility.cpp create mode 100644 pcsx2/CDVD/Windows/IOCtlSrc.cpp delete mode 100644 plugins/CDVDnull/CDVD.cpp delete mode 100644 plugins/CDVDnull/CDVD.h delete mode 100644 plugins/CDVDnull/CMakeLists.txt delete mode 100644 plugins/CDVDnull/ReadMe.txt delete mode 100644 plugins/CDVDnull/Windows/CDVDnull.def delete mode 100644 plugins/CDVDnull/Windows/CDVDnull.vcxproj delete mode 100644 plugins/CDVDnull/Windows/CDVDnull.vcxproj.filters delete mode 100644 plugins/CDVDnull/Windows/ProjectRootDir.props delete mode 100644 plugins/CDVDnull/Windows/plugin.def delete mode 100644 plugins/cdvdGigaherz/src/CDVD.cpp delete mode 100644 plugins/cdvdGigaherz/src/CDVD.h delete mode 100644 plugins/cdvdGigaherz/src/CMakeLists.txt delete mode 100644 plugins/cdvdGigaherz/src/ReadThread.cpp delete mode 100644 plugins/cdvdGigaherz/src/Settings.cpp delete mode 100644 plugins/cdvdGigaherz/src/Settings.h delete mode 100644 plugins/cdvdGigaherz/src/TocStuff.cpp delete mode 100644 plugins/cdvdGigaherz/src/Unix/GtkGui.cpp delete mode 100644 plugins/cdvdGigaherz/src/Unix/LinuxConfig.cpp delete mode 100644 plugins/cdvdGigaherz/src/Unix/LinuxIOCtlSrc.cpp delete mode 100644 plugins/cdvdGigaherz/src/Windows/IOCtlSrc.cpp delete mode 100644 plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.rc delete mode 100644 plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj delete mode 100644 plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj.filters delete mode 100644 plugins/cdvdGigaherz/src/Windows/config.cpp delete mode 100644 plugins/cdvdGigaherz/src/Windows/plugin.def delete mode 100644 plugins/cdvdGigaherz/src/Windows/resource.h diff --git a/PCSX2_suite.sln b/PCSX2_suite.sln index c22adcc83b..a13c92746c 100644 --- a/PCSX2_suite.sln +++ b/PCSX2_suite.sln @@ -60,8 +60,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2cpp", "tools\bin2cpp\bi EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "3rdparty\libjpeg\libjpeg.vcxproj", "{BC236261-77E8-4567-8D09-45CD02965EB6}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cdvdGigaherz", "plugins\cdvdGigaherz\src\Windows\cdvdGigaherz.vcxproj", "{5CF88D5F-64DD-4EDC-9F1A-436BD502940A}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "portaudio", "3rdparty\portaudio\build\msvc\portaudio.vcxproj", "{0A18A071-125E-442F-AFF7-A3F68ABECF99}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DEV9ghzdrk", "plugins\dev9ghzdrk\Win32\DEV9ghzdrk.vcxproj", "{BBE4E5FB-530A-4D18-A633-35AF0577B7F3}" @@ -360,26 +358,6 @@ Global {BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.Build.0 = Release|Win32 {BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.ActiveCfg = Release|x64 {BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.Build.0 = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Debug|Win32.ActiveCfg = Debug|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Debug|Win32.Build.0 = Debug|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Debug|x64.ActiveCfg = Debug|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Debug|x64.Build.0 = Debug|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Devel|Win32.ActiveCfg = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Devel|Win32.Build.0 = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Devel|x64.ActiveCfg = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Devel|x64.Build.0 = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release AVX2|Win32.ActiveCfg = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release AVX2|Win32.Build.0 = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release AVX2|x64.ActiveCfg = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release AVX2|x64.Build.0 = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release SSE4|Win32.ActiveCfg = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release SSE4|Win32.Build.0 = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release SSE4|x64.ActiveCfg = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release SSE4|x64.Build.0 = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release|Win32.ActiveCfg = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release|Win32.Build.0 = Release|Win32 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release|x64.ActiveCfg = Release|x64 - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A}.Release|x64.Build.0 = Release|x64 {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug (NO ASIO)|Win32 {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug (NO ASIO)|Win32 {0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug (NO ASIO)|x64 @@ -620,7 +598,6 @@ Global {4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053} {677B7D11-D5E1-40B3-88B1-9A4DF83D2213} = {2D6F0A62-A247-4CCF-947F-FCD54BE16103} {BC236261-77E8-4567-8D09-45CD02965EB6} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38} - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A} = {703FD00B-D7A0-41E3-BD03-CEC86B385DAF} {0A18A071-125E-442F-AFF7-A3F68ABECF99} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38} {BBE4E5FB-530A-4D18-A633-35AF0577B7F3} = {7A407562-D70F-4F0A-9D3E-B32506416003} {7A407562-D70F-4F0A-9D3E-B32506416003} = {703FD00B-D7A0-41E3-BD03-CEC86B385DAF} @@ -635,6 +612,10 @@ Global {12728250-16EC-4DC6-94D7-E21DD88947F8} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution +<<<<<<< HEAD SolutionGuid = {0BC474EA-3628-45D3-9DBC-E22D0B7E0F77} +======= + SolutionGuid = {E0DF661E-BE9A-4467-A034-16AA535A1CB5} +>>>>>>> CDVD: merging and removing remnants of plugin EndGlobalSection EndGlobal diff --git a/cmake/SelectPcsx2Plugins.cmake b/cmake/SelectPcsx2Plugins.cmake index eba59f360b..bea8505601 100644 --- a/cmake/SelectPcsx2Plugins.cmake +++ b/cmake/SelectPcsx2Plugins.cmake @@ -82,26 +82,6 @@ endif() # be build. #------------------------------------------------------------------------------- -#--------------------------------------- -# CDVDnull -#--------------------------------------- -if(GTKn_FOUND) - set(CDVDnull TRUE) -endif() -#--------------------------------------- - -#--------------------------------------- -# cdvdGigaherz -#--------------------------------------- -if(NOT EXISTS "${CMAKE_SOURCE_DIR}/plugins/cdvdGigaherz" OR NOT Linux) - set(cdvdGigaherz FALSE) -elseif(Linux AND GTKn_FOUND AND LIBUDEV_FOUND) - set(cdvdGigaherz TRUE) -else() - set(cdvdGigaherz FALSE) - print_dep("Skip build of cdvdGigaherz: missing dependencies" "${msg_dep_cdvdgiga}") -endif() -#--------------------------------------- #--------------------------------------- # dev9null diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index ffdcc63b00..271d54bab2 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -74,8 +74,7 @@ typedef struct _keyEvent /////////////////////////////////////////////////////////////////////// #if defined(GSdefs) || defined(PADdefs) || defined(SIOdefs) || \ - defined(SPU2defs) || defined(CDVDdefs) || defined(DEV9defs) || \ - defined(USBdefs) || defined(FWdefs) + defined(SPU2defs) || defined(DEV9defs) || defined(USBdefs) || defined(FWdefs) #define COMMONdefs #endif @@ -83,7 +82,6 @@ typedef struct _keyEvent #define PS2E_LT_GS 0x01 #define PS2E_LT_PAD 0x02 // -=[ OBSOLETE ]=- #define PS2E_LT_SPU2 0x04 -#define PS2E_LT_CDVD 0x08 #define PS2E_LT_DEV9 0x10 #define PS2E_LT_USB 0x20 #define PS2E_LT_FW 0x40 @@ -93,7 +91,6 @@ typedef struct _keyEvent #define PS2E_GS_VERSION 0x0006 #define PS2E_PAD_VERSION 0x0002 // -=[ OBSOLETE ]=- #define PS2E_SPU2_VERSION 0x0005 -#define PS2E_CDVD_VERSION 0x0005 #define PS2E_DEV9_VERSION 0x0003 #define PS2E_USB_VERSION 0x0003 #define PS2E_FW_VERSION 0x0002 @@ -131,69 +128,6 @@ typedef char __keyEvent_Size__[(sizeof(keyEvent) == 8) ? 1 : -1]; typedef int(CALLBACK *SIOchangeSlotCB)(int slot); -typedef struct _cdvdSubQ -{ - u8 ctrl : 4; // control and mode bits - u8 mode : 4; // control and mode bits - u8 trackNum; // current track number (1 to 99) - u8 trackIndex; // current index within track (0 to 99) - u8 trackM; // current minute location on the disc (BCD encoded) - u8 trackS; // current sector location on the disc (BCD encoded) - u8 trackF; // current frame location on the disc (BCD encoded) - u8 pad; // unused - u8 discM; // current minute offset from first track (BCD encoded) - u8 discS; // current sector offset from first track (BCD encoded) - u8 discF; // current frame offset from first track (BCD encoded) -} cdvdSubQ; - -typedef struct _cdvdTD -{ // NOT bcd coded - u32 lsn; - u8 type; -} cdvdTD; - -typedef struct _cdvdTN -{ - u8 strack; //number of the first track (usually 1) - u8 etrack; //number of the last track -} cdvdTN; - -// CDVDreadTrack mode values: -#define CDVD_MODE_2352 0 // full 2352 bytes -#define CDVD_MODE_2340 1 // skip sync (12) bytes -#define CDVD_MODE_2328 2 // skip sync+head+sub (24) bytes -#define CDVD_MODE_2048 3 // skip sync+head+sub (24) bytes -#define CDVD_MODE_2368 4 // full 2352 bytes + 16 subq - -// CDVDgetDiskType returns: -#define CDVD_TYPE_ILLEGAL 0xff // Illegal Disc -#define CDVD_TYPE_DVDV 0xfe // DVD Video -#define CDVD_TYPE_CDDA 0xfd // Audio CD -#define CDVD_TYPE_PS2DVD 0x14 // PS2 DVD -#define CDVD_TYPE_PS2CDDA 0x13 // PS2 CD (with audio) -#define CDVD_TYPE_PS2CD 0x12 // PS2 CD -#define CDVD_TYPE_PSCDDA 0x11 // PS CD (with audio) -#define CDVD_TYPE_PSCD 0x10 // PS CD -#define CDVD_TYPE_UNKNOWN 0x05 // Unknown -#define CDVD_TYPE_DETCTDVDD 0x04 // Detecting Dvd Dual Sided -#define CDVD_TYPE_DETCTDVDS 0x03 // Detecting Dvd Single Sided -#define CDVD_TYPE_DETCTCD 0x02 // Detecting Cd -#define CDVD_TYPE_DETCT 0x01 // Detecting -#define CDVD_TYPE_NODISC 0x00 // No Disc - -// CDVDgetTrayStatus returns: -#define CDVD_TRAY_CLOSE 0x00 -#define CDVD_TRAY_OPEN 0x01 - -// cdvdTD.type (track types for cds) -#define CDVD_AUDIO_TRACK 0x01 -#define CDVD_MODE1_TRACK 0x41 -#define CDVD_MODE2_TRACK 0x61 - -#define CDVD_AUDIO_MASK 0x00 -#define CDVD_DATA_MASK 0x40 -// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel) - typedef void (*DEV9callback)(int cycles); typedef int (*DEV9handler)(void); @@ -367,55 +301,6 @@ s32 CALLBACK SPU2test(); #endif -/* CDVD plugin API */ - -// if this file is included with this define -// the next api will not be skipped by the compiler -#if defined(CDVDdefs) || defined(BUILTIN_CDVD_PLUGIN) - -// basic funcs - -s32 CALLBACK CDVDinit(); -s32 CALLBACK CDVDopen(const char *pTitleFilename); -void CALLBACK CDVDclose(); -void CALLBACK CDVDshutdown(); -void CALLBACK CDVDsetSettingsDir(const char *dir); -void CALLBACK CDVDsetLogDir(const char *dir); - -s32 CALLBACK CDVDreadTrack(u32 lsn, int mode); - -// return can be NULL (for async modes) -u8 *CALLBACK CDVDgetBuffer(); - -s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ *subq); //read subq from disc (only cds have subq data) -s32 CALLBACK CDVDgetTN(cdvdTN *Buffer); //disk information -s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type -s32 CALLBACK CDVDgetTOC(void *toc); //gets ps2 style toc from disc -s32 CALLBACK CDVDgetDiskType(); //CDVD_TYPE_xxxx -s32 CALLBACK CDVDgetTrayStatus(); //CDVD_TRAY_xxxx -s32 CALLBACK CDVDctrlTrayOpen(); //open disc tray -s32 CALLBACK CDVDctrlTrayClose(); //close disc tray - -// extended funcs - -void CALLBACK CDVDconfigure(); -void CALLBACK CDVDabout(); -s32 CALLBACK CDVDtest(); -void CALLBACK CDVDnewDiskCB(void (*callback)()); - -// new funcs - -// read a track directly -s32 CALLBACK CDVDreadSector(u8 *buffer, u32 lsn, int mode); - -// improved getBuffer -s32 CALLBACK CDVDgetBuffer2(u8 *buffer); - -// tool function -s32 CALLBACK CDVDgetDualInfo(s32 *dualType, u32 *_layer1start); - -#endif - /* DEV9 plugin API */ // if this file is included with this define @@ -597,41 +482,6 @@ typedef void(CALLBACK *_SPU2setTimeStretcher)(short int enable); typedef void(CALLBACK *_SPU2async)(u32 cycles); - -// CDVD -// NOTE: The read/write functions CANNOT use XMM/MMX regs -// If you want to use them, need to save and restore current ones -typedef s32(CALLBACK *_CDVDopen)(const char *pTitleFilename); - -// Initiates an asynchronous track read operation. -// Returns -1 on error (invalid track) -// Returns 0 on success. -typedef s32(CALLBACK *_CDVDreadTrack)(u32 lsn, int mode); - -// *OBSOLETE* returns a pointer to the buffer, or NULL if data hasn't finished -// loading yet. -typedef u8 *(CALLBACK *_CDVDgetBuffer)(); - -// Copies loaded data to the target buffer. -// Returns -2 if the asynchronous read is still pending. -// Returns -1 if the asyncronous read failed. -// Returns 0 on success. -typedef s32(CALLBACK *_CDVDgetBuffer2)(u8 *buffer); - -typedef s32(CALLBACK *_CDVDreadSubQ)(u32 lsn, cdvdSubQ *subq); -typedef s32(CALLBACK *_CDVDgetTN)(cdvdTN *Buffer); -typedef s32(CALLBACK *_CDVDgetTD)(u8 Track, cdvdTD *Buffer); -typedef s32(CALLBACK *_CDVDgetTOC)(void *toc); -typedef s32(CALLBACK *_CDVDgetDiskType)(); -typedef s32(CALLBACK *_CDVDgetTrayStatus)(); -typedef s32(CALLBACK *_CDVDctrlTrayOpen)(); -typedef s32(CALLBACK *_CDVDctrlTrayClose)(); -typedef s32(CALLBACK *_CDVDreadSector)(u8 *buffer, u32 lsn, int mode); -typedef s32(CALLBACK *_CDVDgetDualInfo)(s32 *dualType, u32 *_layer1start); - -typedef void(CALLBACK *_CDVDnewDiskCB)(void (*callback)()); - - // DEV9 // NOTE: The read/write functions CANNOT use XMM/MMX regs // If you want to use them, need to save and restore current ones diff --git a/common/include/PluginCallbacks.h b/common/include/PluginCallbacks.h index 7717001bae..4742d7e6b6 100644 --- a/common/include/PluginCallbacks.h +++ b/common/include/PluginCallbacks.h @@ -178,7 +178,6 @@ enum PS2E_ComponentTypes { PS2E_TYPE_GS = 0, PS2E_TYPE_PAD, PS2E_TYPE_SPU2, - PS2E_TYPE_CDVD, PS2E_TYPE_DEV9, PS2E_TYPE_USB, PS2E_TYPE_FW, @@ -190,7 +189,6 @@ enum PluginLibVersion { PS2E_VER_GS = 0x1000, PS2E_VER_PAD = 0x1000, PS2E_VER_SPU2 = 0x1000, - PS2E_VER_CDVD = 0x1000, PS2E_VER_DEV9 = 0x1000, PS2E_VER_USB = 0x1000, PS2E_VER_FW = 0x1000, diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index fe1e5ba386..957015c3ed 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -317,7 +317,7 @@ s32 cdvdWriteConfig(const u8* config) static MutexRecursive Mutex_NewDiskCB; -// Sets ElfCRC to the CRC of the game bound to the CDVD plugin. +// Sets ElfCRC to the CRC of the game bound to the CDVD source. static __fi ElfObject* loadElf( const wxString filename ) { if (filename.StartsWith(L"host")) @@ -625,7 +625,7 @@ void SaveStateBase::cdvdFreeze() if (IsLoading()) { - // Make sure the Cdvd plugin has the expected track loaded into the buffer. + // Make sure the Cdvd source has the expected track loaded into the buffer. // If cdvd.Readed is cleared it means we need to load the SeekToSector (ie, a // seek is in progress!) diff --git a/pcsx2/CDVD/CDVD.h b/pcsx2/CDVD/CDVD.h index 7714d6fb36..bb8fb3aba3 100644 --- a/pcsx2/CDVD/CDVD.h +++ b/pcsx2/CDVD/CDVD.h @@ -18,7 +18,7 @@ #include "IopCommon.h" -#include "CDVD/CDVDaccess.h" +#include "CDVDaccess.h" #define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ #define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index ec431782a3..c4ea6066c3 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -36,10 +36,11 @@ #include "DebugTools/SymbolMap.h" #include "AppConfig.h" +CDVD_API* CDVD = NULL; + const wxChar* CDVD_SourceLabels[] = { L"ISO", - L"Plugin", L"Disc", L"NoDisc", NULL @@ -250,10 +251,13 @@ static void DetectDiskType() int baseMediaType = CDVD->getDiskType(); int mType = -1; - + // Paranoid mode: do not trust the plugin's detection system to work correctly. // (.. and there's no reason plugins should be doing their own detection anyway). + //TODO_CDVD We're not using CDVD plugins anymore but I believe both ISO and Disc use their own + //detection system. Possible code reduction here + switch(baseMediaType) { #if 0 @@ -320,8 +324,6 @@ CDVD_SourceType CDVDsys_GetSourceType() void CDVDsys_ChangeSource( CDVD_SourceType type ) { - GetCorePlugins().Close( PluginId_CDVD ); - switch( m_CurrentSourceType = type ) { case CDVD_SourceType::Iso: @@ -336,10 +338,6 @@ void CDVDsys_ChangeSource( CDVD_SourceType type ) CDVD = &CDVDapi_NoDisc; break; - case CDVD_SourceType::Plugin: - CDVD = &CDVDapi_Plugin; - break; - jNO_DEFAULT; } } @@ -359,13 +357,15 @@ bool DoCDVDopen() // question marks if the filename is another language. // Likely Fix: Force new versions of CDVD plugins to expect UTF8 instead. + //TODO_CDVD check if ISO and Disc use UTF8 + auto CurrentSourceType = enum_cast(m_CurrentSourceType); int ret = CDVD->open( !m_SourceFilename[CurrentSourceType].IsEmpty() ? static_cast(m_SourceFilename[CurrentSourceType].ToUTF8()) : (char*)NULL ); if( ret == -1 ) return false; // error! (handled by caller) - if( ret == 1 ) throw Exception::CancelEvent(L"User canceled the CDVD plugin's open dialog."); + //if( ret == 1 ) throw Exception::CancelEvent(L"User canceled the CDVD plugin's open dialog."); <--- TODO_CDVD is this still needed? int cdtype = DoCDVDdetectDiskType(); @@ -466,6 +466,7 @@ s32 DoCDVDreadTrack(u32 lsn, int mode) { CheckNullCDVD(); + //TODO_CDVD I believe ISO and Disc use the new CDVDgetBuffer style // TEMP: until all the plugins use the new CDVDgetBuffer style switch (mode) { diff --git a/pcsx2/CDVD/CDVDaccess.h b/pcsx2/CDVD/CDVDaccess.h index 6e6b18cd07..739cba7a3c 100644 --- a/pcsx2/CDVD/CDVDaccess.h +++ b/pcsx2/CDVD/CDVDaccess.h @@ -15,12 +15,105 @@ #pragma once -#include "Plugins.h" +typedef struct _cdvdSubQ +{ + u8 ctrl : 4; // control and mode bits + u8 mode : 4; // control and mode bits + u8 trackNum; // current track number (1 to 99) + u8 trackIndex; // current index within track (0 to 99) + u8 trackM; // current minute location on the disc (BCD encoded) + u8 trackS; // current sector location on the disc (BCD encoded) + u8 trackF; // current frame location on the disc (BCD encoded) + u8 pad; // unused + u8 discM; // current minute offset from first track (BCD encoded) + u8 discS; // current sector offset from first track (BCD encoded) + u8 discF; // current frame offset from first track (BCD encoded) +} cdvdSubQ; + +typedef struct _cdvdTD +{ // NOT bcd coded + u32 lsn; + u8 type; +} cdvdTD; + +typedef struct _cdvdTN +{ + u8 strack; //number of the first track (usually 1) + u8 etrack; //number of the last track +} cdvdTN; + +// CDVDreadTrack mode values: +#define CDVD_MODE_2352 0 // full 2352 bytes +#define CDVD_MODE_2340 1 // skip sync (12) bytes +#define CDVD_MODE_2328 2 // skip sync+head+sub (24) bytes +#define CDVD_MODE_2048 3 // skip sync+head+sub (24) bytes +#define CDVD_MODE_2368 4 // full 2352 bytes + 16 subq + +// CDVDgetDiskType returns: +#define CDVD_TYPE_ILLEGAL 0xff // Illegal Disc +#define CDVD_TYPE_DVDV 0xfe // DVD Video +#define CDVD_TYPE_CDDA 0xfd // Audio CD +#define CDVD_TYPE_PS2DVD 0x14 // PS2 DVD +#define CDVD_TYPE_PS2CDDA 0x13 // PS2 CD (with audio) +#define CDVD_TYPE_PS2CD 0x12 // PS2 CD +#define CDVD_TYPE_PSCDDA 0x11 // PS CD (with audio) +#define CDVD_TYPE_PSCD 0x10 // PS CD +#define CDVD_TYPE_UNKNOWN 0x05 // Unknown +#define CDVD_TYPE_DETCTDVDD 0x04 // Detecting Dvd Dual Sided +#define CDVD_TYPE_DETCTDVDS 0x03 // Detecting Dvd Single Sided +#define CDVD_TYPE_DETCTCD 0x02 // Detecting Cd +#define CDVD_TYPE_DETCT 0x01 // Detecting +#define CDVD_TYPE_NODISC 0x00 // No Disc + +// CDVDgetTrayStatus returns: +#define CDVD_TRAY_CLOSE 0x00 +#define CDVD_TRAY_OPEN 0x01 + +// cdvdTD.type (track types for cds) +#define CDVD_AUDIO_TRACK 0x01 +#define CDVD_MODE1_TRACK 0x41 +#define CDVD_MODE2_TRACK 0x61 + +#define CDVD_AUDIO_MASK 0x00 +#define CDVD_DATA_MASK 0x40 +// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel) + +// CDVD +// NOTE: The read/write functions CANNOT use XMM/MMX regs +// If you want to use them, need to save and restore current ones +typedef s32(CALLBACK* _CDVDopen)(const char* pTitleFilename); + +// Initiates an asynchronous track read operation. +// Returns -1 on error (invalid track) +// Returns 0 on success. +typedef s32(CALLBACK* _CDVDreadTrack)(u32 lsn, int mode); + +// *OBSOLETE* returns a pointer to the buffer, or NULL if data hasn't finished +// loading yet. +typedef u8* (CALLBACK* _CDVDgetBuffer)(); + +// Copies loaded data to the target buffer. +// Returns -2 if the asynchronous read is still pending. +// Returns -1 if the asyncronous read failed. +// Returns 0 on success. +typedef s32(CALLBACK* _CDVDgetBuffer2)(u8* buffer); + +typedef s32(CALLBACK* _CDVDreadSubQ)(u32 lsn, cdvdSubQ* subq); +typedef s32(CALLBACK* _CDVDgetTN)(cdvdTN* Buffer); +typedef s32(CALLBACK* _CDVDgetTD)(u8 Track, cdvdTD* Buffer); +typedef s32(CALLBACK* _CDVDgetTOC)(void* toc); +typedef s32(CALLBACK* _CDVDgetDiskType)(); +typedef s32(CALLBACK* _CDVDgetTrayStatus)(); +typedef s32(CALLBACK* _CDVDctrlTrayOpen)(); +typedef s32(CALLBACK* _CDVDctrlTrayClose)(); +typedef s32(CALLBACK* _CDVDreadSector)(u8* buffer, u32 lsn, int mode); +typedef s32(CALLBACK* _CDVDgetDualInfo)(s32* dualType, u32* _layer1start); + +typedef void(CALLBACK* _CDVDnewDiskCB)(void (*callback)()); enum class CDVD_SourceType : uint8_t { Iso, // use built in ISO api - Plugin, // use external plugin Disc, // use built in Disc api NoDisc, // use built in CDVDnull }; @@ -60,9 +153,10 @@ struct CDVD_API // direct CDVD plugin invocation, and add universal block dumping features. // ---------------------------------------------------------------------------- +//TODO_CDVD update comment ^ + extern CDVD_API* CDVD; // currently active CDVD access mode api (either Iso, NoDisc, or Plugin) -extern CDVD_API CDVDapi_Plugin; extern CDVD_API CDVDapi_Iso; extern CDVD_API CDVDapi_Disc; extern CDVD_API CDVDapi_NoDisc; diff --git a/pcsx2/CDVD/CDVDdiscReader.cpp b/pcsx2/CDVD/CDVDdiscReader.cpp index 83e5ee7e13..42c081fffb 100644 --- a/pcsx2/CDVD/CDVDdiscReader.cpp +++ b/pcsx2/CDVD/CDVDdiscReader.cpp @@ -1,5 +1,5 @@ /* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2020 PCSX2 Dev Team + * Copyright (C) 2002-2014 David Quintana [gigaherz] * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- @@ -14,79 +14,485 @@ */ #include "PrecompiledHeader.h" -#include "IopCommon.h" +#include "CDVDdiscReader.h" + +#include "AppConfig.h" + +#include + +void (*newDiscCB)(); + +static std::mutex s_keepalive_lock; +static std::condition_variable s_keepalive_cv; +static std::thread s_keepalive_thread; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// State Information // + +u8 strack; +u8 etrack; +track tracks[100]; + +int curDiskType; +int curTrayStatus; + +static u32 csector; +int cmode; + +int lastReadInNewDiskCB = 0; +u8 directReadSectorBuffer[2448]; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Utility Functions // + +inline u8 dec_to_bcd(u8 dec) +{ + return ((dec / 10) << 4) | (dec % 10); +} + +inline void lsn_to_msf(u8* minute, u8* second, u8* frame, u32 lsn) +{ + *frame = dec_to_bcd(lsn % 75); + lsn /= 75; + *second = dec_to_bcd(lsn % 60); + lsn /= 60; + *minute = dec_to_bcd(lsn % 100); +} + +// TocStuff +void cdvdParseTOC() +{ + tracks[1].start_lba = 0; + + if (!src->GetSectorCount()) { + curDiskType = CDVD_TYPE_NODISC; + strack = 1; + etrack = 0; + return; + } + + if (src->GetMediaType() >= 0) { + tracks[1].type = CDVD_MODE1_TRACK; + + strack = 1; + etrack = 1; + return; + } + + strack = 0xFF; + etrack = 0; + + for (auto& entry : src->ReadTOC()) { + if (entry.track < 1 || entry.track > 99) + continue; + strack = std::min(strack, entry.track); + etrack = std::max(etrack, entry.track); + tracks[entry.track].start_lba = entry.lba; + if ((entry.control & 0x0C) == 0x04) { + std::array buffer; + // Byte 15 of a raw CD data sector determines the track mode + if (src->ReadSectors2352(entry.lba, 1, buffer.data()) && (buffer[15] & 3) == 2) { + tracks[entry.track].type = CDVD_MODE2_TRACK; + } + else { + tracks[entry.track].type = CDVD_MODE1_TRACK; + } + } + else { + tracks[entry.track].type = CDVD_AUDIO_TRACK; + } + fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba); + } +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// CDVD processing functions // + +std::atomic s_keepalive_is_open; +bool disc_has_changed = false; +bool weAreInNewDiskCB = false; + +std::unique_ptr src; + +extern u32 g_last_sector_block_lsn; + + /////////////////////////////////////////////////////////////////////////////// + // keepAliveThread throws a read event regularly to prevent drive spin down // + +void keepAliveThread() +{ + u8 throwaway[2352]; + + printf(" * CDVD: KeepAlive thread started...\n"); + std::unique_lock guard(s_keepalive_lock); + + while (!s_keepalive_cv.wait_for(guard, std::chrono::seconds(30), + []() { return !s_keepalive_is_open; })) { + + //printf(" * keepAliveThread: polling drive.\n"); + if (src->GetMediaType() >= 0) + src->ReadSectors2048(g_last_sector_block_lsn, 1, throwaway); + else + src->ReadSectors2352(g_last_sector_block_lsn, 1, throwaway); + } + + printf(" * CDVD: KeepAlive thread finished.\n"); +} + +bool StartKeepAliveThread() +{ + s_keepalive_is_open = true; + try { + s_keepalive_thread = std::thread(keepAliveThread); + } + catch (std::system_error&) { + s_keepalive_is_open = false; + } + + return s_keepalive_is_open; +} + +void StopKeepAliveThread() +{ + if (!s_keepalive_thread.joinable()) + return; + + { + std::lock_guard guard(s_keepalive_lock); + s_keepalive_is_open = false; + } + s_keepalive_cv.notify_one(); + s_keepalive_thread.join(); +} s32 CALLBACK DISCopen(const char* pTitle) { - return 0; +#if defined(_WIN32) + std::wstring drive = g_Conf->Folders.RunDisc.ToString().ToStdWstring(); +#else + std::string drive = g_Conf->Folders.RunDisc.ToString().ToStdString(); +#endif + GetValidDrive(drive); + + // open device file + try { + src = std::unique_ptr(new IOCtlSrc(drive)); + } + catch (std::runtime_error& ex) { + fputs(ex.what(), stdout); + return -1; + } + + //setup threading manager + if (!cdvdStartThread()) { + src.reset(); + return -1; + } + StartKeepAliveThread(); + + return cdvdRefreshData(); } void CALLBACK DISCclose() { + StopKeepAliveThread(); + cdvdStopThread(); + //close device + src.reset(); } s32 CALLBACK DISCreadTrack(u32 lsn, int mode) { - return -1; + csector = lsn; + cmode = mode; + + if (weAreInNewDiskCB) { + int ret = cdvdDirectReadSector(lsn, mode, directReadSectorBuffer); + if (ret == 0) + lastReadInNewDiskCB = 1; + return ret; + } + + cdvdRequestSector(lsn, mode); + + return 0; } // return can be NULL (for async modes) u8* CALLBACK DISCgetBuffer() { - return NULL; + if (lastReadInNewDiskCB) { + lastReadInNewDiskCB = 0; + return directReadSectorBuffer; + } + + return cdvdGetSector(csector, cmode); } s32 CALLBACK DISCreadSubQ(u32 lsn, cdvdSubQ* subq) { - return -1; + // the formatted subq command returns: control/adr, track, index, trk min, trk sec, trk frm, 0x00, abs min, abs sec, abs frm + + if (lsn >= src->GetSectorCount()) + return -1; + + memset(subq, 0, sizeof(cdvdSubQ)); + + lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150); + + u8 i = strack; + while (i < etrack && lsn >= tracks[i + 1].start_lba) + ++i; + + lsn -= tracks[i].start_lba; + + lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn); + + subq->mode = 1; + subq->ctrl = tracks[i].type; + subq->trackNum = i; + subq->trackIndex = 1; + + return 0; } s32 CALLBACK DISCgetTN(cdvdTN* Buffer) { - return -1; + Buffer->strack = strack; + Buffer->etrack = etrack; + return 0; } s32 CALLBACK DISCgetTD(u8 Track, cdvdTD* Buffer) { - return -1; + if (Track == 0) { + Buffer->lsn = src->GetSectorCount(); + Buffer->type = 0; + return 0; + } + + if (Track < strack) + return -1; + if (Track > etrack) + return -1; + + Buffer->lsn = tracks[Track].start_lba; + Buffer->type = tracks[Track].type; + return 0; } s32 CALLBACK DISCgetTOC(void* toc) { - return -1; + u8* tocBuff = static_cast(toc); + if (curDiskType == CDVD_TYPE_NODISC) + return -1; + + if (curDiskType == CDVD_TYPE_DETCTDVDS || curDiskType == CDVD_TYPE_DETCTDVDD) { + memset(tocBuff, 0, 2048); + + s32 mt = src->GetMediaType(); + + if (mt < 0) + return -1; + + if (mt == 0) { //single layer + // fake it + tocBuff[0] = 0x04; + tocBuff[1] = 0x02; + tocBuff[2] = 0xF2; + tocBuff[3] = 0x00; + tocBuff[4] = 0x86; + tocBuff[5] = 0x72; + + tocBuff[16] = 0x00; // first sector for layer 0 + tocBuff[17] = 0x03; + tocBuff[18] = 0x00; + tocBuff[19] = 0x00; + } + else if (mt == 1) { //PTP + u32 layer1start = src->GetLayerBreakAddress() + 0x30000; + + // dual sided + tocBuff[0] = 0x24; + tocBuff[1] = 0x02; + tocBuff[2] = 0xF2; + tocBuff[3] = 0x00; + tocBuff[4] = 0x41; + tocBuff[5] = 0x95; + + tocBuff[14] = 0x61; // PTP + + tocBuff[16] = 0x00; + tocBuff[17] = 0x03; + tocBuff[18] = 0x00; + tocBuff[19] = 0x00; + + tocBuff[20] = (layer1start >> 24); + tocBuff[21] = (layer1start >> 16) & 0xff; + tocBuff[22] = (layer1start >> 8) & 0xff; + tocBuff[23] = (layer1start >> 0) & 0xff; + } + else { //OTP + u32 layer1start = src->GetLayerBreakAddress() + 0x30000; + + // dual sided + tocBuff[0] = 0x24; + tocBuff[1] = 0x02; + tocBuff[2] = 0xF2; + tocBuff[3] = 0x00; + tocBuff[4] = 0x41; + tocBuff[5] = 0x95; + + tocBuff[14] = 0x71; // OTP + + tocBuff[16] = 0x00; + tocBuff[17] = 0x03; + tocBuff[18] = 0x00; + tocBuff[19] = 0x00; + + tocBuff[24] = (layer1start >> 24); + tocBuff[25] = (layer1start >> 16) & 0xff; + tocBuff[26] = (layer1start >> 8) & 0xff; + tocBuff[27] = (layer1start >> 0) & 0xff; + } + } + else if (curDiskType == CDVD_TYPE_DETCTCD) { + // cd toc + // (could be replaced by 1 command that reads the full toc) + u8 min, sec, frm, i; + s32 err; + cdvdTN diskInfo; + cdvdTD trackInfo; + memset(tocBuff, 0, 1024); + if (DISCgetTN(&diskInfo) == -1) { + diskInfo.etrack = 0; + diskInfo.strack = 1; + } + if (DISCgetTD(0, &trackInfo) == -1) + trackInfo.lsn = 0; + + tocBuff[0] = 0x41; + tocBuff[1] = 0x00; + + //Number of FirstTrack + tocBuff[2] = 0xA0; + tocBuff[7] = dec_to_bcd(diskInfo.strack); + + //Number of LastTrack + tocBuff[12] = 0xA1; + tocBuff[17] = dec_to_bcd(diskInfo.etrack); + + //DiskLength + lba_to_msf(trackInfo.lsn, &min, &sec, &frm); + tocBuff[22] = 0xA2; + tocBuff[27] = dec_to_bcd(min); + tocBuff[28] = dec_to_bcd(sec); + tocBuff[29] = dec_to_bcd(frm); + + fprintf(stderr, "Track 0: %u mins %u secs %u frames\n", min, sec, frm); + + for (i = diskInfo.strack; i <= diskInfo.etrack; i++) { + err = DISCgetTD(i, &trackInfo); + lba_to_msf(trackInfo.lsn, &min, &sec, &frm); + tocBuff[i * 10 + 30] = trackInfo.type; + tocBuff[i * 10 + 32] = err == -1 ? 0 : dec_to_bcd(i); //number + tocBuff[i * 10 + 37] = dec_to_bcd(min); + tocBuff[i * 10 + 38] = dec_to_bcd(sec); + tocBuff[i * 10 + 39] = dec_to_bcd(frm); + fprintf(stderr, "Track %u: %u mins %u secs %u frames\n", i, min, sec, frm); + } + } + else + return -1; + + return 0; } s32 CALLBACK DISCgetDiskType() { - return CDVD_TYPE_NODISC; + return curDiskType; } s32 CALLBACK DISCgetTrayStatus() { - return CDVD_TRAY_CLOSE; + return curTrayStatus; } -s32 CALLBACK DISCdummyS32() +s32 CALLBACK DISCctrlTrayOpen() { + curTrayStatus = CDVD_TRAY_OPEN; return 0; } -void CALLBACK DISCnewDiskCB(void (* /* callback */)()) +s32 CALLBACK DISCctrlTrayClose() { + curTrayStatus = CDVD_TRAY_CLOSE; + return 0; } -s32 CALLBACK DISCreadSector(u8* tempbuffer, u32 lsn, int mode) +void CALLBACK DISCnewDiskCB(void (*callback)()) { - return -1; + newDiscCB = callback; } -s32 CALLBACK DISCgetBuffer2(u8* buffer) +s32 CALLBACK DISCreadSector(u8* buffer, u32 lsn, int mode) { - return -1; + return cdvdDirectReadSector(lsn, mode, buffer); +} + +s32 CALLBACK DISCgetBuffer2(u8* dest) +{ + // Do nothing for out of bounds disc sector reads. It prevents some games + // from hanging (All-Star Baseball 2005, Hello Kitty: Roller Rescue, + // Hot Wheels: Beat That! (NTSC), Ratchet & Clank 3 (PAL), + // Test Drive: Eve of Destruction, etc.). + if (csector >= src->GetSectorCount()) + return 0; + + int csize = 2352; + switch (cmode) { + case CDVD_MODE_2048: + csize = 2048; + break; + case CDVD_MODE_2328: + csize = 2328; + break; + case CDVD_MODE_2340: + csize = 2340; + break; + } + + if (lastReadInNewDiskCB) { + lastReadInNewDiskCB = 0; + + memcpy(dest, directReadSectorBuffer, csize); + return 0; + } + + memcpy(dest, cdvdGetSector(csector, cmode), csize); + + return 0; } s32 CALLBACK DISCgetDualInfo(s32* dualType, u32* _layer1start) { + switch (src->GetMediaType()) { + case 1: + *dualType = 1; + *_layer1start = src->GetLayerBreakAddress() + 1; + return 0; + case 2: + *dualType = 2; + *_layer1start = src->GetLayerBreakAddress() + 1; + return 0; + case 0: + *dualType = 0; + *_layer1start = 0; + return 0; + } return -1; } @@ -102,8 +508,8 @@ CDVD_API CDVDapi_Disc = DISCgetTOC, DISCgetDiskType, DISCgetTrayStatus, - DISCdummyS32, - DISCdummyS32, + DISCctrlTrayOpen, + DISCctrlTrayClose, DISCnewDiskCB, diff --git a/pcsx2/CDVD/CDVDdiscReader.h b/pcsx2/CDVD/CDVDdiscReader.h index b3a7b09282..7f01f8f9af 100644 --- a/pcsx2/CDVD/CDVDdiscReader.h +++ b/pcsx2/CDVD/CDVDdiscReader.h @@ -18,4 +18,95 @@ #include "IopCommon.h" +#if defined(_WIN32) +#define _WIN32_WINNT 0x0600 +#define NOMINMAX +#include +#endif + +#include +#include + +struct track +{ + u32 start_lba; + u8 type; +}; + +extern u8 strack; +extern u8 etrack; +extern track tracks[100]; + +extern int curDiskType; +extern int curTrayStatus; + +struct toc_entry +{ + u32 lba; + u8 track; + u8 adr : 4; + u8 control : 4; +}; + +class IOCtlSrc +{ + IOCtlSrc(const IOCtlSrc&) = delete; + IOCtlSrc& operator=(const IOCtlSrc&) = delete; + +#if defined(_WIN32) + HANDLE m_device = INVALID_HANDLE_VALUE; + std::wstring m_filename; + mutable std::mutex m_lock; +#else + int m_device = -1; + std::string m_filename; +#endif + + s32 m_media_type = 0; + u32 m_sectors = 0; + u32 m_layer_break = 0; + std::vector m_toc; + + bool ReadDVDInfo(); + bool ReadCDInfo(); + bool Reopen(); + +public: + IOCtlSrc(decltype(m_filename) filename); + ~IOCtlSrc(); + + u32 GetSectorCount() const; + const std::vector& ReadTOC() const; + bool ReadSectors2048(u32 sector, u32 count, u8* buffer) const; + bool ReadSectors2352(u32 sector, u32 count, u8* buffer) const; + u32 GetLayerBreakAddress() const; + s32 GetMediaType() const; + void SetSpindleSpeed(bool restore_defaults) const; + bool DiscReady(); +}; + +extern std::unique_ptr src; + +#if defined(_WIN32) +std::vector GetOpticalDriveList(); +void GetValidDrive(std::wstring& drive); +#else +std::vector GetOpticalDriveList(); +void GetValidDrive(std::string& drive); +#endif + +extern bool disc_has_changed; +extern bool weAreInNewDiskCB; + +extern void (*newDiscCB)(); + +bool cdvdStartThread(); +void cdvdStopThread(); +void cdvdRequestSector(u32 sector, s32 mode); +u8* cdvdGetSector(u32 sector, s32 mode); +s32 cdvdDirectReadSector(u32 sector, s32 mode, u8* buffer); +s32 cdvdGetMediaType(); +s32 cdvdRefreshData(); +void cdvdParseTOC(); + #endif /* __CDVD_DISC_READER_H__ */ \ No newline at end of file diff --git a/pcsx2/CDVD/CDVDdiscThread.cpp b/pcsx2/CDVD/CDVDdiscThread.cpp new file mode 100644 index 0000000000..ecf1c66ab0 --- /dev/null +++ b/pcsx2/CDVD/CDVDdiscThread.cpp @@ -0,0 +1,406 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2014 David Quintana [gigaherz] + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" +#include "CDVDdiscReader.h" + +#include +#include +#include +#include +#include + +const u32 sectors_per_read = 16; + +static_assert(sectors_per_read > 1 && !(sectors_per_read & (sectors_per_read - 1)), + "sectors_per_read must by a power of 2"); + +struct SectorInfo +{ + u32 lsn; + // Sectors are read in blocks, not individually + u8 data[2352 * sectors_per_read]; +}; + +u32 g_last_sector_block_lsn; + +static std::thread s_thread; + +static std::mutex s_notify_lock; +static std::condition_variable s_notify_cv; +static std::mutex s_request_lock; +static std::queue s_request_queue; +static std::mutex s_cache_lock; + +static std::atomic cdvd_is_open; + +//bits: 12 would use 1<<12 entries, or 4096*16 sectors ~ 128MB +#define CACHE_SIZE 12 + +const u32 CacheSize = 1U << CACHE_SIZE; +SectorInfo Cache[CacheSize]; + +u32 cdvdSectorHash(u32 lsn) +{ + u32 t = 0; + + int i = 32; + u32 m = CacheSize - 1; + + while (i >= 0) { + t ^= lsn & m; + lsn >>= CACHE_SIZE; + i -= CACHE_SIZE; + } + + return t & m; +} + +void cdvdCacheUpdate(u32 lsn, u8* data) +{ + std::lock_guard guard(s_cache_lock); + u32 entry = cdvdSectorHash(lsn); + + memcpy(Cache[entry].data, data, 2352 * sectors_per_read); + Cache[entry].lsn = lsn; +} + +bool cdvdCacheCheck(u32 lsn) +{ + std::lock_guard guard(s_cache_lock); + u32 entry = cdvdSectorHash(lsn); + + return Cache[entry].lsn == lsn; +} + +bool cdvdCacheFetch(u32 lsn, u8* data) +{ + std::lock_guard guard(s_cache_lock); + u32 entry = cdvdSectorHash(lsn); + + if (Cache[entry].lsn == lsn) { + memcpy(data, Cache[entry].data, 2352 * sectors_per_read); + return true; + } + //printf("NOT IN CACHE\n"); + return false; +} + +void cdvdCacheReset() +{ + std::lock_guard guard(s_cache_lock); + for (u32 i = 0; i < CacheSize; i++) { + Cache[i].lsn = std::numeric_limits::max(); + } +} + +bool cdvdReadBlockOfSectors(u32 sector, u8* data) +{ + u32 count = std::min(sectors_per_read, src->GetSectorCount() - sector); + const s32 media = src->GetMediaType(); + + // TODO: Is it really necessary to retry if it fails? I'm not sure the + // second time is really going to be any better. + for (int tries = 0; tries < 2; ++tries) { + if (media >= 0) { + if (src->ReadSectors2048(sector, count, data)) + return true; + } + else { + if (src->ReadSectors2352(sector, count, data)) + return true; + } + } + return false; +} + +void cdvdCallNewDiscCB() +{ + weAreInNewDiskCB = true; + newDiscCB(); + weAreInNewDiskCB = false; +} + +bool cdvdUpdateDiscStatus() +{ + bool ready = src->DiscReady(); + + if (!ready) { + if (!disc_has_changed) { + disc_has_changed = true; + curDiskType = CDVD_TYPE_NODISC; + curTrayStatus = CDVD_TRAY_OPEN; + cdvdCallNewDiscCB(); + } + } + else { + if (disc_has_changed) { + curDiskType = CDVD_TYPE_NODISC; + curTrayStatus = CDVD_TRAY_CLOSE; + + disc_has_changed = false; + cdvdRefreshData(); + + { + std::lock_guard request_guard(s_request_lock); + s_request_queue = decltype(s_request_queue)(); + } + + cdvdCallNewDiscCB(); + } + } + return !ready; +} + +void cdvdThread() +{ + u8 buffer[2352 * sectors_per_read]; + u32 prefetches_left = 0; + + printf(" * CDVD: IO thread started...\n"); + std::unique_lock guard(s_notify_lock); + + while (cdvd_is_open) { + if (cdvdUpdateDiscStatus()) { + // Need to sleep some to avoid an aggressive spin that sucks the cpu dry. + s_notify_cv.wait_for(guard, std::chrono::milliseconds(10)); + prefetches_left = 0; + continue; + } + + if (prefetches_left == 0) + s_notify_cv.wait_for(guard, std::chrono::milliseconds(250)); + + // check again to make sure we're not done here... + if (!cdvd_is_open) + break; + + // Read request + bool handling_request = false; + u32 request_lsn; + + { + std::lock_guard request_guard(s_request_lock); + if (!s_request_queue.empty()) { + request_lsn = s_request_queue.front(); + s_request_queue.pop(); + handling_request = true; + } + } + + if (!handling_request) { + if (prefetches_left == 0) + continue; + + --prefetches_left; + + u32 next_prefetch_lsn = g_last_sector_block_lsn + sectors_per_read; + request_lsn = next_prefetch_lsn; + } + + // Handle request + if (!cdvdCacheCheck(request_lsn)) { + if (cdvdReadBlockOfSectors(request_lsn, buffer)) { + cdvdCacheUpdate(request_lsn, buffer); + } + else { + // If the read fails, further reads are likely to fail too. + prefetches_left = 0; + continue; + } + } + + g_last_sector_block_lsn = request_lsn; + + if (!handling_request) + continue; + + // Prefetch + u32 next_prefetch_lsn = g_last_sector_block_lsn + sectors_per_read; + if (next_prefetch_lsn >= src->GetSectorCount()) { + prefetches_left = 0; + } + else { + const u32 max_prefetches = 16; + u32 remaining = src->GetSectorCount() - next_prefetch_lsn; + prefetches_left = std::min((remaining + sectors_per_read - 1) / sectors_per_read, max_prefetches); + } + } + printf(" * CDVD: IO thread finished.\n"); +} + +bool cdvdStartThread() +{ + cdvd_is_open = true; + try { + s_thread = std::thread(cdvdThread); + } + catch (std::system_error&) { + cdvd_is_open = false; + return false; + } + + cdvdCacheReset(); + + return true; +} + +void cdvdStopThread() +{ + cdvd_is_open = false; + s_notify_cv.notify_one(); + s_thread.join(); +} + +void cdvdRequestSector(u32 sector, s32 mode) +{ + if (sector >= src->GetSectorCount()) + return; + + // Align to cache block + sector &= ~(sectors_per_read - 1); + + if (cdvdCacheCheck(sector)) + return; + + { + std::lock_guard guard(s_request_lock); + s_request_queue.push(sector); + } + + s_notify_cv.notify_one(); +} + +u8* cdvdGetSector(u32 sector, s32 mode) +{ + static u8 buffer[2352 * sectors_per_read]; + + // Align to cache block + u32 sector_block = sector & ~(sectors_per_read - 1); + + if (!cdvdCacheFetch(sector_block, buffer)) + if (cdvdReadBlockOfSectors(sector_block, buffer)) + cdvdCacheUpdate(sector_block, buffer); + + if (src->GetMediaType() >= 0) { + u32 offset = 2048 * (sector - sector_block); + return buffer + offset; + } + + u32 offset = 2352 * (sector - sector_block); + u8* data = buffer + offset; + + switch (mode) { + case CDVD_MODE_2048: + // Data location depends on CD mode + return (data[15] & 3) == 2 ? data + 24 : data + 16; + case CDVD_MODE_2328: + return data + 24; + case CDVD_MODE_2340: + return data + 12; + } + return data; +} + +s32 cdvdDirectReadSector(u32 sector, s32 mode, u8* buffer) +{ + static u8 data[2352 * sectors_per_read]; + + if (sector >= src->GetSectorCount()) + return -1; + + // Align to cache block + u32 sector_block = sector & ~(sectors_per_read - 1); + + if (!cdvdCacheFetch(sector_block, data)) { + if (cdvdReadBlockOfSectors(sector_block, data)) + cdvdCacheUpdate(sector_block, data); + } + + if (src->GetMediaType() >= 0) { + u32 offset = 2048 * (sector - sector_block); + memcpy(buffer, data + offset, 2048); + return 0; + } + + u32 offset = 2352 * (sector - sector_block); + u8* bfr = data + offset; + + switch (mode) { + case CDVD_MODE_2048: + // Data location depends on CD mode + std::memcpy(buffer, (bfr[15] & 3) == 2 ? bfr + 24 : bfr + 16, 2048); + return 0; + case CDVD_MODE_2328: + memcpy(buffer, bfr + 24, 2328); + return 0; + case CDVD_MODE_2340: + memcpy(buffer, bfr + 12, 2340); + return 0; + default: + memcpy(buffer, bfr, 2352); + return 0; + } +} + +s32 cdvdGetMediaType() +{ + return src->GetMediaType(); +} + +s32 cdvdRefreshData() +{ + const char* diskTypeName = "Unknown"; + + //read TOC from device + cdvdParseTOC(); + + if ((etrack == 0) || (strack > etrack)) { + curDiskType = CDVD_TYPE_NODISC; + } + else { + s32 mt = cdvdGetMediaType(); + + if (mt < 0) + curDiskType = CDVD_TYPE_DETCTCD; + else if (mt == 0) + curDiskType = CDVD_TYPE_DETCTDVDS; + else + curDiskType = CDVD_TYPE_DETCTDVDD; + } + + curTrayStatus = CDVD_TRAY_CLOSE; + + switch (curDiskType) { + case CDVD_TYPE_DETCTDVDD: + diskTypeName = "Double-Layer DVD"; + break; + case CDVD_TYPE_DETCTDVDS: + diskTypeName = "Single-Layer DVD"; + break; + case CDVD_TYPE_DETCTCD: + diskTypeName = "CD-ROM"; + break; + case CDVD_TYPE_NODISC: + diskTypeName = "No Disc"; + break; + } + + printf(" * CDVD: Disk Type: %s\n", diskTypeName); + + cdvdCacheReset(); + + return 0; +} diff --git a/pcsx2/CDVD/CdRom.h b/pcsx2/CDVD/CdRom.h index 599a9b25b0..1ecd140731 100644 --- a/pcsx2/CDVD/CdRom.h +++ b/pcsx2/CDVD/CdRom.h @@ -17,7 +17,7 @@ #define __CDROM_H__ #include "IopCommon.h" -#include "PS2Edefs.h" +#include "CDVDaccess.h" // Not used. typedef struct { diff --git a/pcsx2/CDVD/Unix/DriveUtility.cpp b/pcsx2/CDVD/Unix/DriveUtility.cpp new file mode 100644 index 0000000000..8b2f4a792a --- /dev/null +++ b/pcsx2/CDVD/Unix/DriveUtility.cpp @@ -0,0 +1,76 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2020 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" +#include "../CDVDdiscReader.h" + +#include +#include +#include +#include +#include + +std::vector GetOpticalDriveList() +{ + udev* udev_context = udev_new(); + if (!udev_context) + return {}; + + std::vector drives; + udev_enumerate* enumerate = udev_enumerate_new(udev_context); + if (enumerate) { + udev_enumerate_add_match_subsystem(enumerate, "block"); + udev_enumerate_add_match_property(enumerate, "ID_CDROM_DVD", "1"); + udev_enumerate_scan_devices(enumerate); + udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); + + udev_list_entry* dev_list_entry; + udev_list_entry_foreach(dev_list_entry, devices) + { + const char* path = udev_list_entry_get_name(dev_list_entry); + udev_device* device = udev_device_new_from_syspath(udev_context, path); + const char* devnode = udev_device_get_devnode(device); + if (devnode) + drives.push_back(devnode); + udev_device_unref(device); + } + udev_enumerate_unref(enumerate); + } + udev_unref(udev_context); + + return drives; +} + +void GetValidDrive(std::string& drive) +{ + if (!drive.empty()) { + int fd = open(drive.c_str(), O_RDONLY | O_NONBLOCK); + if (fd != -1) { + if (ioctl(fd, CDROM_GET_CAPABILITY, 0) == -1) + drive.clear(); + close(fd); + } + else { + drive.clear(); + } + } + if (drive.empty()) { + auto drives = GetOpticalDriveList(); + if (!drives.empty()) + drive = drives.front(); + } + if (!drive.empty()) + printf(" * CDVD: Opening drive '%s'...\n", drive.c_str()); +} \ No newline at end of file diff --git a/pcsx2/CDVD/Unix/IOCtlSrc.cpp b/pcsx2/CDVD/Unix/IOCtlSrc.cpp new file mode 100644 index 0000000000..de7c5bac54 --- /dev/null +++ b/pcsx2/CDVD/Unix/IOCtlSrc.cpp @@ -0,0 +1,216 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2016 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" +#include "../CDVDdiscReader.h" + +#include +#include +#include +#include + +#include +#include +#include + +IOCtlSrc::IOCtlSrc(decltype(m_filename) filename) + : m_filename(filename) +{ + if (!Reopen()) + throw std::runtime_error(" * CDVD: Error opening source.\n"); +} + +IOCtlSrc::~IOCtlSrc() +{ + if (m_device != -1) { + SetSpindleSpeed(true); + close(m_device); + } +} + +bool IOCtlSrc::Reopen() +{ + if (m_device != -1) + close(m_device); + + // O_NONBLOCK allows a valid file descriptor to be returned even if the + // drive is empty. Probably does other things too. + m_device = open(m_filename.c_str(), O_RDONLY | O_NONBLOCK); + if (m_device == -1) + return false; + + // DVD detection MUST be first on Linux - The TOC ioctls work for both + // CDs and DVDs. + if (ReadDVDInfo() || ReadCDInfo()) + SetSpindleSpeed(false); + + return true; +} + +void IOCtlSrc::SetSpindleSpeed(bool restore_defaults) const +{ + // TODO: CD seems easy enough (CDROM_SELECT_SPEED ioctl), but I'm not sure + // about DVD. +} + +u32 IOCtlSrc::GetSectorCount() const +{ + return m_sectors; +} + +u32 IOCtlSrc::GetLayerBreakAddress() const +{ + return m_layer_break; +} + +s32 IOCtlSrc::GetMediaType() const +{ + return m_media_type; +} + +const std::vector& IOCtlSrc::ReadTOC() const +{ + return m_toc; +} + +bool IOCtlSrc::ReadSectors2048(u32 sector, u32 count, u8* buffer) const +{ + const ssize_t bytes_to_read = 2048 * count; + ssize_t bytes_read = pread(m_device, buffer, bytes_to_read, sector * 2048ULL); + if (bytes_read == bytes_to_read) + return true; + + if (bytes_read == -1) + fprintf(stderr, " * CDVD read sectors %u-%u failed: %s\n", + sector, sector + count - 1, strerror(errno)); + else + fprintf(stderr, " * CDVD read sectors %u-%u: %zd bytes read, %zd bytes expected\n", + sector, sector + count - 1, bytes_read, bytes_to_read); + return false; +} + +bool IOCtlSrc::ReadSectors2352(u32 sector, u32 count, u8* buffer) const +{ + union + { + cdrom_msf msf; + char buffer[CD_FRAMESIZE_RAW]; + } data; + + for (u32 n = 0; n < count; ++n) { + u32 lba = sector + n; + lba_to_msf(lba, &data.msf.cdmsf_min0, &data.msf.cdmsf_sec0, &data.msf.cdmsf_frame0); + if (ioctl(m_device, CDROMREADRAW, &data) == -1) { + fprintf(stderr, " * CDVD CDROMREADRAW sector %u failed: %s\n", + lba, strerror(errno)); + return false; + } + memcpy(buffer, data.buffer, CD_FRAMESIZE_RAW); + buffer += CD_FRAMESIZE_RAW; + } + + return true; +} + +bool IOCtlSrc::ReadDVDInfo() +{ + dvd_struct dvdrs; + dvdrs.type = DVD_STRUCT_PHYSICAL; + dvdrs.physical.layer_num = 0; + + int ret = ioctl(m_device, DVD_READ_STRUCT, &dvdrs); + if (ret == -1) + return false; + + u32 start_sector = dvdrs.physical.layer[0].start_sector; + u32 end_sector = dvdrs.physical.layer[0].end_sector; + + if (dvdrs.physical.layer[0].nlayers == 0) { + // Single layer + m_media_type = 0; + m_layer_break = 0; + m_sectors = end_sector - start_sector + 1; + } + else if (dvdrs.physical.layer[0].track_path == 0) { + // Dual layer, Parallel Track Path + dvdrs.physical.layer_num = 1; + ret = ioctl(m_device, DVD_READ_STRUCT, &dvdrs); + if (ret == -1) + return false; + u32 layer1_start_sector = dvdrs.physical.layer[1].start_sector; + u32 layer1_end_sector = dvdrs.physical.layer[1].end_sector; + + m_media_type = 1; + m_layer_break = end_sector - start_sector; + m_sectors = end_sector - start_sector + 1 + layer1_end_sector - layer1_start_sector + 1; + } + else { + // Dual layer, Opposite Track Path + u32 end_sector_layer0 = dvdrs.physical.layer[0].end_sector_l0; + m_media_type = 2; + m_layer_break = end_sector_layer0 - start_sector; + m_sectors = end_sector_layer0 - start_sector + 1 + end_sector - (~end_sector_layer0 & 0xFFFFFFU) + 1; + } + + return true; +} + +bool IOCtlSrc::ReadCDInfo() +{ + cdrom_tochdr header; + + if (ioctl(m_device, CDROMREADTOCHDR, &header) == -1) + return false; + + cdrom_tocentry entry{}; + entry.cdte_format = CDROM_LBA; + + m_toc.clear(); + for (u8 n = header.cdth_trk0; n <= header.cdth_trk1; ++n) { + entry.cdte_track = n; + if (ioctl(m_device, CDROMREADTOCENTRY, &entry) != -1) + m_toc.push_back({ static_cast(entry.cdte_addr.lba), entry.cdte_track, + entry.cdte_adr, entry.cdte_ctrl }); + } + + // TODO: Do I need a fallback if this doesn't work? + entry.cdte_track = 0xAA; + if (ioctl(m_device, CDROMREADTOCENTRY, &entry) == -1) + return false; + + m_sectors = entry.cdte_addr.lba; + m_media_type = -1; + + return true; +} + +bool IOCtlSrc::DiscReady() +{ + if (m_device == -1) + return false; + + // CDSL_CURRENT must be used - 0 will cause the drive tray to close. + if (ioctl(m_device, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK) { + if (!m_sectors) + Reopen(); + } + else { + m_sectors = 0; + m_layer_break = 0; + m_media_type = 0; + } + + return !!m_sectors; +} diff --git a/pcsx2/CDVD/Windows/DriveUtility.cpp b/pcsx2/CDVD/Windows/DriveUtility.cpp new file mode 100644 index 0000000000..3ff853450a --- /dev/null +++ b/pcsx2/CDVD/Windows/DriveUtility.cpp @@ -0,0 +1,64 @@ +//Copyright (C) 2020 PCSX2 Dev Team +//Copyright (c) David Quintana +// +//This library is free software; you can redistribute it and/or +//modify it under the terms of the GNU Lesser General Public +//License as published by the Free Software Foundation; either +//version 3.0 of the License, or (at your option) any later version. +// +//This library is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +//Lesser General Public License for more details. +// +//You should have received a copy of the GNU Lesser General Public +//License along with this library; if not, write to the Free Software +//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +// + +#include "PrecompiledHeader.h" +#include "../CDVDdiscReader.h" + +std::vector GetOpticalDriveList() +{ + DWORD size = GetLogicalDriveStrings(0, nullptr); + std::vector drive_strings(size); + if (GetLogicalDriveStrings(size, drive_strings.data()) != size - 1) + return {}; + + std::vector drives; + for (auto p = drive_strings.data(); *p; ++p) { + if (GetDriveType(p) == DRIVE_CDROM) + drives.push_back(p); + while (*p) + ++p; + } + return drives; +} + +void GetValidDrive(std::wstring& drive) +{ + if (drive.empty() || GetDriveType(drive.c_str()) != DRIVE_CDROM) { + auto drives = GetOpticalDriveList(); + if (drives.empty()) + { + drive = {}; + } + else + { + drive = drives.front(); + } + } + else + { + int size = WideCharToMultiByte(CP_UTF8, 0, drive.c_str(), -1, nullptr, 0, nullptr, nullptr); + std::vector converted_string(size); + WideCharToMultiByte(CP_UTF8, 0, drive.c_str(), -1, converted_string.data(), converted_string.size(), nullptr, nullptr); + printf(" * CDVD: Opening drive '%s'...\n", converted_string.data()); + + // The drive string has the form "X:\", but to open the drive, the string + // has to be in the form "\\.\X:" + drive.pop_back(); + drive.insert(0, L"\\\\.\\"); + } +} \ No newline at end of file diff --git a/pcsx2/CDVD/Windows/IOCtlSrc.cpp b/pcsx2/CDVD/Windows/IOCtlSrc.cpp new file mode 100644 index 0000000000..702101b205 --- /dev/null +++ b/pcsx2/CDVD/Windows/IOCtlSrc.cpp @@ -0,0 +1,303 @@ +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2016 PCSX2 Dev Team + * Copyright (C) 2002-2014 David Quintana [gigaherz] + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" +#include "../CDVDdiscReader.h" + +#include +#include +#include + // "typedef ignored" warning will disappear once we move to the Windows 10 SDK. +#pragma warning(push) +#pragma warning(disable : 4091) +#include +#pragma warning(pop) + +#include +#include +#include + +IOCtlSrc::IOCtlSrc(decltype(m_filename) filename) + : m_filename(filename) +{ + if (!Reopen()) + throw std::runtime_error(" * CDVD: Error opening source.\n"); +} + +IOCtlSrc::~IOCtlSrc() +{ + if (m_device != INVALID_HANDLE_VALUE) { + SetSpindleSpeed(true); + CloseHandle(m_device); + } +} + +// 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) + CloseHandle(m_device); + + // SPTI only works if the device is opened with GENERIC_WRITE access. + m_device = CreateFile(m_filename.c_str(), GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, nullptr); + if (m_device == INVALID_HANDLE_VALUE) + return false; + + DWORD unused; + // Required to read from layer 1 of Dual layer DVDs + DeviceIoControl(m_device, FSCTL_ALLOW_EXTENDED_DASD_IO, nullptr, 0, nullptr, + 0, &unused, nullptr); + + if (ReadDVDInfo() || ReadCDInfo()) + SetSpindleSpeed(false); + + return true; +} + +void IOCtlSrc::SetSpindleSpeed(bool restore_defaults) const +{ + // IOCTL_CDROM_SET_SPEED issues a SET CD SPEED command. So 0xFFFF should be + // equivalent to "optimal performance". + // 1x DVD-ROM and CD-ROM speeds are respectively 1385 KB/s and 150KB/s. + // The PS2 can do 4x DVD-ROM and 24x CD-ROM speeds (5540KB/s and 3600KB/s). + // TODO: What speed? Performance seems smoother with a lower speed (less + // time required to get up to speed). + const USHORT speed = restore_defaults ? 0xFFFF : GetMediaType() >= 0 ? 5540 : 3600; + CDROM_SET_SPEED s{ CdromSetSpeed, speed, speed, CdromDefaultRotation }; + + DWORD unused; + if (DeviceIoControl(m_device, IOCTL_CDROM_SET_SPEED, &s, sizeof(s), + nullptr, 0, &unused, nullptr)) { + if (!restore_defaults) + printf(" * CDVD: setSpindleSpeed success (%uKB/s)\n", speed); + } + else { + printf(" * CDVD: setSpindleSpeed failed!\n"); + } +} + +u32 IOCtlSrc::GetSectorCount() const +{ + return m_sectors; +} + +u32 IOCtlSrc::GetLayerBreakAddress() const +{ + return m_layer_break; +} + +s32 IOCtlSrc::GetMediaType() const +{ + return m_media_type; +} + +const std::vector& IOCtlSrc::ReadTOC() const +{ + return m_toc; +} + +bool IOCtlSrc::ReadSectors2048(u32 sector, u32 count, u8* buffer) const +{ + std::lock_guard guard(m_lock); + LARGE_INTEGER offset; + offset.QuadPart = sector * 2048ULL; + + if (!SetFilePointerEx(m_device, offset, nullptr, FILE_BEGIN)) { + fprintf(stderr, " * CDVD SetFilePointerEx failed: sector %u: error %u\n", + sector, GetLastError()); + return false; + } + + const DWORD bytes_to_read = 2048 * count; + DWORD bytes_read; + if (ReadFile(m_device, buffer, bytes_to_read, &bytes_read, nullptr)) { + if (bytes_read == bytes_to_read) + return true; + fprintf(stderr, " * CDVD ReadFile: sectors %u-%u: %u bytes read, %u bytes expected\n", + sector, sector + count - 1, bytes_read, bytes_to_read); + } + else { + fprintf(stderr, " * CDVD ReadFile failed: sectors %u-%u: error %u\n", + sector, sector + count - 1, GetLastError()); + } + + return false; +} + +bool IOCtlSrc::ReadSectors2352(u32 sector, u32 count, u8* buffer) const +{ + struct sptdinfo + { + SCSI_PASS_THROUGH_DIRECT info; + char sense_buffer[20]; + } sptd{}; + + // READ CD command + sptd.info.Cdb[0] = 0xBE; + // Don't care about sector type. + sptd.info.Cdb[1] = 0; + // Number of sectors to read + sptd.info.Cdb[6] = 0; + sptd.info.Cdb[7] = 0; + sptd.info.Cdb[8] = 1; + // Sync + all headers + user data + EDC/ECC. Excludes C2 + subchannel + sptd.info.Cdb[9] = 0xF8; + sptd.info.Cdb[10] = 0; + sptd.info.Cdb[11] = 0; + + sptd.info.CdbLength = 12; + sptd.info.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); + sptd.info.DataIn = SCSI_IOCTL_DATA_IN; + sptd.info.SenseInfoOffset = offsetof(sptdinfo, sense_buffer); + sptd.info.TimeOutValue = 5; + + // Read sectors one by one to avoid reading data from 2 tracks of different + // types in the same read (which will fail). + for (u32 n = 0; n < count; ++n) { + u32 current_sector = sector + n; + sptd.info.Cdb[2] = (current_sector >> 24) & 0xFF; + sptd.info.Cdb[3] = (current_sector >> 16) & 0xFF; + sptd.info.Cdb[4] = (current_sector >> 8) & 0xFF; + sptd.info.Cdb[5] = current_sector & 0xFF; + sptd.info.DataTransferLength = 2352; + sptd.info.DataBuffer = buffer + 2352 * n; + sptd.info.SenseInfoLength = sizeof(sptd.sense_buffer); + + DWORD unused; + if (DeviceIoControl(m_device, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, + sizeof(sptd), &sptd, sizeof(sptd), &unused, nullptr)) { + if (sptd.info.DataTransferLength == 2352) + continue; + } + printf(" * CDVD: SPTI failed reading sector %u; SENSE %u -", current_sector, sptd.info.SenseInfoLength); + for (const auto& c : sptd.sense_buffer) + printf(" %02X", c); + putchar('\n'); + return false; + } + + return true; +} + +bool IOCtlSrc::ReadDVDInfo() +{ + DWORD unused; + // 4 bytes header + 18 bytes layer descriptor - Technically you only need + // to read 17 bytes of the layer descriptor since bytes 17-2047 is for + // media specific information. However, Windows requires you to read at + // least 18 bytes of the layer descriptor or else the ioctl will fail. The + // media specific information seems to be empty, so there's no point reading + // any more than that. + std::array buffer; + DVD_READ_STRUCTURE dvdrs{ {0}, DvdPhysicalDescriptor, 0, 0 }; + + if (!DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), + buffer.data(), buffer.size(), &unused, nullptr)) + return false; + + auto& layer = *reinterpret_cast( + reinterpret_cast(buffer.data())->Data); + + u32 start_sector = _byteswap_ulong(layer.StartingDataSector); + u32 end_sector = _byteswap_ulong(layer.EndDataSector); + + if (layer.NumberOfLayers == 0) { + // Single layer + m_media_type = 0; + m_layer_break = 0; + m_sectors = end_sector - start_sector + 1; + } + else if (layer.TrackPath == 0) { + // Dual layer, Parallel Track Path + dvdrs.LayerNumber = 1; + if (!DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), + buffer.data(), buffer.size(), &unused, nullptr)) + return false; + u32 layer1_start_sector = _byteswap_ulong(layer.StartingDataSector); + u32 layer1_end_sector = _byteswap_ulong(layer.EndDataSector); + + m_media_type = 1; + m_layer_break = end_sector - start_sector; + m_sectors = end_sector - start_sector + 1 + layer1_end_sector - layer1_start_sector + 1; + } + else { + // Dual layer, Opposite Track Path + u32 end_sector_layer0 = _byteswap_ulong(layer.EndLayerZeroSector); + m_media_type = 2; + m_layer_break = end_sector_layer0 - start_sector; + m_sectors = end_sector_layer0 - start_sector + 1 + end_sector - (~end_sector_layer0 & 0xFFFFFFU) + 1; + } + + return true; +} + +bool IOCtlSrc::ReadCDInfo() +{ + DWORD unused; + CDROM_READ_TOC_EX toc_ex{}; + toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC; + toc_ex.Msf = 0; + toc_ex.SessionTrack = 1; + + CDROM_TOC toc; + if (!DeviceIoControl(m_device, IOCTL_CDROM_READ_TOC_EX, &toc_ex, + sizeof(toc_ex), &toc, sizeof(toc), &unused, nullptr)) + return false; + + m_toc.clear(); + size_t track_count = ((toc.Length[0] << 8) + toc.Length[1] - 2) / sizeof(TRACK_DATA); + for (size_t n = 0; n < track_count; ++n) { + TRACK_DATA& track = toc.TrackData[n]; + // Exclude the lead-out track descriptor. + if (track.TrackNumber == 0xAA) + continue; + u32 lba = (track.Address[1] << 16) + (track.Address[2] << 8) + track.Address[3]; + m_toc.push_back({ lba, track.TrackNumber, track.Adr, track.Control }); + } + + GET_LENGTH_INFORMATION info; + if (!DeviceIoControl(m_device, IOCTL_DISK_GET_LENGTH_INFO, nullptr, 0, &info, + sizeof(info), &unused, nullptr)) + return false; + + m_sectors = static_cast(info.Length.QuadPart / 2048); + m_media_type = -1; + + return true; +} + +bool IOCtlSrc::DiscReady() +{ + if (m_device == INVALID_HANDLE_VALUE) + return false; + + DWORD unused; + if (DeviceIoControl(m_device, IOCTL_STORAGE_CHECK_VERIFY, nullptr, 0, + nullptr, 0, &unused, nullptr)) { + if (!m_sectors) + Reopen(); + } + else { + m_sectors = 0; + m_layer_break = 0; + m_media_type = 0; + } + + return !!m_sectors; +} diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index de52eaaa70..1c43cc9e91 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -183,6 +183,7 @@ set(pcsx2CDVDSources CDVD/CDVD.cpp CDVD/CDVDdiscReader.cpp CDVD/CDVDisoReader.cpp + CDVD/CDVDdiscThread.cpp CDVD/InputIsoFile.cpp CDVD/OutputIsoFile.cpp CDVD/ChunksCache.cpp @@ -402,6 +403,8 @@ set(pcsx2IPUHeaders # Linux sources set(pcsx2LinuxSources + CDVD/Unix/DriveUtility.cpp + CDVD/Unix/IOCtlSrc.cpp gui/CpuUsageProviderLnx.cpp Linux/LnxConsolePipe.cpp Linux/LnxKeyCodes.cpp @@ -409,6 +412,8 @@ set(pcsx2LinuxSources ) set(pcsx2OSXSources + CDVD/Unix/DriveUtility.cpp + CDVD/Unix/IOCtlSrc.cpp gui/CpuUsageProviderLnx.cpp Linux/LnxConsolePipe.cpp # Linux/LnxKeyCodes.cpp @@ -515,6 +520,8 @@ set(pcsx2ZipToolsHeaders # Windows sources set(pcsx2WindowsSources + CDVD/Windows/DriveUtility.cpp + CDVD/Windows/IOCtlSrc.cpp gui/CpuUsageProviderMSW.cpp windows/FlatFileReaderWindows.cpp windows/Optimus.cpp @@ -631,7 +638,12 @@ set(Common if(Linux) set(Platform ${pcsx2LinuxSources} - ${pcsx2LinuxHeaders}) + ${pcsx2LinuxHeaders} + ) + + set(Platform_Libs + ${LIBUDEV_LIBRARIES} + ) endif() # Windows @@ -646,6 +658,10 @@ if(APPLE) set(Platform ${pcsx2OSXSources} ${pcsx2LinuxHeaders}) + + set(Platform_Libs + ${LIBUDEV_LIBRARIES} + ) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") @@ -667,6 +683,7 @@ set(pcsx2FinalLibs ${ZLIB_LIBRARIES} ${AIO_LIBRARIES} ${GCOV_LIBRARIES} + ${Platform_Libs} ) if(BUILTIN_GS) diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 41572ffcbc..1c3cddee9d 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -24,7 +24,6 @@ enum PluginsEnum_t PluginId_GS = 0, PluginId_PAD, PluginId_SPU2, - PluginId_CDVD, PluginId_USB, PluginId_FW, PluginId_DEV9, diff --git a/pcsx2/PluginManager.cpp b/pcsx2/PluginManager.cpp index b2c6314a9c..763ab68c12 100644 --- a/pcsx2/PluginManager.cpp +++ b/pcsx2/PluginManager.cpp @@ -22,7 +22,6 @@ #include "GS.h" #include "Gif.h" -#include "CDVD/CDVDisoReader.h" #include "Utilities/pxStreams.h" @@ -83,7 +82,6 @@ const PluginInfo tbl_PluginInfo[] = { "GS", PluginId_GS, PS2E_LT_GS, PS2E_GS_VERSION }, { "PAD", PluginId_PAD, PS2E_LT_PAD, PS2E_PAD_VERSION }, { "SPU2", PluginId_SPU2, PS2E_LT_SPU2, PS2E_SPU2_VERSION }, - { "CDVD", PluginId_CDVD, PS2E_LT_CDVD, PS2E_CDVD_VERSION }, { "USB", PluginId_USB, PS2E_LT_USB, PS2E_USB_VERSION }, { "FW", PluginId_FW, PS2E_LT_FW, PS2E_FW_VERSION }, { "DEV9", PluginId_DEV9, PS2E_LT_DEV9, PS2E_DEV9_VERSION }, @@ -447,118 +445,6 @@ static const LegacyApi_OptMethod s_MethMessOpt_PAD[] = { NULL }, }; -// ---------------------------------------------------------------------------- -// CDVD Mess! -// ---------------------------------------------------------------------------- -void CALLBACK CDVD_newDiskCB(void (*callback)()) {} - -extern int lastReadSize; -extern u32 lastLSN; -static s32 CALLBACK CDVD_getBuffer2(u8* buffer) -{ - // TEMP: until I fix all the plugins to use this function style - u8* pb = CDVD->getBuffer(); - if(pb == NULL) return -2; - - memcpy( buffer, pb, lastReadSize ); - return 0; -} - -static s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode) -{ - if(CDVD->readTrack(lsn,mode) < 0) - return -1; - - // TEMP: until all the plugins use the new CDVDgetBuffer style - switch (mode) - { - case CDVD_MODE_2352: - lastReadSize = 2352; - break; - case CDVD_MODE_2340: - lastReadSize = 2340; - break; - case CDVD_MODE_2328: - lastReadSize = 2328; - break; - case CDVD_MODE_2048: - lastReadSize = 2048; - break; - } - - lastLSN = lsn; - return CDVD->getBuffer2(buffer); -} - -static s32 CALLBACK CDVD_getDualInfo(s32* dualType, u32* layer1Start) -{ - u8 toc[2064]; - - // if error getting toc, settle for single layer disc ;) - if(CDVD->getTOC(toc)) - return 0; - - if(toc[14] & 0x60) - { - if(toc[14] & 0x10) - { - // otp dvd - *dualType = 2; - *layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1; - } - else - { - // ptp dvd - *dualType = 1; - *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; - } - } - else - { - // single layer dvd - *dualType = 0; - *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1; - } - - return 1; -} - -CDVD_API CDVDapi_Plugin = -{ - // All of these are filled by the plugin manager - NULL -}; - -CDVD_API* CDVD = NULL; - -static const LegacyApi_ReqMethod s_MethMessReq_CDVD[] = -{ - { "CDVDopen", (vMeth**)&CDVDapi_Plugin.open, NULL }, - { "CDVDclose", (vMeth**)&CDVDapi_Plugin.close, NULL }, - { "CDVDreadTrack", (vMeth**)&CDVDapi_Plugin.readTrack, NULL }, - { "CDVDgetBuffer", (vMeth**)&CDVDapi_Plugin.getBuffer, NULL }, - { "CDVDreadSubQ", (vMeth**)&CDVDapi_Plugin.readSubQ, NULL }, - { "CDVDgetTN", (vMeth**)&CDVDapi_Plugin.getTN, NULL }, - { "CDVDgetTD", (vMeth**)&CDVDapi_Plugin.getTD, NULL }, - { "CDVDgetTOC", (vMeth**)&CDVDapi_Plugin.getTOC, NULL }, - { "CDVDgetDiskType", (vMeth**)&CDVDapi_Plugin.getDiskType, NULL }, - { "CDVDgetTrayStatus",(vMeth**)&CDVDapi_Plugin.getTrayStatus, NULL }, - { "CDVDctrlTrayOpen", (vMeth**)&CDVDapi_Plugin.ctrlTrayOpen, NULL }, - { "CDVDctrlTrayClose",(vMeth**)&CDVDapi_Plugin.ctrlTrayClose, NULL }, - { "CDVDnewDiskCB", (vMeth**)&CDVDapi_Plugin.newDiskCB, (vMeth*)CDVD_newDiskCB }, - - { "CDVDreadSector", (vMeth**)&CDVDapi_Plugin.readSector, (vMeth*)CDVD_readSector }, - { "CDVDgetBuffer2", (vMeth**)&CDVDapi_Plugin.getBuffer2, (vMeth*)CDVD_getBuffer2 }, - { "CDVDgetDualInfo", (vMeth**)&CDVDapi_Plugin.getDualInfo, (vMeth*)CDVD_getDualInfo }, - - { NULL } -}; - -static const LegacyApi_OptMethod s_MethMessOpt_CDVD[] = -{ - { NULL } -}; - // ---------------------------------------------------------------------------- // SPU2 Mess! // ---------------------------------------------------------------------------- @@ -671,7 +557,6 @@ static const LegacyApi_ReqMethod* const s_MethMessReq[] = s_MethMessReq_GS, s_MethMessReq_PAD, s_MethMessReq_SPU2, - s_MethMessReq_CDVD, s_MethMessReq_USB, s_MethMessReq_FW, s_MethMessReq_DEV9 @@ -682,7 +567,6 @@ static const LegacyApi_OptMethod* const s_MethMessOpt[] = s_MethMessOpt_GS, s_MethMessOpt_PAD, s_MethMessOpt_SPU2, - s_MethMessOpt_CDVD, s_MethMessOpt_USB, s_MethMessOpt_FW, s_MethMessOpt_DEV9 @@ -851,9 +735,6 @@ void* StaticLibrary::GetSymbol(const wxString &name) #ifdef BUILTIN_SPU2_PLUGIN RETURN_COMMON_SYMBOL(SPU2); #endif -#ifdef BUILTIN_CDVD_PLUGIN - RETURN_COMMON_SYMBOL(CDVD); -#endif #ifdef BUILTIN_DEV9_PLUGIN RETURN_COMMON_SYMBOL(DEV9); #endif @@ -921,9 +802,6 @@ SysCorePlugins::PluginStatus_t::PluginStatus_t( PluginsEnum_t _pid, const wxStri #ifdef BUILTIN_SPU2_PLUGIN case PluginId_SPU2: #endif -#ifdef BUILTIN_CDVD_PLUGIN - case PluginId_CDVD: -#endif #ifdef BUILTIN_DEV9_PLUGIN case PluginId_DEV9: #endif @@ -1105,8 +983,6 @@ void SysCorePlugins::Load( const wxString (&folders)[PluginId_Count] ) } while( ++pi, pi->shortname != NULL ); indent.LeaveScope(); - CDVDapi_Plugin.newDiskCB( cdvdNewDiskCB ); - // Hack for PAD's stupid parameter passed on Init PADinit = (_PADinit)m_info[PluginId_PAD]->CommonBindings.Init; m_info[PluginId_PAD]->CommonBindings.Init = _hack_PADinit; @@ -1190,11 +1066,6 @@ extern void spu2DMA4Irq(); extern void spu2DMA7Irq(); extern void spu2Irq(); -bool SysCorePlugins::OpenPlugin_CDVD() -{ - return DoCDVDopen(); -} - bool SysCorePlugins::OpenPlugin_GS() { GetMTGS().Resume(); @@ -1271,7 +1142,6 @@ void SysCorePlugins::Open( PluginsEnum_t pid ) { case PluginId_GS: result = OpenPlugin_GS(); break; case PluginId_PAD: result = OpenPlugin_PAD(); break; - case PluginId_CDVD: result = OpenPlugin_CDVD(); break; case PluginId_SPU2: result = OpenPlugin_SPU2(); break; case PluginId_USB: result = OpenPlugin_USB(); break; case PluginId_FW: result = OpenPlugin_FW(); break; @@ -1342,11 +1212,6 @@ void SysCorePlugins::ClosePlugin_GS() } } -void SysCorePlugins::ClosePlugin_CDVD() -{ - DoCDVDclose(); -} - void SysCorePlugins::ClosePlugin_PAD() { _generalclose( PluginId_PAD ); @@ -1391,7 +1256,6 @@ void SysCorePlugins::Close( PluginsEnum_t pid ) { case PluginId_GS: ClosePlugin_GS(); break; case PluginId_PAD: ClosePlugin_PAD(); break; - case PluginId_CDVD: ClosePlugin_CDVD(); break; case PluginId_SPU2: ClosePlugin_SPU2(); break; case PluginId_USB: ClosePlugin_USB(); break; case PluginId_FW: ClosePlugin_FW(); break; diff --git a/pcsx2/Plugins.h b/pcsx2/Plugins.h index ce7e1cb273..ab5b1dd775 100644 --- a/pcsx2/Plugins.h +++ b/pcsx2/Plugins.h @@ -189,7 +189,7 @@ typedef void CALLBACK FnType_SetDir( const char* dir ); // Important: Contents of this structure must match the order of the contents of the // s_MethMessCommon[] array defined in Plugins.cpp. // -// Note: Open is excluded from this list because the GS and CDVD have custom signatures >_< +// Note: Open is excluded from this list because the GS has a custom signatures >_< // struct LegacyPluginAPI_Common { @@ -401,7 +401,6 @@ protected: virtual bool NeedsUnload() const; virtual bool OpenPlugin_GS(); - virtual bool OpenPlugin_CDVD(); virtual bool OpenPlugin_PAD(); virtual bool OpenPlugin_SPU2(); virtual bool OpenPlugin_DEV9(); @@ -412,7 +411,6 @@ protected: void _generalclose( PluginsEnum_t pid ); virtual void ClosePlugin_GS(); - virtual void ClosePlugin_CDVD(); virtual void ClosePlugin_PAD(); virtual void ClosePlugin_SPU2(); virtual void ClosePlugin_DEV9(); diff --git a/pcsx2/System.h b/pcsx2/System.h index eed80618a1..04abe97349 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -19,7 +19,7 @@ #include "Utilities/SafeArray.h" #include "Utilities/Threading.h" // to use threading stuff, include the Threading namespace in your file. -#include "CDVD/CDVDaccess.h" +#include "Plugins.h" #include "vtlb.h" diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index b04b0bc59d..8b36beac60 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -279,11 +279,13 @@ void SysCoreThread::ExecuteTaskInThread() void SysCoreThread::OnSuspendInThread() { GetCorePlugins().Close(); + DoCDVDclose(); } void SysCoreThread::OnResumeInThread( bool isSuspended ) { GetCorePlugins().Open(); + DoCDVDopen(); } diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index bfdc407c7d..89cedc46cc 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -100,7 +100,6 @@ enum MenuIdentifiers MenuId_Cdvd_Source, MenuId_DriveSelector, MenuId_Src_Iso, - MenuId_Src_Plugin, MenuId_Src_Disc, MenuId_Src_NoDisc, MenuId_Boot_Iso, // Opens submenu with Iso browser, and recent isos. @@ -804,6 +803,7 @@ extern void ShutdownPlugins(); extern bool SysHasValidState(); extern void SysUpdateIsoSrcFile( const wxString& newIsoFile ); +extern void SysUpdateDiscSrcDrive( const wxString& newDiscDrive ); extern void SysStatus( const wxString& text ); extern bool HasMainFrame(); diff --git a/pcsx2/gui/AppConfig.cpp b/pcsx2/gui/AppConfig.cpp index 2f497f4356..2076e0dc70 100644 --- a/pcsx2/gui/AppConfig.cpp +++ b/pcsx2/gui/AppConfig.cpp @@ -641,6 +641,7 @@ void AppConfig::LoadSaveRootItems( IniInterface& ini ) ini.Entry( L"CurrentIso", res, res, ini.IsLoading() || IsPortable() ); CurrentIso = res.GetFullPath(); + IniEntry( CurrentDisc ); IniEntry( CurrentBlockdump ); IniEntry( CurrentELF ); IniEntry( CurrentIRX ); @@ -725,8 +726,9 @@ AppConfig::FolderOptions::FolderOptions() , Cheats ( PathDefs::GetCheats() ) , CheatsWS ( PathDefs::GetCheatsWS() ) - , RunIso( PathDefs::GetDocuments() ) // raw default is always the Documents folder. - , RunELF( PathDefs::GetDocuments() ) // raw default is always the Documents folder. + , RunIso ( PathDefs::GetDocuments() ) // raw default is always the Documents folder. + , RunELF ( PathDefs::GetDocuments() ) // raw default is always the Documents folder. + , RunDisc ( PathDefs::GetDocuments() ) { bitset = 0xffffffff; } @@ -766,6 +768,7 @@ void AppConfig::FolderOptions::LoadSave( IniInterface& ini ) IniEntryDirFile( RunIso, rel ); IniEntryDirFile( RunELF, rel ); + IniEntryDirFile( RunDisc, rel ); if( ini.IsLoading() ) { @@ -1254,7 +1257,14 @@ static void LoadUiSettings() g_Conf->LoadSave( loader ); if( !wxFile::Exists( g_Conf->CurrentIso ) ) + { g_Conf->CurrentIso.clear(); + } + + if( !wxDirExists( g_Conf->CurrentDisc ) ) + { + g_Conf->CurrentDisc.clear(); + } sApp.DispatchUiSettingsEvent( loader ); } @@ -1287,9 +1297,17 @@ void AppLoadSettings() static void SaveUiSettings() { if( !wxFile::Exists( g_Conf->CurrentIso ) ) + { g_Conf->CurrentIso.clear(); + } + + if( !wxDirExists( g_Conf->CurrentDisc ) ) + { + g_Conf->CurrentDisc.clear(); + } sApp.GetRecentIsoManager().Add( g_Conf->CurrentIso ); + //TODO_CDVD Should this be done for CurrentDisc? AppIniSaver saver; g_Conf->LoadSave( saver ); diff --git a/pcsx2/gui/AppConfig.h b/pcsx2/gui/AppConfig.h index affe1678eb..32024f7fd8 100644 --- a/pcsx2/gui/AppConfig.h +++ b/pcsx2/gui/AppConfig.h @@ -166,6 +166,7 @@ public: wxDirName RunIso; // last used location for Iso loading. wxDirName RunELF; // last used location for ELF loading. + wxDirName RunDisc; // last used location for Disc loading. FolderOptions(); void LoadSave( IniInterface& conf ); @@ -324,6 +325,7 @@ public: bool AskOnBoot; wxString CurrentIso; + wxString CurrentDisc; wxString CurrentBlockdump; wxString CurrentELF; wxString CurrentIRX; diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index 260abb4cbd..45faeb86b7 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -178,7 +178,7 @@ void AppCoreThread::ChangeCdvdSource() // Fast change of the CDVD source only -- a Pause will suffice. ScopedCoreThreadPause paused_core; - GetCorePlugins().Close( PluginId_CDVD ); + //TODO_CDVD close CDVDdiscReader here? CDVDsys_ChangeSource( cdvdsrc ); paused_core.AllowResume(); @@ -541,7 +541,7 @@ void AppCoreThread::OnResumeInThread( bool isSuspended ) { if( m_resetCdvd ) { - GetCorePlugins().Close( PluginId_CDVD ); + //TODO_CDVD close CDVDdiscReader here? CDVDsys_ChangeSource( g_Conf->CdvdSource ); cdvdCtrlTrayOpen(); m_resetCdvd = false; diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index f38a5212de..9efdbc5bd2 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -229,8 +229,7 @@ void Pcsx2App::OnInitCmdLine( wxCmdLineParser& parser ) parser.AddOption( wxEmptyString,L"elf", _("executes an ELF image"), wxCMD_LINE_VAL_STRING ); parser.AddOption( wxEmptyString,L"irx", _("executes an IRX image"), wxCMD_LINE_VAL_STRING ); parser.AddSwitch( wxEmptyString,L"nodisc", _("boots an empty DVD tray; use to enter the PS2 system menu") ); - //TODO_CDVD update string - parser.AddSwitch( wxEmptyString,L"usecd", _("boots from the CDVD plugin (overrides IsoFile parameter)") ); + parser.AddSwitch( wxEmptyString,L"usecd", _("boots from the disc drive (overrides IsoFile parameter)") ); parser.AddSwitch( wxEmptyString,L"nohacks", _("disables all speedhacks") ); parser.AddOption( wxEmptyString,L"gamefixes", _("use the specified comma or pipe-delimited list of gamefixes.") + fixlist, wxCMD_LINE_VAL_STRING ); @@ -364,8 +363,7 @@ bool Pcsx2App::OnCmdLineParsed( wxCmdLineParser& parser ) if( parser.Found(L"usecd") ) { - //TODO_CDVD change plugin to disc - Startup.CdvdSource = CDVD_SourceType::Plugin; + Startup.CdvdSource = CDVD_SourceType::Disc; Startup.SysAutoRun = true; } diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index ee7f6c1b5a..fe7f3e1709 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -1180,8 +1180,13 @@ void SysStatus( const wxString& text ) void SysUpdateIsoSrcFile( const wxString& newIsoFile ) { g_Conf->CurrentIso = newIsoFile; - sMainFrame.UpdateIsoSrcSelection(); - sMainFrame.UpdateStatusBar(); + sMainFrame.UpdateCdvdSrcSelection(); +} + +void SysUpdateDiscSrcDrive( const wxString& newDiscDrive ) +{ + g_Conf->CurrentDisc = newDiscDrive; + sMainFrame.UpdateCdvdSrcSelection(); } bool HasMainFrame() diff --git a/pcsx2/gui/Dialogs/DriveSelectorDialog.cpp b/pcsx2/gui/Dialogs/DriveSelectorDialog.cpp index 1cdaa62a84..55a475434a 100644 --- a/pcsx2/gui/Dialogs/DriveSelectorDialog.cpp +++ b/pcsx2/gui/Dialogs/DriveSelectorDialog.cpp @@ -15,35 +15,31 @@ #include "PrecompiledHeader.h" #include "Dialogs/ModalPopups.h" +#include "../CDVD/CDVDdiscReader.h" -static wxArrayString GetOpticalDriveList() -{ - DWORD size = GetLogicalDriveStrings(0, nullptr); - std::vector drive_strings(size); - if (GetLogicalDriveStrings(size, drive_strings.data()) != size - 1) - return {}; - - wxArrayString drives; - for (auto p = drive_strings.data(); *p; ++p) { - if (GetDriveType(p) == DRIVE_CDROM) - drives.Add(p); - while (*p) - ++p; - } - return drives; -} - -Dialogs::DriveSelectorDialog::DriveSelectorDialog(wxWindow* parent) +Dialogs::DriveSelectorDialog::DriveSelectorDialog(wxWindow* parent, wxString curDrive) : wxDialog(parent, wxID_ANY, "") { wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); wxStaticBoxSizer* staticSizer = new wxStaticBoxSizer(wxVERTICAL, this, "Source drive..."); wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL); - wxArrayString driveList = GetOpticalDriveList(); + auto drives = GetOpticalDriveList(); + wxArrayString driveList; + + for (auto i : drives) + { + driveList.Add(i); + } choiceDrive = new wxChoice(this, wxID_ANY, wxDefaultPosition, { 240, 40 }, driveList); + int driveIndex = choiceDrive->FindString(curDrive); + if (driveIndex != wxNOT_FOUND) + { + choiceDrive->SetSelection(driveIndex); + } + wxButton* btnOk = new wxButton(this, wxID_OK); wxButton* btnCancel = new wxButton(this, wxID_CANCEL); diff --git a/pcsx2/gui/Dialogs/ModalPopups.h b/pcsx2/gui/Dialogs/ModalPopups.h index d95b20c8af..d71f3ffea8 100644 --- a/pcsx2/gui/Dialogs/ModalPopups.h +++ b/pcsx2/gui/Dialogs/ModalPopups.h @@ -105,7 +105,7 @@ namespace Dialogs class DriveSelectorDialog : public wxDialog { public: - DriveSelectorDialog( wxWindow* parent ); + DriveSelectorDialog( wxWindow* parent, wxString curDrive ); wxString GetSelectedDrive(); private: wxChoice* choiceDrive; diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index 66eb67b4e9..e8de16d41e 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -229,7 +229,6 @@ void MainEmuFrame::ConnectMenus() Bind(wxEVT_MENU, &MainEmuFrame::Menu_IsoClear_Click, this, MenuId_IsoClear); Bind(wxEVT_MENU, &MainEmuFrame::Menu_CdvdSource_Click, this, MenuId_Src_Iso); Bind(wxEVT_MENU, &MainEmuFrame::Menu_DiscBrowse_Click, this, MenuId_DriveSelector); - Bind(wxEVT_MENU, &MainEmuFrame::Menu_CdvdSource_Click, this, MenuId_Src_Disc); Bind(wxEVT_MENU, &MainEmuFrame::Menu_DriveSelector_Click, this, MenuId_DriveSelector); Bind(wxEVT_MENU, &MainEmuFrame::Menu_CdvdSource_Click, this, MenuId_Src_Disc); Bind(wxEVT_MENU, &MainEmuFrame::Menu_CdvdSource_Click, this, MenuId_Src_NoDisc); diff --git a/pcsx2/gui/MainFrame.h b/pcsx2/gui/MainFrame.h index 4b46ded28e..530ff2bfb6 100644 --- a/pcsx2/gui/MainFrame.h +++ b/pcsx2/gui/MainFrame.h @@ -144,7 +144,7 @@ public: void OnLogBoxHidden(); bool IsPaused() const { return GetMenuBar()->IsChecked( MenuId_Sys_SuspendResume ); } - void UpdateIsoSrcSelection(); + void UpdateCdvdSrcSelection(); void RemoveCdvdMenu(); void EnableMenuItem( int id, bool enable ); void CheckMenuItem(int id, bool checked); @@ -189,7 +189,7 @@ protected: void Menu_IsoBrowse_Click(wxCommandEvent &event); void Menu_IsoClear_Click(wxCommandEvent &event); - void Menu_DriveSelector_Click(wxCommandEvent &event); + void Menu_DiscBrowse_Click(wxCommandEvent &event); void Menu_EnableBackupStates_Click(wxCommandEvent &event); void Menu_EnablePatches_Click(wxCommandEvent &event); void Menu_EnableCheats_Click(wxCommandEvent &event); @@ -249,6 +249,7 @@ protected: void _DoBootCdvd(); bool _DoSelectIsoBrowser( wxString& dest ); bool _DoSelectELFBrowser(); + bool _DoSelectDiscBrowser( wxString& driveLetter ); // ------------------------------------------------------------------------ // MainEmuFram Internal API for Populating Main Menu Contents diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index c108307794..88bc364fe6 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -174,7 +174,54 @@ wxWindowID SwapOrReset_Iso( wxWindow* owner, IScopedCoreThread& core_control, co core_control.AllowResume(); } - GetMainFrame().EnableCdvdPluginSubmenu( g_Conf->CdvdSource == CDVD_SourceType::Plugin); + //TODO_CDVD enable/disable disc selector menu item + + return result; +} + +// Return values: +// wxID_CANCEL - User canceled the action outright. +// wxID_RESET - User wants to reset the emu in addition to swap discs +// (anything else) - Standard swap, no reset. (hotswap!) +wxWindowID SwapOrReset_Disc( wxWindow* owner, IScopedCoreThread& core, const wxString driveLetter) +{ + wxWindowID result = wxID_CANCEL; + + if ((g_Conf->CdvdSource == CDVD_SourceType::Disc) && (driveLetter == g_Conf->CurrentDisc)) + { + core.AllowResume(); + return result; + } + + if (SysHasValidState()) + { + core.DisallowResume(); + wxDialogWithHelpers dialog(owner, _("Confirm disc change")); + + dialog += dialog.Heading("New drive selected: " + driveLetter); + dialog += dialog.GetCharHeight(); + dialog += dialog.Heading(_("Do you want to swap discs or boot the new disc (via system reset)?")); + + result = pxIssueConfirmation(dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap")); + if (result == wxID_CANCEL) + { + core.AllowResume(); + return result; + } + } + + g_Conf->CdvdSource = CDVD_SourceType::Disc; + SysUpdateDiscSrcDrive(driveLetter); + if (result == wxID_RESET) + { + core.DisallowResume(); + sApp.SysExecute(CDVD_SourceType::Disc); + } + else + { + Console.Indent().WriteLn("Hot swapping to new disc!"); + core.AllowResume(); + } return result; } @@ -202,7 +249,7 @@ wxWindowID SwapOrReset_CdvdSrc( wxWindow* owner, CDVD_SourceType newsrc ) if( result == wxID_CANCEL ) { core.AllowResume(); - sMainFrame.UpdateIsoSrcSelection(); + sMainFrame.UpdateCdvdSrcSelection(); return result; } } @@ -216,7 +263,7 @@ wxWindowID SwapOrReset_CdvdSrc( wxWindow* owner, CDVD_SourceType newsrc ) WX_STR(wxString(CDVD_SourceLabels[enum_cast(oldsrc)])), WX_STR(wxString(CDVD_SourceLabels[enum_cast(newsrc)]))); //CoreThread.ChangeCdvdSource(); - sMainFrame.UpdateIsoSrcSelection(); + sMainFrame.UpdateCdvdSrcSelection(); core.AllowResume(); } else @@ -225,7 +272,7 @@ wxWindowID SwapOrReset_CdvdSrc( wxWindow* owner, CDVD_SourceType newsrc ) sApp.SysExecute( g_Conf->CdvdSource ); } - GetMainFrame().EnableCdvdPluginSubmenu( g_Conf->CdvdSource == CDVD_SourceType::Plugin ); + //TODO_CDVD enable/disable disc selector menu item return result; } @@ -311,6 +358,20 @@ bool MainEmuFrame::_DoSelectELFBrowser() return false; } +bool MainEmuFrame::_DoSelectDiscBrowser(wxString& driveLetter) +{ + DriveSelectorDialog driveDialog(this, g_Conf->Folders.RunDisc.ToString()); + + if (driveDialog.ShowModal() != wxID_CANCEL) + { + driveLetter = driveDialog.GetSelectedDrive(); + g_Conf->Folders.RunDisc = wxDirName(driveLetter); + return true; + } + + return false; +} + void MainEmuFrame::_DoBootCdvd() { ScopedCoreThreadPause paused_core; @@ -347,6 +408,37 @@ void MainEmuFrame::_DoBootCdvd() SysUpdateIsoSrcFile( result ); } } + else if( g_Conf->CdvdSource == CDVD_SourceType::Disc ) + { + bool selector = g_Conf->CurrentDisc.IsEmpty(); + + if( !selector && !wxDirExists(g_Conf->CurrentDisc) ) + { + // The previous mounted disc isn't mounted anymore + + wxDialogWithHelpers dialog( this, _("Drive not mounted!") ); + dialog += dialog.Heading( + _("An error occured while trying to read drive: ") + g_Conf->CurrentDisc + L"\n\n" + + _("Error: The configured drive does not exist. Click OK to select a new drive for CDVD.") + ); + + pxIssueConfirmation( dialog, MsgButtons().OK() ); + + selector = true; + } + + if( selector || g_Conf->AskOnBoot ) + { + wxString driveLetter; + if( !_DoSelectDiscBrowser( driveLetter ) ) + { + paused_core.AllowResume(); + return; + } + + SysUpdateDiscSrcDrive( driveLetter ); + } + } if( SysHasValidState() ) { @@ -364,21 +456,6 @@ void MainEmuFrame::_DoBootCdvd() sApp.SysExecute( g_Conf->CdvdSource ); } -void MainEmuFrame::Menu_DriveSelector_Click(wxCommandEvent& event) -{ - DriveSelectorDialog driveDialog(this); - if (driveDialog.ShowModal() == wxID_OK) - { - wxString driveLetter = driveDialog.GetSelectedDrive(); - //TODO_CDVD send driveLetter to CDVDdiscReader - } -} - -void MainEmuFrame::EnableCdvdPluginSubmenu(bool isEnable) -{ - EnableMenuItem( GetPluginMenuId_Settings(PluginId_CDVD), isEnable ); -} - void MainEmuFrame::Menu_CdvdSource_Click( wxCommandEvent &event ) { CDVD_SourceType newsrc = CDVD_SourceType::NoDisc; @@ -386,7 +463,6 @@ void MainEmuFrame::Menu_CdvdSource_Click( wxCommandEvent &event ) switch( event.GetId() ) { case MenuId_Src_Iso: newsrc = CDVD_SourceType::Iso; break; - case MenuId_Src_Plugin: newsrc = CDVD_SourceType::Plugin; break; case MenuId_Src_Disc: newsrc = CDVD_SourceType::Disc; break; case MenuId_Src_NoDisc: newsrc = CDVD_SourceType::NoDisc; break; jNO_DEFAULT @@ -409,6 +485,21 @@ void MainEmuFrame::Menu_FastBoot_Click( wxCommandEvent &event ) UpdateStatusBar(); } +void MainEmuFrame::Menu_DiscBrowse_Click(wxCommandEvent& event) +{ + ScopedCoreThreadPopup core; + wxString driveLetter; + + if ( !_DoSelectDiscBrowser(driveLetter) ) + { + core.AllowResume(); + return; + } + + SwapOrReset_Disc(this, core, driveLetter); + AppSaveSettings(); +} + wxString GetMsg_IsoImageChanged() { return _("You have selected the following ISO image into PCSX2:\n\n"); diff --git a/pcsx2/gui/SysState.cpp b/pcsx2/gui/SysState.cpp index 386682efe5..80cc8d1310 100644 --- a/pcsx2/gui/SysState.cpp +++ b/pcsx2/gui/SysState.cpp @@ -264,7 +264,6 @@ static const std::unique_ptr SavestateEntries[] = { std::unique_ptr(new PluginSavestateEntry( PluginId_GS )), std::unique_ptr(new PluginSavestateEntry( PluginId_PAD )), std::unique_ptr(new PluginSavestateEntry( PluginId_SPU2 )), - std::unique_ptr(new PluginSavestateEntry( PluginId_CDVD )), std::unique_ptr(new PluginSavestateEntry( PluginId_USB )), std::unique_ptr(new PluginSavestateEntry( PluginId_FW )), std::unique_ptr(new PluginSavestateEntry( PluginId_DEV9 )) diff --git a/pcsx2/windows/VCprojects/pcsx2.vcxproj b/pcsx2/windows/VCprojects/pcsx2.vcxproj index 30e67caadf..25a5b49d1b 100644 --- a/pcsx2/windows/VCprojects/pcsx2.vcxproj +++ b/pcsx2/windows/VCprojects/pcsx2.vcxproj @@ -148,11 +148,28 @@ + + false + false + false + + + true + true + true + + + true + true + true + + + diff --git a/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters b/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters index 0fd51f33f1..dad2c8cb98 100644 --- a/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters +++ b/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters @@ -148,6 +148,12 @@ {93e36831-627f-4529-b709-1f4bad398512} + + {be861049-a142-4650-85a5-a2fdd4eef011} + + + {a5904fb6-e846-4cbf-940c-ca1c604140a0} + @@ -867,6 +873,21 @@ AppHost\Dialogs + + System\Ps2\Iop\CDVD + + + System\Ps2\Iop\CDVD\Windows + + + System\Ps2\Iop\CDVD\Windows + + + System\Ps2\Iop\CDVD\Unix + + + System\Ps2\Iop\CDVD\Unix + diff --git a/plugins/CDVDnull/CDVD.cpp b/plugins/CDVDnull/CDVD.cpp deleted file mode 100644 index 6d2e32e0ff..0000000000 --- a/plugins/CDVDnull/CDVD.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* CDVDnull - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - - -#include -#include "CDVD.h" -#include "svnrev.h" - -#ifdef _MSC_VER -#define snprintf sprintf_s -#endif -static char libraryName[256]; - -const unsigned char version = PS2E_CDVD_VERSION; -const unsigned char revision = 0; -const unsigned char build = 6; - -EXPORT_C_(const char *) -PS2EgetLibName() -{ - snprintf(libraryName, 255, "CDVDnull Driver %lld%s", SVN_REV, SVN_MODS ? "m" : ""); - return libraryName; -} - -EXPORT_C_(u32) -PS2EgetLibType() -{ - return PS2E_LT_CDVD; -} - -EXPORT_C_(u32) -CALLBACK PS2EgetLibVersion2(u32 type) -{ - return (version << 16) | (revision << 8) | build; -} - -EXPORT_C_(s32) -CDVDinit() -{ - return 0; -} - -EXPORT_C_(s32) -CDVDopen(const char *pTitle) -{ - return 0; -} - -EXPORT_C_(void) -CDVDclose() -{ -} - -EXPORT_C_(void) -CDVDshutdown() -{ -} - -EXPORT_C_(s32) -CDVDreadTrack(u32 lsn, int mode) -{ - return -1; -} - -// return can be NULL (for async modes) -EXPORT_C_(u8 *) -CDVDgetBuffer() -{ - return NULL; -} - -EXPORT_C_(s32) -CDVDreadSubQ(u32 lsn, cdvdSubQ *subq) -{ - return -1; -} - -EXPORT_C_(s32) -CDVDgetTN(cdvdTN *Buffer) -{ - return -1; -} - -EXPORT_C_(s32) -CDVDgetTD(u8 Track, cdvdTD *Buffer) -{ - return -1; -} - -EXPORT_C_(s32) -CDVDgetTOC(void *toc) -{ - return -1; -} - -EXPORT_C_(s32) -CDVDgetDiskType() -{ - return CDVD_TYPE_NODISC; -} - -EXPORT_C_(s32) -CDVDgetTrayStatus() -{ - return CDVD_TRAY_CLOSE; -} - -EXPORT_C_(s32) -CDVDctrlTrayOpen() -{ - return 0; -} - -EXPORT_C_(s32) -CDVDctrlTrayClose() -{ - return 0; -} - -EXPORT_C_(void) -CDVDconfigure() -{ - SysMessage("Nothing to Configure"); -} - -EXPORT_C_(void) -CDVDabout() -{ - SysMessage("%s %d.%d", "CDVDnull Driver", revision, build); -} - -EXPORT_C_(s32) -CDVDtest() -{ - return 0; -} diff --git a/plugins/CDVDnull/CDVD.h b/plugins/CDVDnull/CDVD.h deleted file mode 100644 index 4f64dbe2fe..0000000000 --- a/plugins/CDVDnull/CDVD.h +++ /dev/null @@ -1,42 +0,0 @@ -/* CDVDnull - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - - -#ifndef __CDVD_H__ -#define __CDVD_H__ - -#define CDVDdefs -#include "PS2Edefs.h" -#include "PS2Eext.h" - -/*#ifdef _MSC_VER -#define EXPORT_C_(type) extern "C" __declspec(dllexport) type CALLBACK -#else -#define EXPORT_C_(type) extern "C" type -#endif*/ - -#ifdef _MSC_VER -#define EXPORT_C_(type) extern "C" type CALLBACK -#else -#define EXPORT_C_(type) extern "C" __attribute__((stdcall, externally_visible, visibility("default"))) type -#endif - -extern const unsigned char version; -extern const unsigned char revision; -extern const unsigned char build; -extern const unsigned int minor; - -extern void SysMessage(const char *fmt, ...); -#endif /* __CDVD_H__ */ diff --git a/plugins/CDVDnull/CMakeLists.txt b/plugins/CDVDnull/CMakeLists.txt deleted file mode 100644 index 4f077b0e08..0000000000 --- a/plugins/CDVDnull/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Check that people use the good file -if(NOT TOP_CMAKE_WAS_SOURCED) - message(FATAL_ERROR " - You did not 'cmake' the good CMakeLists.txt file. Use the one in the top dir. - It is advice to delete all wrongly generated cmake stuff => CMakeFiles & CMakeCache.txt") -endif() - - -# plugin name -set(Output CDVDnull) - -set(CDVDnullFinalFlags - -fvisibility=hidden - -Wall - -Wno-parentheses - ) - -# CDVDnull sources -set(CDVDnullSources - CDVD.cpp) - -# CDVDnull headers -set(CDVDnullHeaders - CDVD.h) - -# CDVDnull Windows sources -set(CDVDnullWindowsSources - Windows/CDVDnull.def - Windows/plugin.def) - -# CDVDnull Windows headers -set(CDVDnullWindowsHeaders - ) - -set(CDVDnullFinalSources - ${CDVDnullSources} - ${CDVDnullHeaders} -) - -set(CDVDnullFinalLibs - ${GTK2_LIBRARIES} -) - -add_pcsx2_plugin(${Output} "${CDVDnullFinalSources}" "${CDVDnullFinalLibs}" "${CDVDnullFinalFlags}") diff --git a/plugins/CDVDnull/ReadMe.txt b/plugins/CDVDnull/ReadMe.txt deleted file mode 100644 index 8038977bf7..0000000000 --- a/plugins/CDVDnull/ReadMe.txt +++ /dev/null @@ -1,39 +0,0 @@ -CDVDnull v0.6 ---------------- - - This is an extension to use with playstation2 emulators - as PCSX2 (only one right now). - The plugin is free open source code. - -Using: ------ - Place the file "CDVDnull.dll" at the Plugins directory - of the Emulator to use it. - -Changes: -------- - v0.6: - * added vsnet2003 project files. - * added support for functions in new plugin version - - v0.5: - * added vsnet2005beta1 project files. 64bit plugin should be okay now (Not tested!) - - v0.4: - * updated to 0.4.3 specifications - - v0.3: - * updated to 0.4.0 specifications - - v0.2: - * add the 0.2.9 specifications - * CDVDopen refixed - - v0.1: - * First Release - * Tested with Pcsx2 - -Authors: -------- - - diff --git a/plugins/CDVDnull/Windows/CDVDnull.def b/plugins/CDVDnull/Windows/CDVDnull.def deleted file mode 100644 index 9617d934ef..0000000000 --- a/plugins/CDVDnull/Windows/CDVDnull.def +++ /dev/null @@ -1,29 +0,0 @@ -; CDVDnull.def : Declares the module parameters for the DLL. - -;LIBRARY "CDVDnull" -;DESCRIPTION 'CDVD Null Driver' - -EXPORTS - ; Explicit exports can go here - PS2EgetLibType @2 - PS2EgetLibName @3 - PS2EgetLibVersion2 @4 - CDVDinit @5 - CDVDshutdown @6 - CDVDopen @7 - CDVDclose @8 - CDVDreadTrack @9 - CDVDgetBuffer @10 - CDVDreadSubQ @11 - CDVDgetTN @12 - CDVDgetTD @13 - CDVDgetTOC @14 - CDVDgetDiskType @15 - CDVDgetTrayStatus @16 - CDVDctrlTrayOpen @17 - CDVDctrlTrayClose @18 - - CDVDconfigure @19 - CDVDtest @20 - CDVDabout @21 - diff --git a/plugins/CDVDnull/Windows/CDVDnull.vcxproj b/plugins/CDVDnull/Windows/CDVDnull.vcxproj deleted file mode 100644 index a1970b5f10..0000000000 --- a/plugins/CDVDnull/Windows/CDVDnull.vcxproj +++ /dev/null @@ -1,98 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - CDVDnull - {F38D9DF0-F68D-49D9-B3A0-932E74FB74A0} - CDVDnull - - - - DynamicLibrary - MultiByte - true - $(DefaultPlatformToolset) - - - DynamicLibrary - MultiByte - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - false - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - - - NDEBUG;_USRDLL;CDVDNULL_EXPORTS;%(PreprocessorDefinitions) - Level3 - - - NDEBUG;%(PreprocessorDefinitions) - 0x2c0a - - - /MACHINE:I386 %(AdditionalOptions) - odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - true - .\CDVDnull.def - false - - - - - - - _USRDLL;CDVDNULL_EXPORTS;%(PreprocessorDefinitions) - - - CDVDnull.def - false - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/CDVDnull/Windows/CDVDnull.vcxproj.filters b/plugins/CDVDnull/Windows/CDVDnull.vcxproj.filters deleted file mode 100644 index 53f700a0a9..0000000000 --- a/plugins/CDVDnull/Windows/CDVDnull.vcxproj.filters +++ /dev/null @@ -1,24 +0,0 @@ - - - - - {4a528d75-fc57-4a25-8f63-9efd961ebaac} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - - - Source Files - - - - - Source Files - - - - - Source Files - - - \ No newline at end of file diff --git a/plugins/CDVDnull/Windows/ProjectRootDir.props b/plugins/CDVDnull/Windows/ProjectRootDir.props deleted file mode 100644 index 423e907385..0000000000 --- a/plugins/CDVDnull/Windows/ProjectRootDir.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - $(ProjectRootDir)\..\.. - $(SvnRootDir)\common - - - <_ProjectFileVersion>10.0.30128.1 - - - - $(SvnRootDir) - - - \ No newline at end of file diff --git a/plugins/CDVDnull/Windows/plugin.def b/plugins/CDVDnull/Windows/plugin.def deleted file mode 100644 index 50003fa4b6..0000000000 --- a/plugins/CDVDnull/Windows/plugin.def +++ /dev/null @@ -1,21 +0,0 @@ -EXPORTS - PS2EgetLibType = PS2EgetLibType@0 @2 - PS2EgetLibName = PS2EgetLibName@0 @3 - PS2EgetLibVersion2 = PS2EgetLibVersion2@4 @4 - CDVDinit = CDVDinit@0 @5 - CDVDshutdown = CDVDshutdown@0 @6 - CDVDopen = CDVDopen@0 @7 - CDVDclose = CDVDclose@0 @8 - CDVDreadTrack = CDVDreadTrack@8 @9 - CDVDgetBuffer = CDVDgetBuffer@0 @10 - CDVDreadSubQ = CDVDreadSubQ@8 @11 - CDVDgetTN = CDVDgetTN@4 @12 - CDVDgetTD = CDVDgetTD@8 @13 - CDVDgetTOC = CDVDgetTOC@4 @14 - CDVDgetDiskType = CDVDgetDiskType@0 @15 - CDVDgetTrayStatus = CDVDgetTrayStatus@0 @16 - CDVDctrlTrayOpen = CDVDctrlTrayOpen@0 @17 - CDVDctrlTrayClose = CDVDctrlTrayClose@0 @18 - CDVDconfigure = CDVDconfigure@0 @19 - CDVDtest = CDVDtest@0 @20 - CDVDabout = CDVDabout@0 @21 diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9b0cbc4501..172d4155e2 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -6,14 +6,6 @@ if(NOT TOP_CMAKE_WAS_SOURCED) endif() -if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/cdvdGigaherz" AND cdvdGigaherz) - add_subdirectory(cdvdGigaherz/src) -endif() - -if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/CDVDnull" AND CDVDnull) - add_subdirectory(CDVDnull) -endif() - if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/dev9null" AND dev9null) add_subdirectory(dev9null) endif() diff --git a/plugins/cdvdGigaherz/src/CDVD.cpp b/plugins/cdvdGigaherz/src/CDVD.cpp deleted file mode 100644 index 8707272017..0000000000 --- a/plugins/cdvdGigaherz/src/CDVD.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2014 David Quintana [gigaherz] - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "CDVD.h" -#include -#include -#include -#include -#include "svnrev.h" - -Settings g_settings; -static std::string s_config_file{"inis/cdvdGigaherz.ini"}; - -void (*newDiscCB)(); - -static std::mutex s_keepalive_lock; -static std::condition_variable s_keepalive_cv; -static std::thread s_keepalive_thread; - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// State Information // - -u8 strack; -u8 etrack; -track tracks[100]; - -int curDiskType; -int curTrayStatus; - -static u32 csector; -int cmode; - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// Plugin Interface // - -#ifndef PCSX2_DEBUG -static std::string s_libname("cdvdGigaherz " + std::to_string(SVN_REV)); -#else -static std::string s_libname("cdvdGigaherz Debug " + std::to_string(SVN_REV)); -#endif - -const unsigned char version = PS2E_CDVD_VERSION; -const unsigned char revision = 0; -const unsigned char build = 11; - -EXPORT const char *CALLBACK PS2EgetLibName() -{ - return s_libname.c_str(); -} - -EXPORT u32 CALLBACK PS2EgetLibType() -{ - return PS2E_LT_CDVD; -} - -EXPORT u32 CALLBACK PS2EgetLibVersion2(u32 type) -{ - return (version << 16) | (revision << 8) | build; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// Utility Functions // - -inline u8 dec_to_bcd(u8 dec) -{ - return ((dec / 10) << 4) | (dec % 10); -} - -inline void lsn_to_msf(u8 *minute, u8 *second, u8 *frame, u32 lsn) -{ - *frame = dec_to_bcd(lsn % 75); - lsn /= 75; - *second = dec_to_bcd(lsn % 60); - lsn /= 60; - *minute = dec_to_bcd(lsn % 100); -} - -void ReadSettings() -{ - g_settings.Load(s_config_file); -} - -void WriteSettings() -{ - g_settings.Save(s_config_file); -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// CDVD processing functions // - -std::atomic s_keepalive_is_open; -bool disc_has_changed = false; -bool weAreInNewDiskCB = false; - -std::unique_ptr src; - -extern u32 g_last_sector_block_lsn; - -/////////////////////////////////////////////////////////////////////////////// -// keepAliveThread throws a read event regularly to prevent drive spin down // - -void keepAliveThread() -{ - u8 throwaway[2352]; - - printf(" * CDVD: KeepAlive thread started...\n"); - std::unique_lock guard(s_keepalive_lock); - - while (!s_keepalive_cv.wait_for(guard, std::chrono::seconds(30), - []() { return !s_keepalive_is_open; })) { - - //printf(" * keepAliveThread: polling drive.\n"); - if (src->GetMediaType() >= 0) - src->ReadSectors2048(g_last_sector_block_lsn, 1, throwaway); - else - src->ReadSectors2352(g_last_sector_block_lsn, 1, throwaway); - } - - printf(" * CDVD: KeepAlive thread finished.\n"); -} - -bool StartKeepAliveThread() -{ - s_keepalive_is_open = true; - try { - s_keepalive_thread = std::thread(keepAliveThread); - } catch (std::system_error &) { - s_keepalive_is_open = false; - } - - return s_keepalive_is_open; -} - -void StopKeepAliveThread() -{ - if (!s_keepalive_thread.joinable()) - return; - - { - std::lock_guard guard(s_keepalive_lock); - s_keepalive_is_open = false; - } - s_keepalive_cv.notify_one(); - s_keepalive_thread.join(); -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// CDVD Pluin Interface // - -EXPORT void CALLBACK CDVDsetSettingsDir(const char *dir) -{ - s_config_file = std::string(dir ? dir : "inis") + "/cdvdGigaherz.ini"; -} - -EXPORT s32 CALLBACK CDVDinit() -{ - return 0; -} - -EXPORT s32 CALLBACK CDVDopen(const char *pTitleFilename) -{ - ReadSettings(); - - auto drive = GetValidDrive(); - if (drive.empty()) - return -1; - - // open device file - try { - src = std::unique_ptr(new IOCtlSrc(drive)); - } catch (std::runtime_error &ex) { - fputs(ex.what(), stdout); - return -1; - } - - //setup threading manager - if (!cdvdStartThread()) { - src.reset(); - return -1; - } - StartKeepAliveThread(); - - return cdvdRefreshData(); -} - -EXPORT void CALLBACK CDVDclose() -{ - StopKeepAliveThread(); - cdvdStopThread(); - //close device - src.reset(); -} - -EXPORT void CALLBACK CDVDshutdown() -{ - //nothing to do here -} - -EXPORT s32 CALLBACK CDVDgetDualInfo(s32 *dualType, u32 *_layer1start) -{ - switch (src->GetMediaType()) { - case 1: - *dualType = 1; - *_layer1start = src->GetLayerBreakAddress() + 1; - return 0; - case 2: - *dualType = 2; - *_layer1start = src->GetLayerBreakAddress() + 1; - return 0; - case 0: - *dualType = 0; - *_layer1start = 0; - return 0; - } - return -1; -} - -int lastReadInNewDiskCB = 0; -u8 directReadSectorBuffer[2448]; - -EXPORT s32 CALLBACK CDVDreadSector(u8 *buffer, u32 lsn, int mode) -{ - return cdvdDirectReadSector(lsn, mode, buffer); -} - -EXPORT s32 CALLBACK CDVDreadTrack(u32 lsn, int mode) -{ - csector = lsn; - cmode = mode; - - if (weAreInNewDiskCB) { - int ret = cdvdDirectReadSector(lsn, mode, directReadSectorBuffer); - if (ret == 0) - lastReadInNewDiskCB = 1; - return ret; - } - - cdvdRequestSector(lsn, mode); - - return 0; -} - -// return can be NULL (for async modes) -EXPORT u8 *CALLBACK CDVDgetBuffer() -{ - if (lastReadInNewDiskCB) { - lastReadInNewDiskCB = 0; - return directReadSectorBuffer; - } - - return cdvdGetSector(csector, cmode); -} - -// return can be NULL (for async modes) -EXPORT int CALLBACK CDVDgetBuffer2(u8 *dest) -{ - // Do nothing for out of bounds disc sector reads. It prevents some games - // from hanging (All-Star Baseball 2005, Hello Kitty: Roller Rescue, - // Hot Wheels: Beat That! (NTSC), Ratchet & Clank 3 (PAL), - // Test Drive: Eve of Destruction, etc.). - if (csector >= src->GetSectorCount()) - return 0; - - int csize = 2352; - switch (cmode) { - case CDVD_MODE_2048: - csize = 2048; - break; - case CDVD_MODE_2328: - csize = 2328; - break; - case CDVD_MODE_2340: - csize = 2340; - break; - } - - if (lastReadInNewDiskCB) { - lastReadInNewDiskCB = 0; - - memcpy(dest, directReadSectorBuffer, csize); - return 0; - } - - memcpy(dest, cdvdGetSector(csector, cmode), csize); - - return 0; -} - -EXPORT s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ *subq) -{ - // the formatted subq command returns: control/adr, track, index, trk min, trk sec, trk frm, 0x00, abs min, abs sec, abs frm - - if (lsn >= src->GetSectorCount()) - return -1; - - memset(subq, 0, sizeof(cdvdSubQ)); - - lsn_to_msf(&subq->discM, &subq->discS, &subq->discF, lsn + 150); - - u8 i = strack; - while (i < etrack && lsn >= tracks[i + 1].start_lba) - ++i; - - lsn -= tracks[i].start_lba; - - lsn_to_msf(&subq->trackM, &subq->trackS, &subq->trackF, lsn); - - subq->mode = 1; - subq->ctrl = tracks[i].type; - subq->trackNum = i; - subq->trackIndex = 1; - - return 0; -} - -EXPORT s32 CALLBACK CDVDgetTN(cdvdTN *Buffer) -{ - Buffer->strack = strack; - Buffer->etrack = etrack; - return 0; -} - -EXPORT s32 CALLBACK CDVDgetTD(u8 Track, cdvdTD *Buffer) -{ - if (Track == 0) { - Buffer->lsn = src->GetSectorCount(); - Buffer->type = 0; - return 0; - } - - if (Track < strack) - return -1; - if (Track > etrack) - return -1; - - Buffer->lsn = tracks[Track].start_lba; - Buffer->type = tracks[Track].type; - return 0; -} - -EXPORT s32 CALLBACK CDVDgetTOC(void *toc) -{ - u8 *tocBuff = static_cast(toc); - if (curDiskType == CDVD_TYPE_NODISC) - return -1; - - if (curDiskType == CDVD_TYPE_DETCTDVDS || curDiskType == CDVD_TYPE_DETCTDVDD) { - memset(tocBuff, 0, 2048); - - s32 mt = src->GetMediaType(); - - if (mt < 0) - return -1; - - if (mt == 0) { //single layer - // fake it - tocBuff[0] = 0x04; - tocBuff[1] = 0x02; - tocBuff[2] = 0xF2; - tocBuff[3] = 0x00; - tocBuff[4] = 0x86; - tocBuff[5] = 0x72; - - tocBuff[16] = 0x00; // first sector for layer 0 - tocBuff[17] = 0x03; - tocBuff[18] = 0x00; - tocBuff[19] = 0x00; - } else if (mt == 1) { //PTP - u32 layer1start = src->GetLayerBreakAddress() + 0x30000; - - // dual sided - tocBuff[0] = 0x24; - tocBuff[1] = 0x02; - tocBuff[2] = 0xF2; - tocBuff[3] = 0x00; - tocBuff[4] = 0x41; - tocBuff[5] = 0x95; - - tocBuff[14] = 0x61; // PTP - - tocBuff[16] = 0x00; - tocBuff[17] = 0x03; - tocBuff[18] = 0x00; - tocBuff[19] = 0x00; - - tocBuff[20] = (layer1start >> 24); - tocBuff[21] = (layer1start >> 16) & 0xff; - tocBuff[22] = (layer1start >> 8) & 0xff; - tocBuff[23] = (layer1start >> 0) & 0xff; - } else { //OTP - u32 layer1start = src->GetLayerBreakAddress() + 0x30000; - - // dual sided - tocBuff[0] = 0x24; - tocBuff[1] = 0x02; - tocBuff[2] = 0xF2; - tocBuff[3] = 0x00; - tocBuff[4] = 0x41; - tocBuff[5] = 0x95; - - tocBuff[14] = 0x71; // OTP - - tocBuff[16] = 0x00; - tocBuff[17] = 0x03; - tocBuff[18] = 0x00; - tocBuff[19] = 0x00; - - tocBuff[24] = (layer1start >> 24); - tocBuff[25] = (layer1start >> 16) & 0xff; - tocBuff[26] = (layer1start >> 8) & 0xff; - tocBuff[27] = (layer1start >> 0) & 0xff; - } - } else if (curDiskType == CDVD_TYPE_DETCTCD) { - // cd toc - // (could be replaced by 1 command that reads the full toc) - u8 min, sec, frm, i; - s32 err; - cdvdTN diskInfo; - cdvdTD trackInfo; - memset(tocBuff, 0, 1024); - if (CDVDgetTN(&diskInfo) == -1) { - diskInfo.etrack = 0; - diskInfo.strack = 1; - } - if (CDVDgetTD(0, &trackInfo) == -1) - trackInfo.lsn = 0; - - tocBuff[0] = 0x41; - tocBuff[1] = 0x00; - - //Number of FirstTrack - tocBuff[2] = 0xA0; - tocBuff[7] = dec_to_bcd(diskInfo.strack); - - //Number of LastTrack - tocBuff[12] = 0xA1; - tocBuff[17] = dec_to_bcd(diskInfo.etrack); - - //DiskLength - lba_to_msf(trackInfo.lsn, &min, &sec, &frm); - tocBuff[22] = 0xA2; - tocBuff[27] = dec_to_bcd(min); - tocBuff[28] = dec_to_bcd(sec); - tocBuff[29] = dec_to_bcd(frm); - - fprintf(stderr, "Track 0: %u mins %u secs %u frames\n", min, sec, frm); - - for (i = diskInfo.strack; i <= diskInfo.etrack; i++) { - err = CDVDgetTD(i, &trackInfo); - lba_to_msf(trackInfo.lsn, &min, &sec, &frm); - tocBuff[i * 10 + 30] = trackInfo.type; - tocBuff[i * 10 + 32] = err == -1 ? 0 : dec_to_bcd(i); //number - tocBuff[i * 10 + 37] = dec_to_bcd(min); - tocBuff[i * 10 + 38] = dec_to_bcd(sec); - tocBuff[i * 10 + 39] = dec_to_bcd(frm); - fprintf(stderr, "Track %u: %u mins %u secs %u frames\n", i, min, sec, frm); - } - } else - return -1; - - return 0; -} - -EXPORT s32 CALLBACK CDVDgetDiskType() -{ - return curDiskType; -} - -EXPORT s32 CALLBACK CDVDgetTrayStatus() -{ - return curTrayStatus; -} - -EXPORT s32 CALLBACK CDVDctrlTrayOpen() -{ - curTrayStatus = CDVD_TRAY_OPEN; - return 0; -} - -EXPORT s32 CALLBACK CDVDctrlTrayClose() -{ - curTrayStatus = CDVD_TRAY_CLOSE; - return 0; -} - -EXPORT void CALLBACK CDVDnewDiskCB(void (*callback)()) -{ - newDiscCB = callback; -} - -EXPORT void CALLBACK CDVDconfigure() -{ - configure(); -} - -EXPORT s32 CALLBACK CDVDtest() -{ - return 0; -} diff --git a/plugins/cdvdGigaherz/src/CDVD.h b/plugins/cdvdGigaherz/src/CDVD.h deleted file mode 100644 index 8f6c050d64..0000000000 --- a/plugins/cdvdGigaherz/src/CDVD.h +++ /dev/null @@ -1,136 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2014 David Quintana [gigaherz] - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#ifndef __CDVD_H__ -#define __CDVD_H__ - -#if defined(_WIN32) -#define _WIN32_WINNT 0x0600 -#define NOMINMAX -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#define CDVDdefs -#include -#include "Settings.h" - -struct track -{ - u32 start_lba; - u8 type; -}; - -extern u8 strack; -extern u8 etrack; -extern track tracks[100]; - -extern int curDiskType; -extern int curTrayStatus; - -struct toc_entry -{ - u32 lba; - u8 track; - u8 adr : 4; - u8 control : 4; -}; - -class IOCtlSrc -{ - IOCtlSrc(const IOCtlSrc &) = delete; - IOCtlSrc &operator=(const IOCtlSrc &) = delete; - -#if defined(_WIN32) - HANDLE m_device = INVALID_HANDLE_VALUE; - std::wstring m_filename; - mutable std::mutex m_lock; -#else - int m_device = -1; - std::string m_filename; -#endif - - s32 m_media_type = 0; - u32 m_sectors = 0; - u32 m_layer_break = 0; - std::vector m_toc; - - bool ReadDVDInfo(); - bool ReadCDInfo(); - bool Reopen(); - -public: - IOCtlSrc(decltype(m_filename) filename); - ~IOCtlSrc(); - - u32 GetSectorCount() const; - const std::vector &ReadTOC() const; - bool ReadSectors2048(u32 sector, u32 count, u8 *buffer) const; - bool ReadSectors2352(u32 sector, u32 count, u8 *buffer) const; - u32 GetLayerBreakAddress() const; - s32 GetMediaType() const; - void SetSpindleSpeed(bool restore_defaults) const; - bool DiscReady(); -}; - -extern std::unique_ptr src; - -void configure(); - -void ReadSettings(); -void WriteSettings(); -#if defined(_WIN32) -std::wstring GetValidDrive(); -#else -std::string GetValidDrive(); -#endif - -extern Settings g_settings; - -extern bool disc_has_changed; -extern bool weAreInNewDiskCB; - -extern void (*newDiscCB)(); - -bool cdvdStartThread(); -void cdvdStopThread(); -void cdvdRequestSector(u32 sector, s32 mode); -u8 *cdvdGetSector(u32 sector, s32 mode); -s32 cdvdDirectReadSector(u32 sector, s32 mode, u8 *buffer); -s32 cdvdGetMediaType(); -s32 cdvdRefreshData(); -void cdvdParseTOC(); - -inline void lba_to_msf(s32 lba, u8 *m, u8 *s, u8 *f) -{ - lba += 150; - *m = static_cast(lba / (60 * 75)); - *s = static_cast((lba / 75) % 60); - *f = static_cast(lba % 75); -} - -#if defined(_WIN32) -#define EXPORT -#else -#define EXPORT extern "C" __attribute__((stdcall, externally_visible, visibility("default"))) -#endif -#endif /* __CDVD_H__ */ diff --git a/plugins/cdvdGigaherz/src/CMakeLists.txt b/plugins/cdvdGigaherz/src/CMakeLists.txt deleted file mode 100644 index ab5ff3eeb9..0000000000 --- a/plugins/cdvdGigaherz/src/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -#Check that people use the good file -if (NOT TOP_CMAKE_WAS_SOURCED) - message(FATAL_ERROR " - You did not 'cmake' the good CMakeLists.txt file. Use the one in the top dir. - It is advised to delete all wrongly generated cmake stuff => CMakeFiles & CMakeCache.txt") -endif() - -#plugin name(no version number to ease future version bump and bisect) -set(Output cdvdGigaherz) - -set(FinalFlags - -fvisibility=hidden - -Wall - -Wno-parentheses - ) - -set(Sources - CDVD.cpp - ReadThread.cpp - Settings.cpp - TocStuff.cpp -) - -set(Headers - CDVD.h - Settings.h -) - -if(Windows) - LIST(APPEND Sources - Windows/config.cpp - Windows/resource.h - ) -else() - LIST(APPEND Sources - Unix/GtkGui.cpp - Unix/LinuxConfig.cpp - Unix/LinuxIOCtlSrc.cpp - ) -endif() - -set(FinalSources - ${Sources} - ${Headers} -) - -set(FinalLibs - ${GTK2_LIBRARIES} - ${LIBC_LIBRARIES} - ${LIBUDEV_LIBRARIES} -) - -add_pcsx2_plugin(${Output} "${FinalSources}" "${FinalLibs}" "${FinalFlags}") diff --git a/plugins/cdvdGigaherz/src/ReadThread.cpp b/plugins/cdvdGigaherz/src/ReadThread.cpp deleted file mode 100644 index 979e97f394..0000000000 --- a/plugins/cdvdGigaherz/src/ReadThread.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2014 David Quintana [gigaherz] - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "CDVD.h" -#include -#include -#include -#include -#include - -const u32 sectors_per_read = 16; - -static_assert(sectors_per_read > 1 && !(sectors_per_read & (sectors_per_read - 1)), - "sectors_per_read must by a power of 2"); - -struct SectorInfo -{ - u32 lsn; - // Sectors are read in blocks, not individually - u8 data[2352 * sectors_per_read]; -}; - -u32 g_last_sector_block_lsn; - -static std::thread s_thread; - -static std::mutex s_notify_lock; -static std::condition_variable s_notify_cv; -static std::mutex s_request_lock; -static std::queue s_request_queue; -static std::mutex s_cache_lock; - -static std::atomic cdvd_is_open; - -//bits: 12 would use 1<<12 entries, or 4096*16 sectors ~ 128MB -#define CACHE_SIZE 12 - -const u32 CacheSize = 1U << CACHE_SIZE; -SectorInfo Cache[CacheSize]; - -u32 cdvdSectorHash(u32 lsn) -{ - u32 t = 0; - - int i = 32; - u32 m = CacheSize - 1; - - while (i >= 0) { - t ^= lsn & m; - lsn >>= CACHE_SIZE; - i -= CACHE_SIZE; - } - - return t & m; -} - -void cdvdCacheUpdate(u32 lsn, u8 *data) -{ - std::lock_guard guard(s_cache_lock); - u32 entry = cdvdSectorHash(lsn); - - memcpy(Cache[entry].data, data, 2352 * sectors_per_read); - Cache[entry].lsn = lsn; -} - -bool cdvdCacheCheck(u32 lsn) -{ - std::lock_guard guard(s_cache_lock); - u32 entry = cdvdSectorHash(lsn); - - return Cache[entry].lsn == lsn; -} - -bool cdvdCacheFetch(u32 lsn, u8 *data) -{ - std::lock_guard guard(s_cache_lock); - u32 entry = cdvdSectorHash(lsn); - - if (Cache[entry].lsn == lsn) { - memcpy(data, Cache[entry].data, 2352 * sectors_per_read); - return true; - } - //printf("NOT IN CACHE\n"); - return false; -} - -void cdvdCacheReset() -{ - std::lock_guard guard(s_cache_lock); - for (u32 i = 0; i < CacheSize; i++) { - Cache[i].lsn = std::numeric_limits::max(); - } -} - -bool cdvdReadBlockOfSectors(u32 sector, u8 *data) -{ - u32 count = std::min(sectors_per_read, src->GetSectorCount() - sector); - const s32 media = src->GetMediaType(); - - // TODO: Is it really necessary to retry if it fails? I'm not sure the - // second time is really going to be any better. - for (int tries = 0; tries < 2; ++tries) { - if (media >= 0) { - if (src->ReadSectors2048(sector, count, data)) - return true; - } else { - if (src->ReadSectors2352(sector, count, data)) - return true; - } - } - return false; -} - -void cdvdCallNewDiscCB() -{ - weAreInNewDiskCB = true; - newDiscCB(); - weAreInNewDiskCB = false; -} - -bool cdvdUpdateDiscStatus() -{ - bool ready = src->DiscReady(); - - if (!ready) { - if (!disc_has_changed) { - disc_has_changed = true; - curDiskType = CDVD_TYPE_NODISC; - curTrayStatus = CDVD_TRAY_OPEN; - cdvdCallNewDiscCB(); - } - } else { - if (disc_has_changed) { - curDiskType = CDVD_TYPE_NODISC; - curTrayStatus = CDVD_TRAY_CLOSE; - - disc_has_changed = false; - cdvdRefreshData(); - - { - std::lock_guard request_guard(s_request_lock); - s_request_queue = decltype(s_request_queue)(); - } - - cdvdCallNewDiscCB(); - } - } - return !ready; -} - -void cdvdThread() -{ - u8 buffer[2352 * sectors_per_read]; - u32 prefetches_left = 0; - - printf(" * CDVD: IO thread started...\n"); - std::unique_lock guard(s_notify_lock); - - while (cdvd_is_open) { - if (cdvdUpdateDiscStatus()) { - // Need to sleep some to avoid an aggressive spin that sucks the cpu dry. - s_notify_cv.wait_for(guard, std::chrono::milliseconds(10)); - prefetches_left = 0; - continue; - } - - if (prefetches_left == 0) - s_notify_cv.wait_for(guard, std::chrono::milliseconds(250)); - - // check again to make sure we're not done here... - if (!cdvd_is_open) - break; - - // Read request - bool handling_request = false; - u32 request_lsn; - - { - std::lock_guard request_guard(s_request_lock); - if (!s_request_queue.empty()) { - request_lsn = s_request_queue.front(); - s_request_queue.pop(); - handling_request = true; - } - } - - if (!handling_request) { - if (prefetches_left == 0) - continue; - - --prefetches_left; - - u32 next_prefetch_lsn = g_last_sector_block_lsn + sectors_per_read; - request_lsn = next_prefetch_lsn; - } - - // Handle request - if (!cdvdCacheCheck(request_lsn)) { - if (cdvdReadBlockOfSectors(request_lsn, buffer)) { - cdvdCacheUpdate(request_lsn, buffer); - } else { - // If the read fails, further reads are likely to fail too. - prefetches_left = 0; - continue; - } - } - - g_last_sector_block_lsn = request_lsn; - - if (!handling_request) - continue; - - // Prefetch - u32 next_prefetch_lsn = g_last_sector_block_lsn + sectors_per_read; - if (next_prefetch_lsn >= src->GetSectorCount()) { - prefetches_left = 0; - } else { - const u32 max_prefetches = 16; - u32 remaining = src->GetSectorCount() - next_prefetch_lsn; - prefetches_left = std::min((remaining + sectors_per_read - 1) / sectors_per_read, max_prefetches); - } - } - printf(" * CDVD: IO thread finished.\n"); -} - -bool cdvdStartThread() -{ - cdvd_is_open = true; - try { - s_thread = std::thread(cdvdThread); - } catch (std::system_error &) { - cdvd_is_open = false; - return false; - } - - cdvdCacheReset(); - - return true; -} - -void cdvdStopThread() -{ - cdvd_is_open = false; - s_notify_cv.notify_one(); - s_thread.join(); -} - -void cdvdRequestSector(u32 sector, s32 mode) -{ - if (sector >= src->GetSectorCount()) - return; - - // Align to cache block - sector &= ~(sectors_per_read - 1); - - if (cdvdCacheCheck(sector)) - return; - - { - std::lock_guard guard(s_request_lock); - s_request_queue.push(sector); - } - - s_notify_cv.notify_one(); -} - -u8 *cdvdGetSector(u32 sector, s32 mode) -{ - static u8 buffer[2352 * sectors_per_read]; - - // Align to cache block - u32 sector_block = sector & ~(sectors_per_read - 1); - - if (!cdvdCacheFetch(sector_block, buffer)) - if (cdvdReadBlockOfSectors(sector_block, buffer)) - cdvdCacheUpdate(sector_block, buffer); - - if (src->GetMediaType() >= 0) { - u32 offset = 2048 * (sector - sector_block); - return buffer + offset; - } - - u32 offset = 2352 * (sector - sector_block); - u8 *data = buffer + offset; - - switch (mode) { - case CDVD_MODE_2048: - // Data location depends on CD mode - return (data[15] & 3) == 2 ? data + 24 : data + 16; - case CDVD_MODE_2328: - return data + 24; - case CDVD_MODE_2340: - return data + 12; - } - return data; -} - -s32 cdvdDirectReadSector(u32 sector, s32 mode, u8 *buffer) -{ - static u8 data[2352 * sectors_per_read]; - - if (sector >= src->GetSectorCount()) - return -1; - - // Align to cache block - u32 sector_block = sector & ~(sectors_per_read - 1); - - if (!cdvdCacheFetch(sector_block, data)) { - if (cdvdReadBlockOfSectors(sector_block, data)) - cdvdCacheUpdate(sector_block, data); - } - - if (src->GetMediaType() >= 0) { - u32 offset = 2048 * (sector - sector_block); - memcpy(buffer, data + offset, 2048); - return 0; - } - - u32 offset = 2352 * (sector - sector_block); - u8 *bfr = data + offset; - - switch (mode) { - case CDVD_MODE_2048: - // Data location depends on CD mode - std::memcpy(buffer, (bfr[15] & 3) == 2 ? bfr + 24 : bfr + 16, 2048); - return 0; - case CDVD_MODE_2328: - memcpy(buffer, bfr + 24, 2328); - return 0; - case CDVD_MODE_2340: - memcpy(buffer, bfr + 12, 2340); - return 0; - default: - memcpy(buffer, bfr, 2352); - return 0; - } -} - -s32 cdvdGetMediaType() -{ - return src->GetMediaType(); -} - -s32 cdvdRefreshData() -{ - const char *diskTypeName = "Unknown"; - - //read TOC from device - cdvdParseTOC(); - - if ((etrack == 0) || (strack > etrack)) { - curDiskType = CDVD_TYPE_NODISC; - } else { - s32 mt = cdvdGetMediaType(); - - if (mt < 0) - curDiskType = CDVD_TYPE_DETCTCD; - else if (mt == 0) - curDiskType = CDVD_TYPE_DETCTDVDS; - else - curDiskType = CDVD_TYPE_DETCTDVDD; - } - - curTrayStatus = CDVD_TRAY_CLOSE; - - switch (curDiskType) { - case CDVD_TYPE_DETCTDVDD: - diskTypeName = "Double-Layer DVD"; - break; - case CDVD_TYPE_DETCTDVDS: - diskTypeName = "Single-Layer DVD"; - break; - case CDVD_TYPE_DETCTCD: - diskTypeName = "CD-ROM"; - break; - case CDVD_TYPE_NODISC: - diskTypeName = "No Disc"; - break; - } - - printf(" * CDVD: Disk Type: %s\n", diskTypeName); - - cdvdCacheReset(); - - return 0; -} diff --git a/plugins/cdvdGigaherz/src/Settings.cpp b/plugins/cdvdGigaherz/src/Settings.cpp deleted file mode 100644 index 355652b4f0..0000000000 --- a/plugins/cdvdGigaherz/src/Settings.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2016 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "Settings.h" - -#if defined(_WIN32) -#define NOMINMAX -#include -#include -#endif -#include -#include -#include -#include - -Settings::Settings() -{ -} - -Settings::Settings(std::map data) - : m_data(data) -{ -} - -void Settings::TrimWhitespace(std::string &str) const -{ - // Leading whitespace - str.erase(0, str.find_first_not_of(" \r\t")); - // Trailing whitespace - auto pos = str.find_last_not_of(" \r\t"); - if (pos != std::string::npos && pos != str.size() - 1) - str.erase(pos + 1); -} - -void Settings::Load(const std::string &filename) -{ -#ifdef _WIN32 - std::ifstream file(convert_utf8_to_utf16(filename)); -#else - std::ifstream file(filename); -#endif - if (!file.is_open()) - return; - - std::string line; - while (std::getline(file, line)) { - auto separator = line.find('='); - if (separator == std::string::npos) - continue; - - std::string key = line.substr(0, separator); - // Trim leading and trailing whitespace - TrimWhitespace(key); - if (key.empty()) - continue; - - std::string value = line.substr(separator + 1); - TrimWhitespace(value); - - Set(key, value); - } -} - -void Settings::Save(const std::string &filename) const -{ -#ifdef _WIN32 - std::ofstream file(convert_utf8_to_utf16(filename), std::ios::trunc); -#else - std::ofstream file(filename, std::ios::trunc); -#endif - if (!file.is_open()) - return; - - for (const auto &pair : m_data) - file << pair.first << '=' << pair.second << '\n'; -} - -void Settings::Set(std::string key, std::string value) -{ - m_data[key] = value; -} - -bool Settings::Get(const std::string &key, std::string &data) const -{ - auto it = m_data.find(key); - if (it == m_data.end()) - return false; - - data = it->second; - return true; -} - -#if defined(_WIN32) -void Settings::Set(std::string key, std::wstring value) -{ - int size = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, nullptr, 0, nullptr, nullptr); - std::vector converted_string(size); - WideCharToMultiByte(CP_UTF8, 0, value.c_str(), -1, converted_string.data(), converted_string.size(), nullptr, nullptr); - m_data[key] = converted_string.data(); -} - -bool Settings::Get(const std::string &key, std::wstring &data) const -{ - auto it = m_data.find(key); - if (it == m_data.end()) - return false; - - int size = MultiByteToWideChar(CP_UTF8, 0, it->second.c_str(), -1, nullptr, 0); - std::vector converted_string(size); - MultiByteToWideChar(CP_UTF8, 0, it->second.c_str(), -1, converted_string.data(), converted_string.size()); - data = converted_string.data(); - return true; -} -#endif diff --git a/plugins/cdvdGigaherz/src/Settings.h b/plugins/cdvdGigaherz/src/Settings.h deleted file mode 100644 index 520ad8431e..0000000000 --- a/plugins/cdvdGigaherz/src/Settings.h +++ /dev/null @@ -1,41 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2016 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#pragma once - -#include -#include - -class Settings -{ -private: - std::map m_data; - - void TrimWhitespace(std::string &str) const; - -public: - Settings(); - Settings(std::map data); - - void Load(const std::string &filename); - void Save(const std::string &filename) const; - - void Set(std::string key, std::string value); - bool Get(const std::string &key, std::string &data) const; -#if defined(_WIN32) - void Set(std::string key, std::wstring value); - bool Get(const std::string &key, std::wstring &data) const; -#endif -}; diff --git a/plugins/cdvdGigaherz/src/TocStuff.cpp b/plugins/cdvdGigaherz/src/TocStuff.cpp deleted file mode 100644 index 6cd7c548b2..0000000000 --- a/plugins/cdvdGigaherz/src/TocStuff.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2014 David Quintana [gigaherz] - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "CDVD.h" - -#include -#include - -void cdvdParseTOC() -{ - tracks[1].start_lba = 0; - - if (!src->GetSectorCount()) { - curDiskType = CDVD_TYPE_NODISC; - strack = 1; - etrack = 0; - return; - } - - if (src->GetMediaType() >= 0) { - tracks[1].type = CDVD_MODE1_TRACK; - - strack = 1; - etrack = 1; - return; - } - - strack = 0xFF; - etrack = 0; - - for (auto &entry : src->ReadTOC()) { - if (entry.track < 1 || entry.track > 99) - continue; - strack = std::min(strack, entry.track); - etrack = std::max(etrack, entry.track); - tracks[entry.track].start_lba = entry.lba; - if ((entry.control & 0x0C) == 0x04) { - std::array buffer; - // Byte 15 of a raw CD data sector determines the track mode - if (src->ReadSectors2352(entry.lba, 1, buffer.data()) && (buffer[15] & 3) == 2) { - tracks[entry.track].type = CDVD_MODE2_TRACK; - } else { - tracks[entry.track].type = CDVD_MODE1_TRACK; - } - } else { - tracks[entry.track].type = CDVD_AUDIO_TRACK; - } - fprintf(stderr, "Track %u start sector: %u\n", entry.track, entry.lba); - } -} diff --git a/plugins/cdvdGigaherz/src/Unix/GtkGui.cpp b/plugins/cdvdGigaherz/src/Unix/GtkGui.cpp deleted file mode 100644 index a9f1646a9e..0000000000 --- a/plugins/cdvdGigaherz/src/Unix/GtkGui.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2016 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "CDVD.h" -#include - -std::vector GetOpticalDriveList(); - -void configure() -{ - ReadSettings(); - - GtkDialogFlags flags = static_cast(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT); - GtkWidget *dialog = gtk_dialog_new_with_buttons("Config", nullptr, - flags, - "Cancel", GTK_RESPONSE_REJECT, - "Ok", GTK_RESPONSE_ACCEPT, - nullptr); - - GtkWidget *label = gtk_label_new("Device:"); - GtkWidget *combobox = gtk_combo_box_text_new(); - - auto drives = GetOpticalDriveList(); - std::string drive; - g_settings.Get("drive", drive); - for (size_t n = 0; n < drives.size(); ++n) { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), drives[n].c_str()); - if (drive == drives[n]) - gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), n); - } - - GtkContainer *content_area = GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))); - gtk_container_add(content_area, label); - gtk_container_add(content_area, combobox); - - gtk_widget_show_all(dialog); - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - if (const char *selected_drive = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combobox))) { - g_settings.Set("drive", selected_drive); - WriteSettings(); - } - } - gtk_widget_destroy(dialog); -} diff --git a/plugins/cdvdGigaherz/src/Unix/LinuxConfig.cpp b/plugins/cdvdGigaherz/src/Unix/LinuxConfig.cpp deleted file mode 100644 index 3fe321876d..0000000000 --- a/plugins/cdvdGigaherz/src/Unix/LinuxConfig.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2016 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "CDVD.h" -#include -#include -#include -#include -#include - -std::vector GetOpticalDriveList() -{ - udev *udev_context = udev_new(); - if (!udev_context) - return {}; - - std::vector drives; - udev_enumerate *enumerate = udev_enumerate_new(udev_context); - if (enumerate) { - udev_enumerate_add_match_subsystem(enumerate, "block"); - udev_enumerate_add_match_property(enumerate, "ID_CDROM_DVD", "1"); - udev_enumerate_scan_devices(enumerate); - udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate); - - udev_list_entry *dev_list_entry; - udev_list_entry_foreach(dev_list_entry, devices) - { - const char *path = udev_list_entry_get_name(dev_list_entry); - udev_device *device = udev_device_new_from_syspath(udev_context, path); - const char *devnode = udev_device_get_devnode(device); - if (devnode) - drives.push_back(devnode); - udev_device_unref(device); - } - udev_enumerate_unref(enumerate); - } - udev_unref(udev_context); - - return drives; -} - -std::string GetValidDrive() -{ - std::string drive; - g_settings.Get("drive", drive); - if (!drive.empty()) { - int fd = open(drive.c_str(), O_RDONLY | O_NONBLOCK); - if (fd != -1) { - if (ioctl(fd, CDROM_GET_CAPABILITY, 0) == -1) - drive.clear(); - close(fd); - } else { - drive.clear(); - } - } - if (drive.empty()) { - auto drives = GetOpticalDriveList(); - if (!drives.empty()) - drive = drives.front(); - } - if (!drive.empty()) - printf(" * CDVD: Opening drive '%s'...\n", drive.c_str()); - - return drive; -} diff --git a/plugins/cdvdGigaherz/src/Unix/LinuxIOCtlSrc.cpp b/plugins/cdvdGigaherz/src/Unix/LinuxIOCtlSrc.cpp deleted file mode 100644 index 500043bec2..0000000000 --- a/plugins/cdvdGigaherz/src/Unix/LinuxIOCtlSrc.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2016 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "../CDVD.h" - -#include -#include -#include -#include - -#include -#include -#include - -IOCtlSrc::IOCtlSrc(decltype(m_filename) filename) - : m_filename(filename) -{ - if (!Reopen()) - throw std::runtime_error(" * CDVD: Error opening source.\n"); -} - -IOCtlSrc::~IOCtlSrc() -{ - if (m_device != -1) { - SetSpindleSpeed(true); - close(m_device); - } -} - -bool IOCtlSrc::Reopen() -{ - if (m_device != -1) - close(m_device); - - // O_NONBLOCK allows a valid file descriptor to be returned even if the - // drive is empty. Probably does other things too. - m_device = open(m_filename.c_str(), O_RDONLY | O_NONBLOCK); - if (m_device == -1) - return false; - - // DVD detection MUST be first on Linux - The TOC ioctls work for both - // CDs and DVDs. - if (ReadDVDInfo() || ReadCDInfo()) - SetSpindleSpeed(false); - - return true; -} - -void IOCtlSrc::SetSpindleSpeed(bool restore_defaults) const -{ - // TODO: CD seems easy enough (CDROM_SELECT_SPEED ioctl), but I'm not sure - // about DVD. -} - -u32 IOCtlSrc::GetSectorCount() const -{ - return m_sectors; -} - -u32 IOCtlSrc::GetLayerBreakAddress() const -{ - return m_layer_break; -} - -s32 IOCtlSrc::GetMediaType() const -{ - return m_media_type; -} - -const std::vector &IOCtlSrc::ReadTOC() const -{ - return m_toc; -} - -bool IOCtlSrc::ReadSectors2048(u32 sector, u32 count, u8 *buffer) const -{ - const ssize_t bytes_to_read = 2048 * count; - ssize_t bytes_read = pread(m_device, buffer, bytes_to_read, sector * 2048ULL); - if (bytes_read == bytes_to_read) - return true; - - if (bytes_read == -1) - fprintf(stderr, " * CDVD read sectors %u-%u failed: %s\n", - sector, sector + count - 1, strerror(errno)); - else - fprintf(stderr, " * CDVD read sectors %u-%u: %zd bytes read, %zd bytes expected\n", - sector, sector + count - 1, bytes_read, bytes_to_read); - return false; -} - -bool IOCtlSrc::ReadSectors2352(u32 sector, u32 count, u8 *buffer) const -{ - union - { - cdrom_msf msf; - char buffer[CD_FRAMESIZE_RAW]; - } data; - - for (u32 n = 0; n < count; ++n) { - u32 lba = sector + n; - lba_to_msf(lba, &data.msf.cdmsf_min0, &data.msf.cdmsf_sec0, &data.msf.cdmsf_frame0); - if (ioctl(m_device, CDROMREADRAW, &data) == -1) { - fprintf(stderr, " * CDVD CDROMREADRAW sector %u failed: %s\n", - lba, strerror(errno)); - return false; - } - memcpy(buffer, data.buffer, CD_FRAMESIZE_RAW); - buffer += CD_FRAMESIZE_RAW; - } - - return true; -} - -bool IOCtlSrc::ReadDVDInfo() -{ - dvd_struct dvdrs; - dvdrs.type = DVD_STRUCT_PHYSICAL; - dvdrs.physical.layer_num = 0; - - int ret = ioctl(m_device, DVD_READ_STRUCT, &dvdrs); - if (ret == -1) - return false; - - u32 start_sector = dvdrs.physical.layer[0].start_sector; - u32 end_sector = dvdrs.physical.layer[0].end_sector; - - if (dvdrs.physical.layer[0].nlayers == 0) { - // Single layer - m_media_type = 0; - m_layer_break = 0; - m_sectors = end_sector - start_sector + 1; - } else if (dvdrs.physical.layer[0].track_path == 0) { - // Dual layer, Parallel Track Path - dvdrs.physical.layer_num = 1; - ret = ioctl(m_device, DVD_READ_STRUCT, &dvdrs); - if (ret == -1) - return false; - u32 layer1_start_sector = dvdrs.physical.layer[1].start_sector; - u32 layer1_end_sector = dvdrs.physical.layer[1].end_sector; - - m_media_type = 1; - m_layer_break = end_sector - start_sector; - m_sectors = end_sector - start_sector + 1 + layer1_end_sector - layer1_start_sector + 1; - } else { - // Dual layer, Opposite Track Path - u32 end_sector_layer0 = dvdrs.physical.layer[0].end_sector_l0; - m_media_type = 2; - m_layer_break = end_sector_layer0 - start_sector; - m_sectors = end_sector_layer0 - start_sector + 1 + end_sector - (~end_sector_layer0 & 0xFFFFFFU) + 1; - } - - return true; -} - -bool IOCtlSrc::ReadCDInfo() -{ - cdrom_tochdr header; - - if (ioctl(m_device, CDROMREADTOCHDR, &header) == -1) - return false; - - cdrom_tocentry entry{}; - entry.cdte_format = CDROM_LBA; - - m_toc.clear(); - for (u8 n = header.cdth_trk0; n <= header.cdth_trk1; ++n) { - entry.cdte_track = n; - if (ioctl(m_device, CDROMREADTOCENTRY, &entry) != -1) - m_toc.push_back({static_cast(entry.cdte_addr.lba), entry.cdte_track, - entry.cdte_adr, entry.cdte_ctrl}); - } - - // TODO: Do I need a fallback if this doesn't work? - entry.cdte_track = 0xAA; - if (ioctl(m_device, CDROMREADTOCENTRY, &entry) == -1) - return false; - - m_sectors = entry.cdte_addr.lba; - m_media_type = -1; - - return true; -} - -bool IOCtlSrc::DiscReady() -{ - if (m_device == -1) - return false; - - // CDSL_CURRENT must be used - 0 will cause the drive tray to close. - if (ioctl(m_device, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK) { - if (!m_sectors) - Reopen(); - } else { - m_sectors = 0; - m_layer_break = 0; - m_media_type = 0; - } - - return !!m_sectors; -} diff --git a/plugins/cdvdGigaherz/src/Windows/IOCtlSrc.cpp b/plugins/cdvdGigaherz/src/Windows/IOCtlSrc.cpp deleted file mode 100644 index 6ae9db3e4b..0000000000 --- a/plugins/cdvdGigaherz/src/Windows/IOCtlSrc.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2016 PCSX2 Dev Team - * Copyright (C) 2002-2014 David Quintana [gigaherz] - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "../CDVD.h" - -#include -#include -#include -// "typedef ignored" warning will disappear once we move to the Windows 10 SDK. -#pragma warning(push) -#pragma warning(disable : 4091) -#include -#pragma warning(pop) - -#include -#include -#include -#include - -IOCtlSrc::IOCtlSrc(decltype(m_filename) filename) - : m_filename(filename) -{ - if (!Reopen()) - throw std::runtime_error(" * CDVD: Error opening source.\n"); -} - -IOCtlSrc::~IOCtlSrc() -{ - if (m_device != INVALID_HANDLE_VALUE) { - SetSpindleSpeed(true); - CloseHandle(m_device); - } -} - -// 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) - CloseHandle(m_device); - - // SPTI only works if the device is opened with GENERIC_WRITE access. - m_device = CreateFile(m_filename.c_str(), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, nullptr, OPEN_EXISTING, - FILE_FLAG_SEQUENTIAL_SCAN, nullptr); - if (m_device == INVALID_HANDLE_VALUE) - return false; - - DWORD unused; - // Required to read from layer 1 of Dual layer DVDs - DeviceIoControl(m_device, FSCTL_ALLOW_EXTENDED_DASD_IO, nullptr, 0, nullptr, - 0, &unused, nullptr); - - if (ReadDVDInfo() || ReadCDInfo()) - SetSpindleSpeed(false); - - return true; -} - -void IOCtlSrc::SetSpindleSpeed(bool restore_defaults) const -{ - // IOCTL_CDROM_SET_SPEED issues a SET CD SPEED command. So 0xFFFF should be - // equivalent to "optimal performance". - // 1x DVD-ROM and CD-ROM speeds are respectively 1385 KB/s and 150KB/s. - // The PS2 can do 4x DVD-ROM and 24x CD-ROM speeds (5540KB/s and 3600KB/s). - // TODO: What speed? Performance seems smoother with a lower speed (less - // time required to get up to speed). - const USHORT speed = restore_defaults ? 0xFFFF : GetMediaType() >= 0 ? 5540 : 3600; - CDROM_SET_SPEED s{CdromSetSpeed, speed, speed, CdromDefaultRotation}; - - DWORD unused; - if (DeviceIoControl(m_device, IOCTL_CDROM_SET_SPEED, &s, sizeof(s), - nullptr, 0, &unused, nullptr)) { - if (!restore_defaults) - printf(" * CDVD: setSpindleSpeed success (%uKB/s)\n", speed); - } else { - printf(" * CDVD: setSpindleSpeed failed!\n"); - } -} - -u32 IOCtlSrc::GetSectorCount() const -{ - return m_sectors; -} - -u32 IOCtlSrc::GetLayerBreakAddress() const -{ - return m_layer_break; -} - -s32 IOCtlSrc::GetMediaType() const -{ - return m_media_type; -} - -const std::vector &IOCtlSrc::ReadTOC() const -{ - return m_toc; -} - -bool IOCtlSrc::ReadSectors2048(u32 sector, u32 count, u8 *buffer) const -{ - std::lock_guard guard(m_lock); - LARGE_INTEGER offset; - offset.QuadPart = sector * 2048ULL; - - if (!SetFilePointerEx(m_device, offset, nullptr, FILE_BEGIN)) { - fprintf(stderr, " * CDVD SetFilePointerEx failed: sector %u: error %u\n", - sector, GetLastError()); - return false; - } - - const DWORD bytes_to_read = 2048 * count; - DWORD bytes_read; - if (ReadFile(m_device, buffer, bytes_to_read, &bytes_read, nullptr)) { - if (bytes_read == bytes_to_read) - return true; - fprintf(stderr, " * CDVD ReadFile: sectors %u-%u: %u bytes read, %u bytes expected\n", - sector, sector + count - 1, bytes_read, bytes_to_read); - } else { - fprintf(stderr, " * CDVD ReadFile failed: sectors %u-%u: error %u\n", - sector, sector + count - 1, GetLastError()); - } - - return false; -} - -bool IOCtlSrc::ReadSectors2352(u32 sector, u32 count, u8 *buffer) const -{ - struct sptdinfo - { - SCSI_PASS_THROUGH_DIRECT info; - char sense_buffer[20]; - } sptd{}; - - // READ CD command - sptd.info.Cdb[0] = 0xBE; - // Don't care about sector type. - sptd.info.Cdb[1] = 0; - // Number of sectors to read - sptd.info.Cdb[6] = 0; - sptd.info.Cdb[7] = 0; - sptd.info.Cdb[8] = 1; - // Sync + all headers + user data + EDC/ECC. Excludes C2 + subchannel - sptd.info.Cdb[9] = 0xF8; - sptd.info.Cdb[10] = 0; - sptd.info.Cdb[11] = 0; - - sptd.info.CdbLength = 12; - sptd.info.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); - sptd.info.DataIn = SCSI_IOCTL_DATA_IN; - sptd.info.SenseInfoOffset = offsetof(sptdinfo, sense_buffer); - sptd.info.TimeOutValue = 5; - - // Read sectors one by one to avoid reading data from 2 tracks of different - // types in the same read (which will fail). - for (u32 n = 0; n < count; ++n) { - u32 current_sector = sector + n; - sptd.info.Cdb[2] = (current_sector >> 24) & 0xFF; - sptd.info.Cdb[3] = (current_sector >> 16) & 0xFF; - sptd.info.Cdb[4] = (current_sector >> 8) & 0xFF; - sptd.info.Cdb[5] = current_sector & 0xFF; - sptd.info.DataTransferLength = 2352; - sptd.info.DataBuffer = buffer + 2352 * n; - sptd.info.SenseInfoLength = sizeof(sptd.sense_buffer); - - DWORD unused; - if (DeviceIoControl(m_device, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, - sizeof(sptd), &sptd, sizeof(sptd), &unused, nullptr)) { - if (sptd.info.DataTransferLength == 2352) - continue; - } - printf(" * CDVD: SPTI failed reading sector %u; SENSE %u -", current_sector, sptd.info.SenseInfoLength); - for (const auto &c : sptd.sense_buffer) - printf(" %02X", c); - putchar('\n'); - return false; - } - - return true; -} - -bool IOCtlSrc::ReadDVDInfo() -{ - DWORD unused; - // 4 bytes header + 18 bytes layer descriptor - Technically you only need - // to read 17 bytes of the layer descriptor since bytes 17-2047 is for - // media specific information. However, Windows requires you to read at - // least 18 bytes of the layer descriptor or else the ioctl will fail. The - // media specific information seems to be empty, so there's no point reading - // any more than that. - std::array buffer; - DVD_READ_STRUCTURE dvdrs{{0}, DvdPhysicalDescriptor, 0, 0}; - - if (!DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), - buffer.data(), buffer.size(), &unused, nullptr)) - return false; - - auto &layer = *reinterpret_cast( - reinterpret_cast(buffer.data())->Data); - - u32 start_sector = _byteswap_ulong(layer.StartingDataSector); - u32 end_sector = _byteswap_ulong(layer.EndDataSector); - - if (layer.NumberOfLayers == 0) { - // Single layer - m_media_type = 0; - m_layer_break = 0; - m_sectors = end_sector - start_sector + 1; - } else if (layer.TrackPath == 0) { - // Dual layer, Parallel Track Path - dvdrs.LayerNumber = 1; - if (!DeviceIoControl(m_device, IOCTL_DVD_READ_STRUCTURE, &dvdrs, sizeof(dvdrs), - buffer.data(), buffer.size(), &unused, nullptr)) - return false; - u32 layer1_start_sector = _byteswap_ulong(layer.StartingDataSector); - u32 layer1_end_sector = _byteswap_ulong(layer.EndDataSector); - - m_media_type = 1; - m_layer_break = end_sector - start_sector; - m_sectors = end_sector - start_sector + 1 + layer1_end_sector - layer1_start_sector + 1; - } else { - // Dual layer, Opposite Track Path - u32 end_sector_layer0 = _byteswap_ulong(layer.EndLayerZeroSector); - m_media_type = 2; - m_layer_break = end_sector_layer0 - start_sector; - m_sectors = end_sector_layer0 - start_sector + 1 + end_sector - (~end_sector_layer0 & 0xFFFFFFU) + 1; - } - - return true; -} - -bool IOCtlSrc::ReadCDInfo() -{ - DWORD unused; - CDROM_READ_TOC_EX toc_ex{}; - toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC; - toc_ex.Msf = 0; - toc_ex.SessionTrack = 1; - - CDROM_TOC toc; - if (!DeviceIoControl(m_device, IOCTL_CDROM_READ_TOC_EX, &toc_ex, - sizeof(toc_ex), &toc, sizeof(toc), &unused, nullptr)) - return false; - - m_toc.clear(); - size_t track_count = ((toc.Length[0] << 8) + toc.Length[1] - 2) / sizeof(TRACK_DATA); - for (size_t n = 0; n < track_count; ++n) { - TRACK_DATA &track = toc.TrackData[n]; - // Exclude the lead-out track descriptor. - if (track.TrackNumber == 0xAA) - continue; - u32 lba = (track.Address[1] << 16) + (track.Address[2] << 8) + track.Address[3]; - m_toc.push_back({lba, track.TrackNumber, track.Adr, track.Control}); - } - - GET_LENGTH_INFORMATION info; - if (!DeviceIoControl(m_device, IOCTL_DISK_GET_LENGTH_INFO, nullptr, 0, &info, - sizeof(info), &unused, nullptr)) - return false; - - m_sectors = static_cast(info.Length.QuadPart / 2048); - m_media_type = -1; - - return true; -} - -bool IOCtlSrc::DiscReady() -{ - if (m_device == INVALID_HANDLE_VALUE) - return false; - - DWORD unused; - if (DeviceIoControl(m_device, IOCTL_STORAGE_CHECK_VERIFY, nullptr, 0, - nullptr, 0, &unused, nullptr)) { - if (!m_sectors) - Reopen(); - } else { - m_sectors = 0; - m_layer_break = 0; - m_media_type = 0; - } - - return !!m_sectors; -} diff --git a/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.rc b/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.rc deleted file mode 100644 index d1d26c2897..0000000000 --- a/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.rc +++ /dev/null @@ -1,102 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Spanish resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESN) -#ifdef _WIN32 -LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_CONFIG DIALOGEX 0, 0, 184, 77 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "cdvdGigaherz" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,75,59,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,59,50,14 - COMBOBOX IDC_DRIVE,15,20,160,64,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Source drive...",IDC_STATIC,7,7,172,48 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_CONFIG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 179 - TOPMARGIN, 7 - BOTTOMMARGIN, 73 - END -END -#endif // APSTUDIO_INVOKED - -#endif // Spanish resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj b/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj deleted file mode 100644 index a4065a3d49..0000000000 --- a/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - {5CF88D5F-64DD-4EDC-9F1A-436BD502940A} - - - - DynamicLibrary - $(DefaultPlatformToolset) - Unicode - true - true - false - - - - - - - - - - - - - - AllRules.ruleset - - - - .\plugin.def - MachineX86 - MachineX64 - - - - - - - true - - - true - - - true - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj.filters b/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj.filters deleted file mode 100644 index 78ef4c372a..0000000000 --- a/plugins/cdvdGigaherz/src/Windows/cdvdGigaherz.vcxproj.filters +++ /dev/null @@ -1,76 +0,0 @@ - - - - - {c03fe088-95f7-4235-a796-5fe044914fb5} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {6c12b075-7b05-42ce-8628-c668f325f4ce} - h;hpp;hxx;hm;inl - - - {a80698fd-3734-41c4-b7e8-6b96b34633e0} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - {a0a8deec-63fd-4ef5-b815-d6c9ff3d80e1} - - - {102507ff-fef0-4989-9bcb-4fa14a0b7595} - - - {2054202d-299a-4cbf-8f4f-282bfe79a98e} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files\Linux - - - Source Files\Windows - - - Source Files\Windows - - - Source Files\Linux - - - Source Files\GTK - - - - - Header Files - - - Header Files - - - Header Files - - - - - Resource Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/plugins/cdvdGigaherz/src/Windows/config.cpp b/plugins/cdvdGigaherz/src/Windows/config.cpp deleted file mode 100644 index 8873bf91a6..0000000000 --- a/plugins/cdvdGigaherz/src/Windows/config.cpp +++ /dev/null @@ -1,127 +0,0 @@ -//Copyright (C) 2016 PCSX2 Dev Team -//Copyright (c) David Quintana -// -//This library is free software; you can redistribute it and/or -//modify it under the terms of the GNU Lesser General Public -//License as published by the Free Software Foundation; either -//version 3.0 of the License, or (at your option) any later version. -// -//This library is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -//Lesser General Public License for more details. -// -//You should have received a copy of the GNU Lesser General Public -//License along with this library; if not, write to the Free Software -//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -// - -#include "../CDVD.h" -#include -#include -#include "resource.h" - -static HINSTANCE s_hinstance; - -BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) -{ - if (reason == DLL_PROCESS_ATTACH) - s_hinstance = hinstance; - - return TRUE; -} - -static INT_PTR CALLBACK ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: { - std::vector &drives = - *reinterpret_cast *>(lParam); - HWND combobox = GetDlgItem(hWnd, IDC_DRIVE); - std::wstring drive; - g_settings.Get("drive", drive); - for (size_t n = 0; n < drives.size(); ++n) { - SendMessage(combobox, CB_ADDSTRING, 0, - reinterpret_cast(drives[n].c_str())); - if (drive == drives[n]) - SendMessage(combobox, CB_SETCURSEL, n, 0); - } - } break; - case WM_COMMAND: - // Parse the menu selections: - switch (LOWORD(wParam)) { - case IDOK: { - HWND combobox = GetDlgItem(hWnd, IDC_DRIVE); - LRESULT index = SendMessage(combobox, CB_GETCURSEL, 0, 0); - if (index != CB_ERR) { - LRESULT length = SendMessage(combobox, CB_GETLBTEXTLEN, - index, 0); - std::vector drive(length + 1); - SendMessage(combobox, CB_GETLBTEXT, index, - reinterpret_cast(drive.data())); - g_settings.Set("drive", std::wstring(drive.data())); - WriteSettings(); - } - EndDialog(hWnd, 0); - } break; - case IDCANCEL: - EndDialog(hWnd, 0); - break; - - default: - return FALSE; - } - break; - default: - return FALSE; - } - return TRUE; -} - -static std::vector GetOpticalDriveList() -{ - DWORD size = GetLogicalDriveStrings(0, nullptr); - std::vector drive_strings(size); - if (GetLogicalDriveStrings(size, drive_strings.data()) != size - 1) - return {}; - - std::vector drives; - for (auto p = drive_strings.data(); *p; ++p) { - if (GetDriveType(p) == DRIVE_CDROM) - drives.push_back(p); - while (*p) - ++p; - } - return drives; -} - -std::wstring GetValidDrive() -{ - std::wstring drive; - g_settings.Get("drive", drive); - if (drive.empty() || GetDriveType(drive.c_str()) != DRIVE_CDROM) { - auto drives = GetOpticalDriveList(); - if (drives.empty()) - return {}; - drive = drives.front(); - } - - int size = WideCharToMultiByte(CP_UTF8, 0, drive.c_str(), -1, nullptr, 0, nullptr, nullptr); - std::vector converted_string(size); - WideCharToMultiByte(CP_UTF8, 0, drive.c_str(), -1, converted_string.data(), converted_string.size(), nullptr, nullptr); - printf(" * CDVD: Opening drive '%s'...\n", converted_string.data()); - - // The drive string has the form "X:\", but to open the drive, the string - // has to be in the form "\\.\X:" - drive.pop_back(); - drive.insert(0, L"\\\\.\\"); - return drive; -} - -void configure() -{ - ReadSettings(); - auto drives = GetOpticalDriveList(); - DialogBoxParam(s_hinstance, MAKEINTRESOURCE(IDD_CONFIG), GetActiveWindow(), - ConfigProc, reinterpret_cast(&drives)); -} diff --git a/plugins/cdvdGigaherz/src/Windows/plugin.def b/plugins/cdvdGigaherz/src/Windows/plugin.def deleted file mode 100644 index d348f76b9e..0000000000 --- a/plugins/cdvdGigaherz/src/Windows/plugin.def +++ /dev/null @@ -1,25 +0,0 @@ -EXPORTS - PS2EgetLibType @2 - PS2EgetLibName @3 - PS2EgetLibVersion2 @4 - CDVDinit @5 - CDVDshutdown @6 - CDVDopen @7 - CDVDclose @8 - CDVDreadTrack @9 - CDVDgetBuffer @10 - CDVDreadSubQ @11 - CDVDgetTN @12 - CDVDgetTD @13 - CDVDgetTOC @14 - CDVDgetDiskType @15 - CDVDgetTrayStatus @16 - CDVDctrlTrayOpen @17 - CDVDctrlTrayClose @18 - CDVDconfigure @19 - CDVDtest @20 - CDVDnewDiskCB @22 - CDVDgetBuffer2 @23 - CDVDreadSector @24 - CDVDgetDualInfo @25 - CDVDsetSettingsDir @26 diff --git a/plugins/cdvdGigaherz/src/Windows/resource.h b/plugins/cdvdGigaherz/src/Windows/resource.h deleted file mode 100644 index 64efd1e4d2..0000000000 --- a/plugins/cdvdGigaherz/src/Windows/resource.h +++ /dev/null @@ -1,42 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by cdvd.rc -// - -#ifndef IDC_STATIC -#define IDC_STATIC -1 -#endif - -#define IDD_CONFIG 101 -#define IDC_PLUGINS 1000 -#define IDC_CONFIGURE 1001 -#define IDC_TEST 1002 -#define IDC_ABOUT 1003 -#define IDC_IMAGE_BROWSE 1004 -#define IDC_USEISO 1005 -#define IDC_NOCD 1006 -#define IDC_PLUGIN 1007 -#define IDC_IMAGE 1008 -#define IDC_IMAGE_FILE 1009 -#define IDC_NOSUB 1010 -#define IDC_FAKE 1011 -#define IDC_SAME 1012 -#define IDC_DRIVE 1012 -#define IDC_SUB_FILE 1014 -#define IDC_ABOUT3 1015 -#define IDC_SUB_BROWSE 1015 -#define IDC_FILE 1016 -#define IDC_NODUMP 1020 -#define IDC_DUMP_ISO 1021 -#define IDC_DUMP_BDV2 1022 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1011 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif