aboutsummaryrefslogtreecommitdiff
path: root/backends/audiocd/linux/linux-audiocd.cpp
diff options
context:
space:
mode:
authorMatthew Hoops2015-09-28 21:13:54 -0400
committerJohannes Schickel2016-03-13 13:56:39 +0100
commit91d695d4a2fea6742c31abd246a22c40797b014f (patch)
treeb7ef0a742d76b921473c1bd9dc46a97a1783496a /backends/audiocd/linux/linux-audiocd.cpp
parenta1a4fc0d5186ae4aeeb1e5ea99be4b36bf645179 (diff)
downloadscummvm-rg350-91d695d4a2fea6742c31abd246a22c40797b014f.tar.gz
scummvm-rg350-91d695d4a2fea6742c31abd246a22c40797b014f.tar.bz2
scummvm-rg350-91d695d4a2fea6742c31abd246a22c40797b014f.zip
BACKENDS: Detect the CD drive from the game's path on Linux
Diffstat (limited to 'backends/audiocd/linux/linux-audiocd.cpp')
-rw-r--r--backends/audiocd/linux/linux-audiocd.cpp77
1 files changed, 65 insertions, 12 deletions
diff --git a/backends/audiocd/linux/linux-audiocd.cpp b/backends/audiocd/linux/linux-audiocd.cpp
index a173a9d3be..c079c2d744 100644
--- a/backends/audiocd/linux/linux-audiocd.cpp
+++ b/backends/audiocd/linux/linux-audiocd.cpp
@@ -32,6 +32,7 @@
#include "audio/audiostream.h"
#include "backends/audiocd/default/default-audiocd.h"
#include "common/array.h"
+#include "common/config-manager.h"
#include "common/str.h"
#include "common/debug.h"
@@ -153,14 +154,20 @@ public:
private:
struct Device {
- Device(const Common::String &n, dev_t m) : name(n), mode(m) {}
+ Device(const Common::String &n, dev_t d) : name(n), device(d) {}
Common::String name;
- dev_t mode;
+ dev_t device;
};
- Common::Array<Device> scanDevices();
- bool tryAddDrive(const Common::String &drive, Common::Array<Device> &devices);
+ typedef Common::Array<Device> DeviceList;
+ DeviceList scanDevices();
+ bool tryAddDrive(DeviceList &devices, const Common::String &drive);
+ bool tryAddDrive(DeviceList &devices, const Common::String &drive, dev_t device);
+ bool tryAddDrive(DeviceList &devices, dev_t device);
+ bool tryAddPath(DeviceList &devices, const Common::String &path);
+ bool tryAddGamePath(DeviceList &devices);
bool loadTOC();
+ static bool hasDevice(const DeviceList &devices, dev_t device);
int _fd;
cdrom_tochdr _tocHeader;
@@ -193,11 +200,11 @@ LinuxAudioCDManager::~LinuxAudioCDManager() {
bool LinuxAudioCDManager::openCD(int drive) {
closeCD();
- Common::Array<Device> devices = scanDevices();
- if (devices.empty())
+ DeviceList devices = scanDevices();
+ if (drive >= (int)devices.size())
return false;
- _fd = open(devices[0].name.c_str(), O_RDONLY | O_NONBLOCK, 0);
+ _fd = open(devices[drive].name.c_str(), O_RDONLY | O_NONBLOCK, 0);
if (_fd < 0)
return false;
@@ -259,13 +266,21 @@ void LinuxAudioCDManager::playCD(int track, int numLoops, int startFrame, int du
true);
}
-Common::Array<LinuxAudioCDManager::Device> LinuxAudioCDManager::scanDevices() {
- Common::Array<Device> devices;
- tryAddDrive("/dev/cdrom", devices);
+LinuxAudioCDManager::DeviceList LinuxAudioCDManager::scanDevices() {
+ DeviceList devices;
+
+ // Try to use the game's path first as the device
+ tryAddGamePath(devices);
+
+ // Try adding the default CD-ROM
+ tryAddDrive(devices, "/dev/cdrom");
+
+ // TODO: Try others?
+
return devices;
}
-bool LinuxAudioCDManager::tryAddDrive(const Common::String &drive, Common::Array<Device> &devices) {
+bool LinuxAudioCDManager::tryAddDrive(DeviceList &devices, const Common::String &drive) {
struct stat stbuf;
if (stat(drive.c_str(), &stbuf) < 0)
return false;
@@ -274,6 +289,13 @@ bool LinuxAudioCDManager::tryAddDrive(const Common::String &drive, Common::Array
if (!S_ISCHR(stbuf.st_mode) && !S_ISBLK(stbuf.st_mode))
return false;
+ return tryAddDrive(devices, drive, stbuf.st_rdev);
+}
+
+bool LinuxAudioCDManager::tryAddDrive(DeviceList &devices, const Common::String &drive, dev_t device) {
+ if (hasDevice(devices, device))
+ return true;
+
// Try opening the device and seeing if it is a CD-ROM drve
int fd = open(drive.c_str(), O_RDONLY | O_NONBLOCK, 0);
if (fd >= 0) {
@@ -283,7 +305,7 @@ bool LinuxAudioCDManager::tryAddDrive(const Common::String &drive, Common::Array
bool isCD = ioctl(fd, CDROMSUBCHNL, &info) == 0 || isTrayEmpty(errno);
close(fd);
if (isCD) {
- devices.push_back(Device(drive, stbuf.st_rdev));
+ devices.push_back(Device(drive, device));
return true;
}
}
@@ -291,6 +313,29 @@ bool LinuxAudioCDManager::tryAddDrive(const Common::String &drive, Common::Array
return false;
}
+bool LinuxAudioCDManager::tryAddDrive(DeviceList &devices, dev_t device) {
+ // Construct the block name
+ // (Does anyone have a better way to do this? bdevname is kernel only)
+ Common::String name = Common::String::format("/dev/block/%d:%d", gnu_dev_major(device), gnu_dev_minor(device));
+
+ return tryAddDrive(devices, name, device);
+}
+
+bool LinuxAudioCDManager::tryAddPath(DeviceList &devices, const Common::String &path) {
+ struct stat stbuf;
+ if (stat(path.c_str(), &stbuf) < 0)
+ return false;
+
+ return tryAddDrive(devices, stbuf.st_dev);
+}
+
+bool LinuxAudioCDManager::tryAddGamePath(DeviceList &devices) {
+ if (!ConfMan.hasKey("path"))
+ return false;
+
+ return tryAddPath(devices, ConfMan.get("path"));
+}
+
bool LinuxAudioCDManager::loadTOC() {
if (_fd < 0)
return false;
@@ -345,6 +390,14 @@ bool LinuxAudioCDManager::loadTOC() {
return true;
}
+bool LinuxAudioCDManager::hasDevice(const DeviceList &devices, dev_t device) {
+ for (DeviceList::const_iterator it = devices.begin(); it != devices.end(); it++)
+ if (it->device == device)
+ return true;
+
+ return false;
+}
+
AudioCDManager *createLinuxAudioCDManager() {
return new LinuxAudioCDManager();
}