From a8080f14a9c75a1175976ee8d0cd17c677b55119 Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Wed, 21 Mar 2018 17:12:29 +0100 Subject: Change: DOS music loading for non-Windows music drivers --- src/music/allegro_m.cpp | 11 ++++++--- src/music/bemidi.cpp | 13 ++++++---- src/music/cocoa_m.cpp | 13 ++++++---- src/music/dmusic.cpp | 5 ++-- src/music/extmidi.cpp | 10 +++++--- src/music/libtimidity.cpp | 6 +++-- src/music/midifile.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++ src/music/midifile.hpp | 2 ++ src/music/os2_m.cpp | 6 +++-- src/music/qtmidi.cpp | 11 ++++++--- 10 files changed, 111 insertions(+), 28 deletions(-) (limited to 'src/music') diff --git a/src/music/allegro_m.cpp b/src/music/allegro_m.cpp index fee5bf8a0..906aec84f 100644 --- a/src/music/allegro_m.cpp +++ b/src/music/allegro_m.cpp @@ -14,6 +14,7 @@ #include "../stdafx.h" #include "../debug.h" #include "allegro_m.h" +#include "midifile.hpp" #include #include "../safeguards.h" @@ -60,11 +61,15 @@ void MusicDriver_Allegro::Stop() void MusicDriver_Allegro::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; + std::string filename = MidiFile::GetSMFFile(song); if (_midi != NULL) destroy_midi(_midi); - _midi = load_midi(song.filename); - play_midi(_midi, false); + if (!filename.empty()) { + _midi = load_midi(filename.c_str()); + play_midi(_midi, false); + } else { + _midi = NULL; + } } void MusicDriver_Allegro::StopSong() diff --git a/src/music/bemidi.cpp b/src/music/bemidi.cpp index 7d5793f0d..ff56d787f 100644 --- a/src/music/bemidi.cpp +++ b/src/music/bemidi.cpp @@ -13,6 +13,7 @@ #include "../openttd.h" #include "bemidi.h" #include "../base_media_base.h" +#include "midifile.hpp" /* BeOS System Includes */ #include @@ -37,13 +38,15 @@ void MusicDriver_BeMidi::Stop() void MusicDriver_BeMidi::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; + std::string filename = MidiFile::GetSMFFile(song); this->Stop(); - entry_ref midiRef; - get_ref_for_path(song.filename, &midiRef); - midiSynthFile.LoadFile(&midiRef); - midiSynthFile.Start(); + if (!filename.empty()) { + entry_ref midiRef; + get_ref_for_path(filename.c_str(), &midiRef); + midiSynthFile.LoadFile(&midiRef); + midiSynthFile.Start(); + } } void MusicDriver_BeMidi::StopSong() diff --git a/src/music/cocoa_m.cpp b/src/music/cocoa_m.cpp index 9dcd12cf0..8d97aedf0 100644 --- a/src/music/cocoa_m.cpp +++ b/src/music/cocoa_m.cpp @@ -18,6 +18,7 @@ #include "../stdafx.h" #include "../os/macosx/macos.h" #include "cocoa_m.h" +#include "midifile.hpp" #include "../debug.h" #include "../base_media_base.h" @@ -142,13 +143,13 @@ void MusicDriver_Cocoa::Stop() /** * Starts playing a new song. * - * @param filename Path to a MIDI file. + * @param song Description of music to load and play */ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; + std::string filename = MidiFile::GetSMFFile(song); - DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename); + DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename.c_str()); this->StopSong(); if (_sequence != NULL) { @@ -156,12 +157,14 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) _sequence = NULL; } + if (filename.empty()) return; + if (NewMusicSequence(&_sequence) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to create music sequence"); return; } - const char *os_file = OTTD2FS(song.filename); + const char *os_file = OTTD2FS(filename.c_str()); CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) @@ -221,7 +224,7 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) if (MusicPlayerStart(_player) != noErr) return; _playing = true; - DEBUG(driver, 3, "cocoa_m: playing '%s'", filename); + DEBUG(driver, 3, "cocoa_m: playing '%s'", filename.c_str()); } diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp index b874924f2..ce76d22ef 100644 --- a/src/music/dmusic.cpp +++ b/src/music/dmusic.cpp @@ -1228,11 +1228,10 @@ void MusicDriver_DMusic::Stop() void MusicDriver_DMusic::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; - ThreadMutexLocker lock(_thread_mutex); - _playback.next_file.LoadFile(song.filename); + if (!_playback.next_file.LoadSong(song)) return; + _playback.next_segment.start = 0; _playback.next_segment.end = 0; _playback.next_segment.loop = false; diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp index c532e9d44..9d07761b7 100644 --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -18,6 +18,7 @@ #include "../gfx_func.h" #include "extmidi.h" #include "../base_media_base.h" +#include "midifile.hpp" #include #include #include @@ -86,10 +87,11 @@ void MusicDriver_ExtMidi::Stop() void MusicDriver_ExtMidi::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; - - strecpy(this->song, song.filename, lastof(this->song)); - this->DoStop(); + std::string filename = MidiFile::GetSMFFile(song); + if (!filename.empty()) { + strecpy(this->song, filename.c_str(), lastof(this->song)); + this->DoStop(); + } } void MusicDriver_ExtMidi::StopSong() diff --git a/src/music/libtimidity.cpp b/src/music/libtimidity.cpp index f198280dc..42c1e3c15 100644 --- a/src/music/libtimidity.cpp +++ b/src/music/libtimidity.cpp @@ -14,6 +14,7 @@ #include "../sound_type.h" #include "../debug.h" #include "libtimidity.h" +#include "midifile.hpp" #include "../base_media_base.h" #include #include @@ -76,11 +77,12 @@ void MusicDriver_LibTimidity::Stop() void MusicDriver_LibTimidity::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; + std::string filename = MidiFile::GetSMFFile(song); this->StopSong(); + if (filename.empty()) return; - _midi.stream = mid_istream_open_file(song.filename); + _midi.stream = mid_istream_open_file(filename.c_str()); if (_midi.stream == NULL) { DEBUG(driver, 0, "Could not open music file"); return; diff --git a/src/music/midifile.cpp b/src/music/midifile.cpp index 407c7a123..688538db9 100644 --- a/src/music/midifile.cpp +++ b/src/music/midifile.cpp @@ -1000,6 +1000,68 @@ bool MidiFile::WriteSMF(const char *filename) return true; } +/** + * Get the name of a Standard MIDI File for a given song. + * For songs already in SMF format, just returns the original. + * Otherwise the song is converted, written to a temporary-ish file, and the written filename is returned. + * @param song Song definition to query + * @return Full filename string, empty string if failed + */ +std::string MidiFile::GetSMFFile(const MusicSongInfo &song) +{ + if (song.filetype == MTT_STANDARDMIDI) { + return std::string(song.filename); + } + + if (song.filetype != MTT_MPSMIDI) return std::string(); + + const char *lastpathsep = strrchr(song.filename, PATHSEPCHAR); + if (lastpathsep == NULL) { + lastpathsep = song.filename; + } + + char basename[MAX_PATH]; + { + /* Remove all '.' characters from filename */ + char *wp = basename; + for (const char *rp = lastpathsep + 1; *rp != '\0'; rp++) { + if (*rp != '.') *wp++ = *rp; + } + *wp++ = '\0'; + } + + char tempdirname[MAX_PATH]; + FioGetFullPath(tempdirname, lastof(tempdirname), Searchpath::SP_AUTODOWNLOAD_DIR, Subdirectory::BASESET_DIR, basename); + if (!AppendPathSeparator(tempdirname, lastof(tempdirname))) return std::string(); + FioCreateDirectory(tempdirname); + + char output_filename[MAX_PATH]; + seprintf(output_filename, lastof(output_filename), "%s%d.mid", tempdirname, song.cat_index); + + if (FileExists(output_filename)) { + /* If the file already exists, assume it's the correct decoded data */ + return std::string(output_filename); + } + + byte *data; + size_t datalen; + data = GetMusicCatEntryData(song.filename, song.cat_index, datalen); + if (data == NULL) return std::string(); + + MidiFile midifile; + if (!midifile.LoadMpsData(data, datalen)) { + free(data); + return std::string(); + } + free(data); + + if (midifile.WriteSMF(output_filename)) { + return std::string(output_filename); + } else { + return std::string(); + } +} + static bool CmdDumpSMF(byte argc, char *argv[]) { diff --git a/src/music/midifile.hpp b/src/music/midifile.hpp index 7c567d45c..0016be86c 100644 --- a/src/music/midifile.hpp +++ b/src/music/midifile.hpp @@ -16,6 +16,7 @@ #include "../core/smallvec_type.hpp" #include "midi.h" #include +#include struct MusicSongInfo; @@ -46,6 +47,7 @@ struct MidiFile { bool WriteSMF(const char *filename); + static std::string GetSMFFile(const MusicSongInfo &song); static bool ReadSMFHeader(const char *filename, SMFHeader &header); static bool ReadSMFHeader(FILE *file, SMFHeader &header); }; diff --git a/src/music/os2_m.cpp b/src/music/os2_m.cpp index e308bac0d..1689f00a6 100644 --- a/src/music/os2_m.cpp +++ b/src/music/os2_m.cpp @@ -12,6 +12,7 @@ #include "../stdafx.h" #include "../openttd.h" #include "os2_m.h" +#include "midifile.hpp" #include "../base_media_base.h" #define INCL_DOS @@ -52,11 +53,12 @@ static FMusicDriver_OS2 iFMusicDriver_OS2; void MusicDriver_OS2::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; + std::string filename = MidiFile::GetSMFFile(song); MidiSendCommand("close all"); + if (filename.empty()) return; - if (MidiSendCommand("open %s type sequencer alias song", song.filename) != 0) { + if (MidiSendCommand("open %s type sequencer alias song", filename.c_str()) != 0) { return; } diff --git a/src/music/qtmidi.cpp b/src/music/qtmidi.cpp index 4cd01691d..f8ab150e7 100644 --- a/src/music/qtmidi.cpp +++ b/src/music/qtmidi.cpp @@ -30,6 +30,7 @@ #include "../stdafx.h" #include "qtmidi.h" +#include "midifile.hpp" #include "../debug.h" #include "../base_media_base.h" @@ -261,10 +262,12 @@ void MusicDriver_QtMidi::Stop() */ void MusicDriver_QtMidi::PlaySong(const MusicSongInfo &song) { - if (song.filetype != MTT_STANDARDMIDI) return; if (!_quicktime_started) return; - DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename); + std::string filename = MidiFile::GetSMFFile(song); + if (filename.empty()) return; + + DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename.c_str()); switch (_quicktime_state) { case QT_STATE_PLAY: StopSong(); @@ -278,12 +281,12 @@ void MusicDriver_QtMidi::PlaySong(const MusicSongInfo &song) FALLTHROUGH; case QT_STATE_IDLE: - LoadMovieForMIDIFile(song.filename, &_quicktime_movie); + LoadMovieForMIDIFile(filename.c_str(), &_quicktime_movie); SetMovieVolume(_quicktime_movie, VOLUME); StartMovie(_quicktime_movie); _quicktime_state = QT_STATE_PLAY; } - DEBUG(driver, 3, "qtmidi: playing '%s'", filename); + DEBUG(driver, 3, "qtmidi: playing '%s'", filename.c_str()); } -- cgit v1.2.3-54-g00ecf