File diff r7169:b87d36998a2d → r7170:38b143754b40
src/music/qtmidi.cpp
Show inline comments
 
@@ -38,24 +38,26 @@
 
#undef   OTTD_Random
 
#undef   WindowClass
 
#undef   SL_ERROR
 
#undef   bool
 

	
 
#include <assert.h>
 
#include <unistd.h>
 
#include <fcntl.h>
 

	
 
// we need to include debug.h after CoreServices because defining DEBUG will break CoreServices in OSX 10.2
 
#include "../debug.h"
 

	
 
static FMusicDriver_QtMidi iFMusicDriver_QtMidi;
 

	
 

	
 
enum {
 
	midiType = 'Midi' /**< OSType code for MIDI songs. */
 
};
 

	
 

	
 
/**
 
 * Converts a Unix-like pathname to a @c FSSpec structure which may be
 
 * used with functions from several MacOS X frameworks (Carbon, QuickTime,
 
 * etc). The pointed file or directory must exist.
 
 *
 
 * @param *path A string containing a Unix-like path.
 
@@ -198,48 +200,45 @@ enum {
 

	
 
static Movie _quicktime_movie;                  /**< Current QuickTime @c Movie. */
 
static byte  _quicktime_volume = 127;           /**< Current volume. */
 
static int   _quicktime_state  = QT_STATE_IDLE; /**< Current player state. */
 

	
 

	
 
/**
 
 * Maps OpenTTD volume to QuickTime notion of volume.
 
 */
 
#define VOLUME  ((short)((0x00FF & _quicktime_volume) << 1))
 

	
 

	
 
static void StopSong();
 

	
 

	
 
/**
 
 * Initialized the MIDI player, including QuickTime initialization.
 
 *
 
 * @todo Give better error messages by inspecting error codes returned by
 
 * @c Gestalt() and @c EnterMovies(). Needs changes in
 
 * #InitQuickTimeIfNeeded.
 
 */
 
static const char* StartDriver(const char * const *parm)
 
const char *MusicDriver_QtMidi::Start(const char * const *parm)
 
{
 
	InitQuickTimeIfNeeded();
 
	return (_quicktime_started) ? NULL : "can't initialize QuickTime";
 
}
 

	
 

	
 
/**
 
 * Checks wether the player is active.
 
 *
 
 * This function is called at regular intervals from OpenTTD's main loop, so
 
 * we call @c MoviesTask() from here to let QuickTime do its work.
 
 */
 
static bool SongIsPlaying()
 
bool MusicDriver_QtMidi::IsSongPlaying()
 
{
 
	if (!_quicktime_started) return true;
 

	
 
	switch (_quicktime_state) {
 
		case QT_STATE_IDLE:
 
		case QT_STATE_STOP:
 
			/* Do nothing. */
 
			break;
 
		case QT_STATE_PLAY:
 
			MoviesTask(_quicktime_movie, 0);
 
			/* Check wether movie ended. */
 
			if (IsMovieDone(_quicktime_movie) ||
 
@@ -249,25 +248,25 @@ static bool SongIsPlaying()
 
	}
 

	
 
	return _quicktime_state == QT_STATE_PLAY;
 
}
 

	
 

	
 
/**
 
 * Stops the MIDI player.
 
 *
 
 * Stops playing and frees any used resources before returning. As it
 
 * deinitilizes QuickTime, the #_quicktime_started flag is set to @c false.
 
 */
 
static void StopDriver()
 
void MusicDriver_QtMidi::Stop()
 
{
 
	if (!_quicktime_started) return;
 

	
 
	DEBUG(driver, 2, "qtmidi: stopping driver...");
 
	switch (_quicktime_state) {
 
		case QT_STATE_IDLE:
 
			DEBUG(driver, 3, "qtmidi: stopping not needed, already idle");
 
			/* Do nothing. */
 
			break;
 
		case QT_STATE_PLAY:
 
			StopSong();
 
		case QT_STATE_STOP:
 
@@ -275,25 +274,25 @@ static void StopDriver()
 
	}
 

	
 
	ExitMovies();
 
	_quicktime_started = false;
 
}
 

	
 

	
 
/**
 
 * Starts playing a new song.
 
 *
 
 * @param filename Path to a MIDI file.
 
 */
 
static void PlaySong(const char *filename)
 
void MusicDriver_QtMidi::PlaySong(const char *filename)
 
{
 
	if (!_quicktime_started) return;
 

	
 
	DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename);
 
	switch (_quicktime_state) {
 
		case QT_STATE_PLAY:
 
			StopSong();
 
			DEBUG(driver, 3, "qtmidi: previous tune stopped");
 
			/* XXX Fall-through -- no break needed. */
 
		case QT_STATE_STOP:
 
			DisposeMovie(_quicktime_movie);
 
			DEBUG(driver, 3, "qtmidi: previous tune disposed");
 
@@ -303,25 +302,25 @@ static void PlaySong(const char *filenam
 
			LoadMovieForMIDIFile(filename, &_quicktime_movie);
 
			SetMovieVolume(_quicktime_movie, VOLUME);
 
			StartMovie(_quicktime_movie);
 
			_quicktime_state = QT_STATE_PLAY;
 
	}
 
	DEBUG(driver, 3, "qtmidi: playing '%s'", filename);
 
}
 

	
 

	
 
/**
 
 * Stops playing the current song, if the player is active.
 
 */
 
static void StopSong()
 
void MusicDriver_QtMidi::StopSong()
 
{
 
	if (!_quicktime_started) return;
 

	
 
	switch (_quicktime_state) {
 
		case QT_STATE_IDLE:
 
			/* XXX Fall-through -- no break needed. */
 
		case QT_STATE_STOP:
 
			DEBUG(driver, 3, "qtmidi: stop requested, but already idle");
 
			/* Do nothing. */
 
			break;
 
		case QT_STATE_PLAY:
 
			StopMovie(_quicktime_movie);
 
@@ -331,41 +330,29 @@ static void StopSong()
 
}
 

	
 

	
 
/**
 
 * Changes the playing volume of the MIDI player.
 
 *
 
 * As QuickTime controls volume in a per-movie basis, the desired volume is
 
 * stored in #_quicktime_volume, and the volume is set here using the
 
 * #VOLUME macro, @b and when loading new song in #PlaySong.
 
 *
 
 * @param vol The desired volume, range of the value is @c 0-127
 
 */
 
static void SetVolume(byte vol)
 
void MusicDriver_QtMidi::SetVolume(byte vol)
 
{
 
	if (!_quicktime_started) return;
 

	
 
	_quicktime_volume = vol;
 

	
 
	DEBUG(driver, 2, "qtmidi: set volume to %u (%hi)", vol, VOLUME);
 
	switch (_quicktime_state) {
 
		case QT_STATE_IDLE:
 
			/* Do nothing. */
 
			break;
 
		case QT_STATE_PLAY:
 
		case QT_STATE_STOP:
 
			SetMovieVolume(_quicktime_movie, VOLUME);
 
	}
 
}
 

	
 

	
 
/**
 
 * Table of callbacks that implement the QuickTime MIDI player.
 
 */
 
const HalMusicDriver _qtime_music_driver = {
 
	StartDriver,
 
	StopDriver,
 
	PlaySong,
 
	StopSong,
 
	SongIsPlaying,
 
	SetVolume,
 
};