29 #include "../stdafx.h" 31 #include "midifile.hpp" 33 #include "../base_media_base.h" 35 #define Rect OTTD_Rect 36 #define Point OTTD_Point 37 #define WindowClass OTTD_WindowClass 38 #include <QuickTime/QuickTime.h> 43 #include "../safeguards.h" 59 FSCatalogInfo catalogInfo;
63 if (noErr != FSGetCatalogInfo(ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo,
nullptr,
nullptr,
nullptr))
return;
64 if (!(catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) {
65 FileInfo *
const info = (FileInfo *) catalogInfo.finderInfo;
66 if (info->fileType !=
MIDI_TYPE && !(info->finderFlags & kIsAlias)) {
69 e = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
71 DEBUG(driver, 3,
"qtmidi: changed filetype to 'Midi'");
73 DEBUG(driver, 0,
"qtmidi: changing filetype to 'Midi' failed - error %d", e);
97 assert(path !=
nullptr);
98 assert(moov !=
nullptr);
100 DEBUG(driver, 2,
"qtmidi: start loading '%s'...", path);
108 fd = open(path, O_RDONLY, 0);
109 if (fd == -1)
return false;
110 ret = read(fd, magic, 4);
112 if (ret < 4)
return false;
114 DEBUG(driver, 3,
"qtmidi: header is '%.4s'", magic);
115 if (magic[0] !=
'M' || magic[1] !=
'T' || magic[2] !=
'h' || magic[3] !=
'd') {
119 if (noErr != FSPathMakeRef((
const UInt8 *) path, &fsref,
nullptr))
return false;
122 if (noErr != FSGetCatalogInfo(&fsref, kFSCatInfoNone,
nullptr,
nullptr, &fsspec,
nullptr))
return false;
123 if (OpenMovieFile(&fsspec, &refnum, fsRdPerm) != noErr)
return false;
124 DEBUG(driver, 3,
"qtmidi: '%s' successfully opened", path);
126 if (noErr != NewMovieFromFile(moov, refnum, &resid,
nullptr,
127 newMovieActive | newMovieDontAskUnresolvedDataRefs,
nullptr)) {
128 CloseMovieFile(refnum);
131 DEBUG(driver, 3,
"qtmidi: movie container created");
133 CloseMovieFile(refnum);
156 DEBUG(driver, 2,
"qtmidi: initializing Quicktime");
159 (noErr == Gestalt(gestaltQuickTime, &dummy)) &&
160 (noErr == EnterMovies());
181 #define VOLUME ((short)((0x00FF & _quicktime_volume) << 1)) 238 DEBUG(driver, 2,
"qtmidi: stopping driver...");
241 DEBUG(driver, 3,
"qtmidi: stopping not needed, already idle");
268 if (filename.empty())
return;
270 DEBUG(driver, 2,
"qtmidi: trying to play '%s'", filename.c_str());
274 DEBUG(driver, 3,
"qtmidi: previous tune stopped");
279 DEBUG(driver, 3,
"qtmidi: previous tune disposed");
289 DEBUG(driver, 3,
"qtmidi: playing '%s'", filename.c_str());
305 DEBUG(driver, 3,
"qtmidi: stop requested, but already idle");
312 DEBUG(driver, 3,
"qtmidi: player stopped");
332 DEBUG(driver, 2,
"qtmidi: set volume to %u (%hi)", vol,
VOLUME);
Metadata about a music track.
void SetVolume(byte vol) override
Changes the playing volume of the MIDI player.
Base of music playback via the QuickTime driver.
void Stop() override
Stops the MIDI player.
static void InitQuickTimeIfNeeded()
Initialize QuickTime if needed.
const char * Start(const char *const *param) override
Initialized the MIDI player, including QuickTime initialization.
static int _quicktime_state
Current player state.
bool IsSongPlaying() override
Checks whether the player is active.
static Movie _quicktime_movie
Current QuickTime Movie.
void StopSong() override
Stops playing the current song, if the player is active.
static bool LoadMovieForMIDIFile(const char *path, Movie *moov)
Loads a MIDI file and returns it as a QuickTime Movie structure.
static byte _quicktime_volume
Current volume.
#define DEBUG(name, level,...)
Output a line of debugging information.
static std::string GetSMFFile(const MusicSongInfo &song)
Get the name of a Standard MIDI File for a given song.
QTStates
Possible states of the QuickTime music driver.
void PlaySong(const MusicSongInfo &song) override
Starts playing a new song.
static const uint MIDI_TYPE
OSType code for MIDI songs.
static bool _quicktime_started
Flag which has the true value when QuickTime is available and initialized.
static void SetMIDITypeIfNeeded(const FSRef *ref)
Sets the OSType of a given file to 'Midi', but only if it's not already set.
#define VOLUME
Maps OpenTTD volume to QuickTime notion of volume.