diff options
24 files changed, 281 insertions, 267 deletions
| diff --git a/backends/audiocd/audiocd.h b/backends/audiocd/audiocd.h index 598893e315..b3674f2570 100644 --- a/backends/audiocd/audiocd.h +++ b/backends/audiocd/audiocd.h @@ -48,26 +48,31 @@ public:  	};  	/** -	 * @name Emulated playback functions -	 * Engines should call these functions. Not all platforms -	 * support cd playback, and these functions should try to -	 * emulate it. +	 * Initialize the specified CD drive for audio playback. +	 * @return true if the CD drive was inited successfully  	 */ -	//@{ +	virtual bool open() = 0; + +	/** +	 * Close the currently open CD drive +	 */ +	virtual void close() = 0;  	/**  	 * Start audio CD playback -	 * @param track			the track to play. -	 * @param numLoops		how often playback should be repeated (-1 = infinitely often). -	 * @param startFrame	the frame at which playback should start (75 frames = 1 second). -	 * @param duration		the number of frames to play. -	 * @param only_emulate	determines if the track should be emulated only +	 * @param track          the track to play. +	 * @param numLoops       how often playback should be repeated (<=0 means infinitely often). +	 * @param startFrame     the frame at which playback should start (75 frames = 1 second). +	 * @param duration       the number of frames to play. +	 * @param onlyEmulate    determines if the track should be emulated only +	 * @note The @c onlyEmulate parameter is deprecated. +	 * @return @c true if the track started playing, @c false otherwise  	 */ -	virtual void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false) = 0; +	virtual bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false) = 0;  	/**  	 * Get if audio is being played. -	 * @return true if CD or emulated audio is playing +	 * @return true if CD audio is playing  	 */  	virtual bool isPlaying() const = 0; @@ -82,12 +87,12 @@ public:  	virtual void setBalance(int8 balance) = 0;  	/** -	 * Stop CD or emulated audio playback. +	 * Stop audio playback.  	 */  	virtual void stop() = 0;  	/** -	 * Update CD or emulated audio status. +	 * Update audio status.  	 */  	virtual void update() = 0; @@ -96,54 +101,6 @@ public:  	 * @return a Status struct with playback data.  	 */  	virtual Status getStatus() const = 0; - -	//@} - - -	/** -	 * @name Real CD audio methods -	 * These functions should be called from the emulated -	 * ones if they can't emulate the audio playback. -	 */ -	//@{ - -	/** -	 * Initialize the specified CD drive for audio playback. -	 * @return true if the CD drive was inited successfully -	 */ -	virtual bool openCD() = 0; - -	/** -	 * Close the currently open CD drive -	 */ -	virtual void closeCD() = 0; - -	/** -	 * Poll CD status. -	 * @return true if CD audio is playing -	 */ -	virtual bool pollCD() const = 0; - -	/** -	 * Start CD audio playback. -	 * @param track			the track to play. -	 * @param num_loops		how often playback should be repeated (-1 = infinitely often). -	 * @param start_frame	the frame at which playback should start (75 frames = 1 second). -	 * @param duration		the number of frames to play. -	 */ -	virtual void playCD(int track, int num_loops, int start_frame, int duration) = 0; - -	/** -	 * Stop CD audio playback. -	 */ -	virtual void stopCD() = 0; - -	/** -	 * Update CD audio status. -	 */ -	virtual void updateCD() = 0; - -	//@}  };  #endif diff --git a/backends/audiocd/default/default-audiocd.cpp b/backends/audiocd/default/default-audiocd.cpp index 4c08938741..c2ce7cedcc 100644 --- a/backends/audiocd/default/default-audiocd.cpp +++ b/backends/audiocd/default/default-audiocd.cpp @@ -38,7 +38,25 @@ DefaultAudioCDManager::DefaultAudioCDManager() {  	assert(_mixer);  } -void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool only_emulate) { +DefaultAudioCDManager::~DefaultAudioCDManager() { +	// Subclasses should call close as well +	close(); +} + +bool DefaultAudioCDManager::open() { +	// For emulation, opening is always valid +	close(); +	return true; +} + +void DefaultAudioCDManager::close() { +	// Only need to stop for emulation +	stop(); +} + +bool DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) { +	stop(); +  	if (numLoops != 0 || startFrame != 0) {  		_cd.track = track;  		_cd.numLoops = numLoops; @@ -56,9 +74,6 @@ void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int du  		for (int i = 0; !stream && i < 2; ++i)  			stream = Audio::SeekableAudioStream::openStreamFile(trackName[i]); -		// Stop any currently playing emulated track -		_mixer->stopHandle(_handle); -  		if (stream != 0) {  			Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75);  			Audio::Timestamp end = duration ? Audio::Timestamp(0, startFrame + duration, 75) : stream->getLength(); @@ -71,12 +86,11 @@ void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int du  			_emulating = true;  			_mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,  			                        Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance); -		} else { -			_emulating = false; -			if (!only_emulate) -				playCD(track, numLoops, startFrame, duration); +			return true;  		}  	} + +	return false;  }  void DefaultAudioCDManager::stop() { @@ -84,52 +98,32 @@ void DefaultAudioCDManager::stop() {  		// Audio CD emulation  		_mixer->stopHandle(_handle);  		_emulating = false; -	} else { -		// Real Audio CD -		stopCD();  	}  }  bool DefaultAudioCDManager::isPlaying() const { -	if (_emulating) { -		// Audio CD emulation +	// Audio CD emulation +	if (_emulating)  		return _mixer->isSoundHandleActive(_handle); -	} else { -		// Real Audio CD -		return pollCD(); -	} + +	// The default class only handles emulation +	return false;  }  void DefaultAudioCDManager::setVolume(byte volume) {  	_cd.volume = volume; -	if (_emulating) { -		// Audio CD emulation -		if (_mixer->isSoundHandleActive(_handle)) -			_mixer->setChannelVolume(_handle, _cd.volume); -	} else { -		// Real Audio CD - -		// Unfortunately I can't implement this atm -		// since SDL doesn't seem to offer an interface method for this. -		// g_system->setVolumeCD(_cd.volume); -	} +	// Audio CD emulation +	if (_emulating && isPlaying()) +		_mixer->setChannelVolume(_handle, _cd.volume);  }  void DefaultAudioCDManager::setBalance(int8 balance) {  	_cd.balance = balance; -	if (_emulating) { -		// Audio CD emulation -		if (isPlaying()) -			_mixer->setChannelBalance(_handle, _cd.balance); -	} else { -		// Real Audio CD -		// Unfortunately I can't implement this atm -		// since SDL doesn't seem to offer an interface method for this. - -		// g_system->setBalanceCD(_cd.balance); -	} +	// Audio CD emulation +	if (_emulating && isPlaying()) +		_mixer->setChannelBalance(_handle, _cd.balance);  }  void DefaultAudioCDManager::update() { @@ -143,8 +137,6 @@ void DefaultAudioCDManager::update() {  			// or not.  			_emulating = false;  		} -	} else { -		updateCD();  	}  } @@ -154,7 +146,7 @@ DefaultAudioCDManager::Status DefaultAudioCDManager::getStatus() const {  	return info;  } -bool DefaultAudioCDManager::openCD() { +bool DefaultAudioCDManager::openRealCD() {  	Common::String cdrom = ConfMan.get("cdrom");  	// Try to parse it as an int diff --git a/backends/audiocd/default/default-audiocd.h b/backends/audiocd/default/default-audiocd.h index 5c7ee9ee34..e3fbb4b5a1 100644 --- a/backends/audiocd/default/default-audiocd.h +++ b/backends/audiocd/default/default-audiocd.h @@ -36,18 +36,23 @@ class String;  class DefaultAudioCDManager : public AudioCDManager {  public:  	DefaultAudioCDManager(); -	virtual ~DefaultAudioCDManager() {} +	virtual ~DefaultAudioCDManager(); -	void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false); -	void stop(); -	bool isPlaying() const; -	void setVolume(byte volume); -	void setBalance(int8 balance); -	void update(); +	virtual bool open(); +	virtual void close(); +	virtual bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false); +	virtual void stop(); +	virtual bool isPlaying() const; +	virtual void setVolume(byte volume); +	virtual void setBalance(int8 balance); +	virtual void update();  	virtual Status getStatus() const; // Subclasses should override for better status results -	bool openCD(); -	virtual void closeCD() {} +protected: +	/** +	 * Open a CD using the cdrom config variable +	 */ +	bool openRealCD();  	/**  	 * Open a CD using the specified drive index @@ -56,12 +61,6 @@ public:  	 */  	virtual bool openCD(int drive) { return false; } -	virtual void updateCD() {} -	virtual bool pollCD() const { return false; } -	virtual void playCD(int track, int num_loops, int start_frame, int duration) {} -	virtual void stopCD() {} - -protected:  	/**  	 * Open a CD from a specific drive  	 * @param drive The name of the drive/path diff --git a/backends/audiocd/linux/linux-audiocd.cpp b/backends/audiocd/linux/linux-audiocd.cpp index fe3ae1e58b..a835ade218 100644 --- a/backends/audiocd/linux/linux-audiocd.cpp +++ b/backends/audiocd/linux/linux-audiocd.cpp @@ -252,11 +252,12 @@ public:  	LinuxAudioCDManager();  	~LinuxAudioCDManager(); -	bool openCD(int drive); -	void closeCD(); -	void playCD(int track, int numLoops, int startFrame, int duration); +	bool open(); +	void close(); +	bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);  protected: +	bool openCD(int drive);  	bool openCD(const Common::String &drive);  private: @@ -301,22 +302,40 @@ LinuxAudioCDManager::LinuxAudioCDManager() {  }  LinuxAudioCDManager::~LinuxAudioCDManager() { -	closeCD(); +	close();  } -bool LinuxAudioCDManager::openCD(int drive) { -	closeCD(); +bool LinuxAudioCDManager::open() { +	close(); + +	if (openRealCD()) +		return true; + +	return DefaultAudioCDManager::open(); +} + +void LinuxAudioCDManager::close() { +	DefaultAudioCDManager::close(); + +	if (_fd < 0) +		return; + +	::close(_fd); +	memset(&_tocHeader, 0, sizeof(_tocHeader)); +	_tocEntries.clear(); +} +bool LinuxAudioCDManager::openCD(int drive) {  	DeviceList devices = scanDevices();  	if (drive >= (int)devices.size())  		return false; -	_fd = open(devices[drive].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;  	if (!loadTOC()) { -		closeCD(); +		close();  		return false;  	} @@ -328,44 +347,39 @@ bool LinuxAudioCDManager::openCD(const Common::String &drive) {  	if (!tryAddDrive(devices, drive) && !tryAddPath(devices, drive))  		return false; -	_fd = open(devices[0].name.c_str(), O_RDONLY | O_NONBLOCK, 0); +	_fd = ::open(devices[0].name.c_str(), O_RDONLY | O_NONBLOCK, 0);  	if (_fd < 0)  		return false;  	if (!loadTOC()) { -		closeCD(); +		close();  		return false;  	}  	return true;  } -void LinuxAudioCDManager::closeCD() { -	if (_fd < 0) -		return; - -	stop(); -	close(_fd); -	memset(&_tocHeader, 0, sizeof(_tocHeader)); -	_tocEntries.clear(); -} +bool LinuxAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) { +	// Prefer emulation +	if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate)) +		return true; -void LinuxAudioCDManager::playCD(int track, int numLoops, int startFrame, int duration) { -	// Stop any previous track -	stop(); +	// If we're set to only emulate, or have no CD drive, return here +	if (onlyEmulate || _fd < 0) +		return false;  	// HACK: For now, just assume that track number is right  	// That only works because ScummVM uses the wrong track number anyway	  	if (track >= (int)_tocEntries.size() - 1) {  		warning("No such track %d", track); -		return; +		return false;  	}  	// Bail if the track isn't an audio track  	if ((_tocEntries[track].cdte_ctrl & 0x04) != 0) {  		warning("Track %d is not audio", track); -		return; +		return false;  	}  	// Create the AudioStream and play it @@ -388,6 +402,8 @@ void LinuxAudioCDManager::playCD(int track, int numLoops, int startFrame, int du  		_cd.balance,  		DisposeAfterUse::YES,  		true); + +	return true;  }  LinuxAudioCDManager::DeviceList LinuxAudioCDManager::scanDevices() { @@ -421,13 +437,13 @@ bool LinuxAudioCDManager::tryAddDrive(DeviceList &devices, const Common::String  		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); +	int fd = ::open(drive.c_str(), O_RDONLY | O_NONBLOCK, 0);  	if (fd >= 0) {  		cdrom_subchnl info;  		info.cdsc_format = CDROM_MSF;  		bool isCD = ioctl(fd, CDROMSUBCHNL, &info) == 0 || isTrayEmpty(errno); -		close(fd); +		::close(fd);  		if (isCD) {  			devices.push_back(Device(drive, device));  			return true; diff --git a/backends/audiocd/macosx/macosx-audiocd.cpp b/backends/audiocd/macosx/macosx-audiocd.cpp index 76bae95500..07d8d31f26 100644 --- a/backends/audiocd/macosx/macosx-audiocd.cpp +++ b/backends/audiocd/macosx/macosx-audiocd.cpp @@ -47,8 +47,9 @@ public:  	MacOSXAudioCDManager() {}  	~MacOSXAudioCDManager(); -	void playCD(int track, int num_loops, int start_frame, int duration); -	void closeCD(); +	bool open(); +	void close(); +	bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);  protected:  	bool openCD(int drive); @@ -74,7 +75,16 @@ private:  };  MacOSXAudioCDManager::~MacOSXAudioCDManager() { -	closeCD(); +	close(); +} + +bool MacOSXAudioCDManager::open() { +	close(); + +	if (openRealCD()) +		return true; + +	return DefaultAudioCDManager::open();  }  /** @@ -95,8 +105,6 @@ static int findBaseDiskNumber(const Common::String &diskName) {  }  bool MacOSXAudioCDManager::openCD(int drive) { -	closeCD(); -  	DriveList allDrives = detectAllDrives();  	if (allDrives.empty())  		return false; @@ -137,8 +145,6 @@ bool MacOSXAudioCDManager::openCD(int drive) {  }  bool MacOSXAudioCDManager::openCD(const Common::String &drive) { -	closeCD(); -  	DriveList drives = detectAllDrives();  	for (uint32 i = 0; i < drives.size(); i++) { @@ -154,8 +160,8 @@ bool MacOSXAudioCDManager::openCD(const Common::String &drive) {  	return false;  } -void MacOSXAudioCDManager::closeCD() { -	stop(); +void MacOSXAudioCDManager::close() { +	DefaultAudioCDManager::close();  	_trackMap.clear();  } @@ -178,9 +184,17 @@ MacOSXAudioCDManager::DriveList MacOSXAudioCDManager::detectAllDrives() {  	return drives;  } -void MacOSXAudioCDManager::playCD(int track, int numLoops, int startFrame, int duration) { -	if (!_trackMap.contains(track) || (!numLoops && !startFrame)) -		return; +bool MacOSXAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) { +	// Prefer emulation +	if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate)) +		return true; + +	// If we're set to only emulate, or have no CD drive, return here +	if (onlyEmulate || !_trackMap.contains(track)) +		return false; + +	if (!numLoops && !startFrame) +		return false;  	// Now load the AIFF track from the name  	Common::String fileName = _trackMap[track]; @@ -188,19 +202,19 @@ void MacOSXAudioCDManager::playCD(int track, int numLoops, int startFrame, int d  	if (!stream) {  		warning("Failed to open track '%s'", fileName.c_str()); -		return; +		return false;  	}  	Audio::AudioStream *audioStream = Audio::makeAIFFStream(stream, DisposeAfterUse::YES);  	if (!audioStream) {  		warning("Track '%s' is not an AIFF track", fileName.c_str()); -		return; +		return false;  	}  	Audio::SeekableAudioStream *seekStream = dynamic_cast<Audio::SeekableAudioStream *>(audioStream);  	if (!seekStream) {  		warning("Track '%s' is not seekable", fileName.c_str()); -		return; +		return false;  	}  	Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75); @@ -211,6 +225,7 @@ void MacOSXAudioCDManager::playCD(int track, int numLoops, int startFrame, int d  	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,  			Audio::makeLoopingAudioStream(seekStream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance); +	return true;  }  bool MacOSXAudioCDManager::findTrackNames(const Common::String &drivePath) { diff --git a/backends/audiocd/sdl/sdl-audiocd.cpp b/backends/audiocd/sdl/sdl-audiocd.cpp index d745f29a12..3558fb5671 100644 --- a/backends/audiocd/sdl/sdl-audiocd.cpp +++ b/backends/audiocd/sdl/sdl-audiocd.cpp @@ -43,7 +43,16 @@ SdlAudioCDManager::SdlAudioCDManager()  }  SdlAudioCDManager::~SdlAudioCDManager() { -	closeCD(); +	close(); +} + +bool SdlAudioCDManager::open() { +	close(); + +	if (openRealCD()) +		return true; + +	return DefaultAudioCDManager::open();  }  bool SdlAudioCDManager::openCD(int drive) { @@ -64,7 +73,9 @@ bool SdlAudioCDManager::openCD(int drive) {  	return (_cdrom != NULL);  } -void SdlAudioCDManager::closeCD() { +void SdlAudioCDManager::close() { +	DefaultAudioCDManager::close(); +  	if (_cdrom) {                  SDL_CDStop(_cdrom);                  SDL_CDClose(_cdrom); @@ -72,44 +83,59 @@ void SdlAudioCDManager::closeCD() {          }  } -void SdlAudioCDManager::stopCD() { +void SdlAudioCDManager::stop() { +	DefaultAudioCDManager::stop(); +  	// Stop CD Audio in 1/10th of a second  	_cdStopTime = SDL_GetTicks() + 100;  	_cdNumLoops = 0;  } -void SdlAudioCDManager::playCD(int track, int num_loops, int start_frame, int duration) { -	if (!num_loops && !start_frame) -		return; +bool SdlAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) { +	// Prefer emulation +	if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate)) +		return true; -	if (!_cdrom) -		return; +	// If we're set to only emulate, or have no CD, return here +	if (onlyEmulate || !_cdrom) +		return false; + +	if (!numLoops && !startFrame) +		return false; +	// FIXME: Explain this.  	if (duration > 0)  		duration += 5;  	_cdTrack = track; -	_cdNumLoops = num_loops; -	_cdStartFrame = start_frame; +	_cdNumLoops = numLoops; +	_cdStartFrame = startFrame;  	SDL_CDStatus(_cdrom); -	if (start_frame == 0 && duration == 0) +	if (startFrame == 0 && duration == 0)  		SDL_CDPlayTracks(_cdrom, track, 0, 1, 0);  	else -		SDL_CDPlayTracks(_cdrom, track, start_frame, 0, duration); +		SDL_CDPlayTracks(_cdrom, track, startFrame, 0, duration);  	_cdDuration = duration;  	_cdStopTime = 0;  	_cdEndTime = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS; + +	return true;  } -bool SdlAudioCDManager::pollCD() const { +bool SdlAudioCDManager::isPlaying() const { +	if (DefaultAudioCDManager::isPlaying()) +		return true; +  	if (!_cdrom)  		return false;  	return (_cdNumLoops != 0 && (SDL_GetTicks() < _cdEndTime || SDL_CDStatus(_cdrom) == CD_PLAYING));  } -void SdlAudioCDManager::updateCD() { +void SdlAudioCDManager::update() { +	DefaultAudioCDManager::update(); +  	if (!_cdrom)  		return; diff --git a/backends/audiocd/sdl/sdl-audiocd.h b/backends/audiocd/sdl/sdl-audiocd.h index 4ece8ddfe7..91895dac99 100644 --- a/backends/audiocd/sdl/sdl-audiocd.h +++ b/backends/audiocd/sdl/sdl-audiocd.h @@ -37,13 +37,15 @@ public:  	SdlAudioCDManager();  	virtual ~SdlAudioCDManager(); +	virtual bool open(); +	virtual void close(); +	virtual bool play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false); +	virtual void stop(); +	virtual bool isPlaying() const; +	virtual void update(); +  protected:  	virtual bool openCD(int drive); -	virtual void closeCD(); -	virtual void updateCD(); -	virtual bool pollCD() const; -	virtual void playCD(int track, int num_loops, int start_frame, int duration); -	virtual void stopCD();  	SDL_CD *_cdrom;  	int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration; diff --git a/backends/audiocd/win32/win32-audiocd.cpp b/backends/audiocd/win32/win32-audiocd.cpp index 5de7c7b2e6..e3fdcf6477 100644 --- a/backends/audiocd/win32/win32-audiocd.cpp +++ b/backends/audiocd/win32/win32-audiocd.cpp @@ -263,11 +263,12 @@ public:  	Win32AudioCDManager();  	~Win32AudioCDManager(); -	bool openCD(int drive); -	void closeCD(); -	void playCD(int track, int numLoops, int startFrame, int duration); +	bool open(); +	void close(); +	void play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false);  protected: +	bool openCD(int drive);  	bool openCD(const Common::String &drive);  private: @@ -288,12 +289,19 @@ Win32AudioCDManager::Win32AudioCDManager() {  }  Win32AudioCDManager::~Win32AudioCDManager() { -	closeCD(); +	close();  } -bool Win32AudioCDManager::openCD(int drive) { -	closeCD(); +bool Win32AudioCDManager::open() { +	close(); + +	if (openRealCD()) +		return true; +	return DefaultAudioCDManager::open(); +} + +bool Win32AudioCDManager::openCD(int drive) {  	// Fetch the drive list  	DriveList drives = detectDrives();  	if (drive >= (int)drives.size()) @@ -310,11 +318,11 @@ bool Win32AudioCDManager::openCD(int drive) {  	}  	if (!loadTOC()) { -		closeCD(); +		close();  		return false;  	} -	return false; +	return true;  }  bool Win32AudioCDManager::openCD(const Common::String &drive) { @@ -341,16 +349,15 @@ bool Win32AudioCDManager::openCD(const Common::String &drive) {  	}  	if (!loadTOC()) { -		closeCD(); +		close();  		return false;  	}  	return true;  } -void Win32AudioCDManager::closeCD() { -	// Stop any previous track -	stop(); +void Win32AudioCDManager::close() { +	DefaultAudioCDManager::close();  	if (_driveHandle != INVALID_HANDLE_VALUE) {  		CloseHandle(_driveHandle); @@ -361,22 +368,27 @@ void Win32AudioCDManager::closeCD() {  	_tocEntries.clear();  } -void Win32AudioCDManager::playCD(int track, int numLoops, int startFrame, int duration) { -	// Stop any previous track -	stop(); +bool Win32AudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) { +	// Prefer emulation +	if (DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate)) +		return true; + +	// If we're set to only emulate, or have no CD drive, return here +	if (onlyEmulate || _driveHandle == INVALID_HANDLE_VALUE) +		return false;  	// HACK: For now, just assume that track number is right  	// That only works because ScummVM uses the wrong track number anyway	  	if (track >= (int)_tocEntries.size() - 1) {  		warning("No such track %d", track); -		return; +		return false;  	}  	// Bail if the track isn't an audio track  	if ((_tocEntries[track].Control & 0x04) != 0) {  		warning("Track %d is not audio", track); -		return; +		return false;  	}  	// Create the AudioStream and play it @@ -399,6 +411,7 @@ void Win32AudioCDManager::playCD(int track, int numLoops, int startFrame, int du  		_cd.balance,  		DisposeAfterUse::YES,  		true); +	return true;  }  bool Win32AudioCDManager::loadTOC() { diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h index b49080324d..b567142b8f 100644 --- a/backends/platform/dc/dc.h +++ b/backends/platform/dc/dc.h @@ -57,24 +57,16 @@ class DCHardware {  };  class DCCDManager : public DefaultAudioCDManager { -  // Initialize the specified CD drive for audio playback. -  bool openCD(); - -	// Close the open CD drive -	void closeCD() {} - -  // Poll cdrom status -  // Returns true if cd audio is playing -  bool pollCD(); - -  // Play cdrom audio track -  void playCD(int track, int num_loops, int start_frame, int duration); +public: +	// Poll cdrom status +	// Returns true if cd audio is playing +	bool isPlaying() const; -  // Stop cdrom audio track -  void stopCD(); +	// Play cdrom audio track +	void play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate = false); -  // Update cdrom audio status -  void updateCD(); +	// Stop cdrom audio track +	void stop();  };  class OSystem_Dreamcast : private DCHardware, public EventsBaseBackend, public PaletteManager, public FilesystemFactory diff --git a/backends/platform/dc/dcmain.cpp b/backends/platform/dc/dcmain.cpp index aa8430afc8..bd66b81b35 100644 --- a/backends/platform/dc/dcmain.cpp +++ b/backends/platform/dc/dcmain.cpp @@ -90,43 +90,45 @@ static bool find_track(int track, int &first_sec, int &last_sec)    return false;  } -void DCCDManager::playCD(int track, int num_loops, int start_frame, int duration) -{ -  int first_sec, last_sec; +void DCCDManager::play(int track, int numLoops, int startFrame, int duration, bool onlyEmulate) { +	DefaultAudioCDManager::play(track, numLoops, startFrame, duration, onlyEmulate); + +	// If we're playing now, are set to only emulate, return here +	if (isPlaying() || onlyEmulate) +		return; + +	int firstSec, lastSec;  #if 1 -  if (num_loops) -    --num_loops; +	if (numLoops) +		--numLoops;  #endif -  if (num_loops>14) num_loops=14; -  else if (num_loops<0) num_loops=15; // infinity -  if (!find_track(track, first_sec, last_sec)) -    return; -  if (duration) -    last_sec = first_sec + start_frame + duration; -  first_sec += start_frame; -  play_cdda_sectors(first_sec, last_sec, num_loops); -} -void DCCDManager::stopCD() -{ -  stop_cdda(); -} +	if (numLoops > 14) +		numLoops = 14; +	else if (numLoops < 0) +		num_loops = 15; // infinity -bool DCCDManager::pollCD() -{ -  extern int getCdState(); -  return getCdState() == 3; +	if (!find_track(track, firstSec, lastSec)) +		return; + +	if (duration) +		lastSec = firstSec + startFrame + duration; + + 	firstSec += startFrame; +	play_cdda_sectors(firstSec, lastSec, numLoops);  } -void DCCDManager::updateCD() -{ -  // Dummy.  The CD drive takes care of itself. +void DCCDManager::stop() { +	DefaultAudioCDManager::stop(); +	stop_cdda();  } -bool DCCDManager::openCD() -{ -  // Dummy. -  return true; +bool DCCDManager::isPlaying() const { +	if (DefaultAudioCDManager::isPlaying()) +		return true; + +	extern int getCdState(); +	return getCdState() == 3;  }  void OSystem_Dreamcast::setWindowCaption(const char *caption) diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index 95bcc68234..5240cdd771 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -427,7 +427,7 @@ void AGOSEngine::delay(uint amount) {  	uint32 cur = start;  	uint this_delay, vgaPeriod; -	_system->getAudioCDManager()->updateCD(); +	_system->getAudioCDManager()->update();  	_debugger->onFrame(); @@ -538,7 +538,7 @@ void AGOSEngine::delay(uint amount) {  		if (_leftButton == 1)  			_leftButtonCount++; -		_system->getAudioCDManager()->updateCD(); +		_system->getAudioCDManager()->update();  		_system->updateScreen(); diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp index e52fc464d5..19a2d8a82e 100644 --- a/engines/cine/main_loop.cpp +++ b/engines/cine/main_loop.cpp @@ -222,7 +222,7 @@ void manageEvents() {  	mouseData.left = mouseLeft;  	mouseData.right = mouseRight; -	g_system->getAudioCDManager()->updateCD(); +	g_system->getAudioCDManager()->update();  }  void getMouseData(uint16 param, uint16 *pButton, uint16 *pX, uint16 *pY) { diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp index 0e7da2e2bc..a8b4c085ff 100644 --- a/engines/cine/sound.cpp +++ b/engines/cine/sound.cpp @@ -942,7 +942,7 @@ PCSound::PCSound(Audio::Mixer *mixer, CineEngine *vm)  	// Ensure the CD is open  	if (_vm->getGameType() == GType_FW && (_vm->getFeatures() & GF_CD)) -		g_system->getAudioCDManager()->openCD(); +		g_system->getAudioCDManager()->open();  }  PCSound::~PCSound() { diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp index 1a7659fc85..9ac9031fb7 100644 --- a/engines/drascula/drascula.cpp +++ b/engines/drascula/drascula.cpp @@ -183,7 +183,7 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam  	const Common::FSNode gameDataDir(ConfMan.get("path"));  	SearchMan.addSubDirectoryMatching(gameDataDir, "audio"); -	_system->getAudioCDManager()->openCD(); +	_system->getAudioCDManager()->open();  	_lang = kEnglish; diff --git a/engines/drascula/sound.cpp b/engines/drascula/sound.cpp index 148dae76f5..c576b37660 100644 --- a/engines/drascula/sound.cpp +++ b/engines/drascula/sound.cpp @@ -133,7 +133,7 @@ void DrasculaEngine::stopMusic() {  }  void DrasculaEngine::updateMusic() { -	_system->getAudioCDManager()->updateCD(); +	_system->getAudioCDManager()->update();  }  int DrasculaEngine::musicStatus() { diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index df2d804bd2..d995f26d9f 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -296,7 +296,7 @@ Common::Error GobEngine::run() {  	if (isCD())  		checkCD(); -	_system->getAudioCDManager()->openCD(); +	_system->getAudioCDManager()->open();  	_global->_debugFlag = 1;  	_video->_doRangeClamp = true; diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp index a25bf0008b..bbc290eccf 100644 --- a/engines/groovie/groovie.cpp +++ b/engines/groovie/groovie.cpp @@ -257,7 +257,7 @@ Common::Error GroovieEngine::run() {  	// the same cd  	if (getPlatform() != Common::kPlatformIOS) {  		checkCD(); -		_system->getAudioCDManager()->openCD(); +		_system->getAudioCDManager()->open();  	}  	while (!shouldQuit()) { diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index b269cb4d67..646f908b94 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -69,13 +69,13 @@ bool SoundTowns::init() {  	_player->driver()->setOutputVolume(1, 118, 118);  	// Initialize CD for audio -	g_system->getAudioCDManager()->openCD(); +	g_system->getAudioCDManager()->open();  	return true;  }  void SoundTowns::process() { -	g_system->getAudioCDManager()->updateCD(); +	g_system->getAudioCDManager()->update();  }  void SoundTowns::playTrack(uint8 track) { @@ -98,7 +98,7 @@ void SoundTowns::playTrack(uint8 track) {  	if (_musicEnabled == 2 && trackNum != -1) {  		_player->driver()->setOutputVolume(1, 118, 118);  		g_system->getAudioCDManager()->play(trackNum + 1, loop ? -1 : 1, 0, 0); -		g_system->getAudioCDManager()->updateCD(); +		g_system->getAudioCDManager()->update();  		_cdaPlaying = true;  	} else if (_musicEnabled) {  		playEuphonyTrack(READ_LE_UINT32(&res()->cdaTable[tTableIndex]), loop); @@ -111,7 +111,7 @@ void SoundTowns::playTrack(uint8 track) {  void SoundTowns::haltTrack() {  	_lastTrack = -1;  	g_system->getAudioCDManager()->stop(); -	g_system->getAudioCDManager()->updateCD(); +	g_system->getAudioCDManager()->update();  	_cdaPlaying = false;  	for (int i = 0; i < 6; i++) @@ -412,7 +412,7 @@ bool SoundPC98::init() {  	updateVolumeSettings();  	// Initialize CD for audio -	g_system->getAudioCDManager()->openCD(); +	g_system->getAudioCDManager()->open();  	return reslt;  } @@ -478,7 +478,7 @@ void SoundPC98::playTrack(uint8 track) {  void SoundPC98::haltTrack() {  	_lastTrack = -1;  	g_system->getAudioCDManager()->stop(); -	g_system->getAudioCDManager()->updateCD(); +	g_system->getAudioCDManager()->update();  	_driver->reset();  } @@ -538,7 +538,7 @@ bool SoundTownsPC98_v2::init() {  				_vm->checkCD();  		// Initialize CD for audio -		bool hasRealCD = g_system->getAudioCDManager()->openCD(); +		bool hasRealCD = g_system->getAudioCDManager()->open();  		// FIXME: While checking for 'track1.XXX(X)' looks like  		// a good idea, we should definitely not be doing this @@ -591,7 +591,7 @@ void SoundTownsPC98_v2::loadSoundFile(Common::String file) {  }  void SoundTownsPC98_v2::process() { -	g_system->getAudioCDManager()->updateCD(); +	g_system->getAudioCDManager()->update();  }  void SoundTownsPC98_v2::playTrack(uint8 track) { @@ -621,7 +621,7 @@ void SoundTownsPC98_v2::playTrack(uint8 track) {  	if (_musicEnabled == 2 && trackNum != -1) {  		g_system->getAudioCDManager()->play(trackNum+1, _driver->looping() ? -1 : 1, 0, 0); -		g_system->getAudioCDManager()->updateCD(); +		g_system->getAudioCDManager()->update();  	} else if (_musicEnabled) {  		_driver->cont();  	} @@ -632,7 +632,7 @@ void SoundTownsPC98_v2::playTrack(uint8 track) {  void SoundTownsPC98_v2::haltTrack() {  	_lastTrack = -1;  	g_system->getAudioCDManager()->stop(); -	g_system->getAudioCDManager()->updateCD(); +	g_system->getAudioCDManager()->update();  	_driver->reset();  } diff --git a/engines/made/made.cpp b/engines/made/made.cpp index 57130e277f..f1539297ee 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -67,7 +67,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng  	_console = new MadeConsole(this); -	_system->getAudioCDManager()->openCD(); +	_system->getAudioCDManager()->open();  	_pmvPlayer = new PmvPlayer(this, _mixer);  	_res = new ResourceReader(); @@ -268,7 +268,7 @@ void MadeEngine::handleEvents() {  		}  	} -	_system->getAudioCDManager()->updateCD(); +	_system->getAudioCDManager()->update();  } diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp index 5e5e8b0466..a74bfa245f 100644 --- a/engines/sci/sound/audio.cpp +++ b/engines/sci/sound/audio.cpp @@ -514,7 +514,7 @@ void AudioPlayer::stopSoundSync() {  int AudioPlayer::audioCdPlay(int track, int start, int duration) {  	if (!_initCD) {  		// Initialize CD mode if we haven't already -		g_system->getAudioCDManager()->openCD(); +		g_system->getAudioCDManager()->open();  		_initCD = true;  	} diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 680bdb2463..d9148ed300 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1275,7 +1275,7 @@ void ScummEngine::setupScumm() {  	// On some systems it's not safe to run CD audio games from the CD.  	if (_game.features & GF_AUDIOTRACKS && !Common::File::exists("CDDA.SOU")) {  		checkCD(); -		_system->getAudioCDManager()->openCD(); +		_system->getAudioCDManager()->open();  	}  	// Create the sound manager diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index 4d70ee8482..404bdd022c 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -1093,7 +1093,7 @@ int Sound::pollCD() const {  void Sound::updateCD() {  	if (!_isLoomSteam) -		g_system->getAudioCDManager()->updateCD(); +		g_system->getAudioCDManager()->update();  }  AudioCDManager::Status Sound::getCDStatus() { diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp index f5d9f72cc3..4dc785754c 100644 --- a/engines/teenagent/teenagent.cpp +++ b/engines/teenagent/teenagent.cpp @@ -547,7 +547,7 @@ Common::Error TeenAgentEngine::run() {  	// Initialize CD audio  	if (_gameDescription->flags & ADGF_CD) -		g_system->getAudioCDManager()->openCD(); +		g_system->getAudioCDManager()->open();  	setMusic(1);  	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, music, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, false); diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp index 782dd7ae48..1b733a08ba 100644 --- a/engines/tinsel/tinsel.cpp +++ b/engines/tinsel/tinsel.cpp @@ -841,7 +841,7 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)  		if (!scumm_stricmp(g->gameid, gameid))  			_gameId = g->id; -	_system->getAudioCDManager()->openCD(); +	_system->getAudioCDManager()->open();  	_mousePos.x = 0;  	_mousePos.y = 0; @@ -973,7 +973,7 @@ Common::Error TinselEngine::run() {  		// Check for time to do next game cycle  		if ((g_system->getMillis() > timerVal + GAME_FRAME_DELAY)) {  			timerVal = g_system->getMillis(); -			_system->getAudioCDManager()->updateCD(); +			_system->getAudioCDManager()->update();  			NextGameCycle();  		} | 
