31 #include "../stdafx.h" 33 #include "midifile.hpp" 35 #include "../base_media_base.h" 37 #define Rect OTTD_Rect 38 #define Point OTTD_Point 39 #define WindowClass OTTD_WindowClass 40 #include <QuickTime/QuickTime.h> 45 #include "../safeguards.h" 61 FSCatalogInfo catalogInfo;
65 if (noErr != FSGetCatalogInfo(ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo,
nullptr,
nullptr,
nullptr))
return;
66 if (!(catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) {
67 FileInfo *
const info = (FileInfo *) catalogInfo.finderInfo;
68 if (info->fileType !=
MIDI_TYPE && !(info->finderFlags & kIsAlias)) {
71 e = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
73 DEBUG(driver, 3,
"qtmidi: changed filetype to 'Midi'");
75 DEBUG(driver, 0,
"qtmidi: changing filetype to 'Midi' failed - error %d", e);
99 assert(path !=
nullptr);
100 assert(moov !=
nullptr);
102 DEBUG(driver, 2,
"qtmidi: start loading '%s'...", path);
110 fd = open(path, O_RDONLY, 0);
111 if (fd == -1)
return false;
112 ret = read(fd, magic, 4);
114 if (ret < 4)
return false;
116 DEBUG(driver, 3,
"qtmidi: header is '%.4s'", magic);
117 if (magic[0] !=
'M' || magic[1] !=
'T' || magic[2] !=
'h' || magic[3] !=
'd') {
121 if (noErr != FSPathMakeRef((
const UInt8 *) path, &fsref,
nullptr))
return false;
124 if (noErr != FSGetCatalogInfo(&fsref, kFSCatInfoNone,
nullptr,
nullptr, &fsspec,
nullptr))
return false;
125 if (OpenMovieFile(&fsspec, &refnum, fsRdPerm) != noErr)
return false;
126 DEBUG(driver, 3,
"qtmidi: '%s' successfully opened", path);
128 if (noErr != NewMovieFromFile(moov, refnum, &resid,
nullptr,
129 newMovieActive | newMovieDontAskUnresolvedDataRefs,
nullptr)) {
130 CloseMovieFile(refnum);
133 DEBUG(driver, 3,
"qtmidi: movie container created");
135 CloseMovieFile(refnum);
158 DEBUG(driver, 2,
"qtmidi: initializing Quicktime");
161 (noErr == Gestalt(gestaltQuickTime, &dummy)) &&
162 (noErr == EnterMovies());
183 #define VOLUME ((short)((0x00FF & _quicktime_volume) << 1)) 240 DEBUG(driver, 2,
"qtmidi: stopping driver...");
243 DEBUG(driver, 3,
"qtmidi: stopping not needed, already idle");
270 if (filename.empty())
return;
272 DEBUG(driver, 2,
"qtmidi: trying to play '%s'", filename.c_str());
276 DEBUG(driver, 3,
"qtmidi: previous tune stopped");
281 DEBUG(driver, 3,
"qtmidi: previous tune disposed");
291 DEBUG(driver, 3,
"qtmidi: playing '%s'", filename.c_str());
307 DEBUG(driver, 3,
"qtmidi: stop requested, but already idle");
314 DEBUG(driver, 3,
"qtmidi: player stopped");
334 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.