diff --git a/src/base_media_base.h b/src/base_media_base.h index 7614118b7f..15f4372fb7 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -285,11 +285,23 @@ static const uint NUM_SONGS_AVAILABLE = 1 + NUM_SONG_CLASSES * NUM_SONGS_CLASS; /** Maximum number of songs in the (custom) playlist */ static const uint NUM_SONGS_PLAYLIST = 32; +enum MusicTrackType { + MTT_STANDARDMIDI, ///< Standard MIDI file +}; + +/** Metadata about a music track. */ +struct MusicSongInfo { + char songname[32]; ///< name of song displayed in UI + byte tracknr; ///< track number of song displayed in UI + const char *filename; ///< file on disk containing song (when used in MusicSet class, this pointer is owned by MD5File object for the file) + MusicTrackType filetype; ///< decoder required for song file +}; + /** All data of a music set. */ struct MusicSet : BaseSet { - /** The name of the different songs. */ - char song_name[NUM_SONGS_AVAILABLE][32]; - byte track_nr[NUM_SONGS_AVAILABLE]; + /** Data about individual songs in set. */ + MusicSongInfo songinfo[NUM_SONGS_AVAILABLE]; + /** Number of valid songs in set. */ byte num_available; bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename); diff --git a/src/music.cpp b/src/music.cpp index 4001e621e1..5bfe62ebd3 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -66,13 +66,16 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f if (ret) { this->num_available = 0; IniGroup *names = ini->GetGroup("names"); - for (uint i = 0, j = 1; i < lengthof(this->song_name); i++) { + for (uint i = 0, j = 1; i < lengthof(this->songinfo); i++) { const char *filename = this->files[i].filename; if (names == NULL || StrEmpty(filename)) { - this->song_name[i][0] = '\0'; + this->songinfo[i].songname[0] = '\0'; continue; } + this->songinfo[i].filename = filename; // non-owned pointer + this->songinfo[i].filetype = MTT_STANDARDMIDI; + IniItem *item = NULL; /* As we possibly add a path to the filename and we compare * on the filename with the path as in the .obm, we need to @@ -91,8 +94,8 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f return false; } - strecpy(this->song_name[i], item->value, lastof(this->song_name[i])); - this->track_nr[i] = j++; + strecpy(this->songinfo[i].songname, item->value, lastof(this->songinfo[i].songname)); + this->songinfo[i].tracknr = j++; this->num_available++; } } diff --git a/src/music/allegro_m.cpp b/src/music/allegro_m.cpp index 77b488186a..fee5bf8a01 100644 --- a/src/music/allegro_m.cpp +++ b/src/music/allegro_m.cpp @@ -58,10 +58,12 @@ void MusicDriver_Allegro::Stop() if (--_allegro_instance_count == 0) allegro_exit(); } -void MusicDriver_Allegro::PlaySong(const char *filename) +void MusicDriver_Allegro::PlaySong(const MusicSongInfo &song) { + if (song.filetype != MTT_STANDARDMIDI) return; + if (_midi != NULL) destroy_midi(_midi); - _midi = load_midi(filename); + _midi = load_midi(song.filename); play_midi(_midi, false); } diff --git a/src/music/allegro_m.h b/src/music/allegro_m.h index 69cf59569a..65d8ab811d 100644 --- a/src/music/allegro_m.h +++ b/src/music/allegro_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/bemidi.cpp b/src/music/bemidi.cpp index 2bc2074763..7d5793f0df 100644 --- a/src/music/bemidi.cpp +++ b/src/music/bemidi.cpp @@ -12,6 +12,7 @@ #include "../stdafx.h" #include "../openttd.h" #include "bemidi.h" +#include "../base_media_base.h" /* BeOS System Includes */ #include @@ -34,11 +35,13 @@ void MusicDriver_BeMidi::Stop() midiSynthFile.UnloadFile(); } -void MusicDriver_BeMidi::PlaySong(const char *filename) +void MusicDriver_BeMidi::PlaySong(const MusicSongInfo &song) { + if (song.filetype != MTT_STANDARDMIDI) return; + this->Stop(); entry_ref midiRef; - get_ref_for_path(filename, &midiRef); + get_ref_for_path(song.filename, &midiRef); midiSynthFile.LoadFile(&midiRef); midiSynthFile.Start(); } diff --git a/src/music/bemidi.h b/src/music/bemidi.h index 23c6249d59..7c546525d2 100644 --- a/src/music/bemidi.h +++ b/src/music/bemidi.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/cocoa_m.cpp b/src/music/cocoa_m.cpp index 925dc21ab5..9dcd12cf07 100644 --- a/src/music/cocoa_m.cpp +++ b/src/music/cocoa_m.cpp @@ -19,6 +19,7 @@ #include "../os/macosx/macos.h" #include "cocoa_m.h" #include "../debug.h" +#include "../base_media_base.h" #define Rect OTTDRect #define Point OTTDPoint @@ -143,8 +144,10 @@ void MusicDriver_Cocoa::Stop() * * @param filename Path to a MIDI file. */ -void MusicDriver_Cocoa::PlaySong(const char *filename) +void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) { + if (song.filetype != MTT_STANDARDMIDI) return; + DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename); this->StopSong(); @@ -158,7 +161,7 @@ void MusicDriver_Cocoa::PlaySong(const char *filename) return; } - const char *os_file = OTTD2FS(filename); + const char *os_file = OTTD2FS(song.filename); 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) diff --git a/src/music/cocoa_m.h b/src/music/cocoa_m.h index 1963bef5b7..fdb10b84e6 100644 --- a/src/music/cocoa_m.h +++ b/src/music/cocoa_m.h @@ -20,7 +20,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp index 934bb9fe26..b874924f29 100644 --- a/src/music/dmusic.cpp +++ b/src/music/dmusic.cpp @@ -21,6 +21,7 @@ #include "../core/mem_func.hpp" #include "../thread/thread.h" #include "../fileio_func.h" +#include "../base_media_base.h" #include "dmusic.h" #include "midifile.hpp" #include "midi.h" @@ -1225,11 +1226,13 @@ void MusicDriver_DMusic::Stop() } -void MusicDriver_DMusic::PlaySong(const char *filename) +void MusicDriver_DMusic::PlaySong(const MusicSongInfo &song) { + if (song.filetype != MTT_STANDARDMIDI) return; + ThreadMutexLocker lock(_thread_mutex); - _playback.next_file.LoadFile(filename); + _playback.next_file.LoadFile(song.filename); _playback.next_segment.start = 0; _playback.next_segment.end = 0; _playback.next_segment.loop = false; diff --git a/src/music/dmusic.h b/src/music/dmusic.h index 7287623e48..527e064e49 100644 --- a/src/music/dmusic.h +++ b/src/music/dmusic.h @@ -23,7 +23,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp index d39a050f6c..c532e9d446 100644 --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -17,6 +17,7 @@ #include "../video/video_driver.hpp" #include "../gfx_func.h" #include "extmidi.h" +#include "../base_media_base.h" #include #include #include @@ -83,9 +84,11 @@ void MusicDriver_ExtMidi::Stop() this->DoStop(); } -void MusicDriver_ExtMidi::PlaySong(const char *filename) +void MusicDriver_ExtMidi::PlaySong(const MusicSongInfo &song) { - strecpy(this->song, filename, lastof(this->song)); + if (song.filetype != MTT_STANDARDMIDI) return; + + strecpy(this->song, song.filename, lastof(this->song)); this->DoStop(); } diff --git a/src/music/extmidi.h b/src/music/extmidi.h index cfbd894596..e174dc9b08 100644 --- a/src/music/extmidi.h +++ b/src/music/extmidi.h @@ -28,7 +28,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/libtimidity.cpp b/src/music/libtimidity.cpp index 93284bd834..f198280dc7 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 "../base_media_base.h" #include #include #include @@ -73,11 +74,13 @@ void MusicDriver_LibTimidity::Stop() mid_exit(); } -void MusicDriver_LibTimidity::PlaySong(const char *filename) +void MusicDriver_LibTimidity::PlaySong(const MusicSongInfo &song) { + if (song.filetype != MTT_STANDARDMIDI) return; + this->StopSong(); - _midi.stream = mid_istream_open_file(filename); + _midi.stream = mid_istream_open_file(song.filename); if (_midi.stream == NULL) { DEBUG(driver, 0, "Could not open music file"); return; diff --git a/src/music/libtimidity.h b/src/music/libtimidity.h index abe17e7703..badb05bab2 100644 --- a/src/music/libtimidity.h +++ b/src/music/libtimidity.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/music_driver.hpp b/src/music/music_driver.hpp index be09d3ea2b..10a99d2750 100644 --- a/src/music/music_driver.hpp +++ b/src/music/music_driver.hpp @@ -14,6 +14,8 @@ #include "../driver.h" +struct MusicSongInfo; + /** Driver for all music playback. */ class MusicDriver : public Driver { public: @@ -21,7 +23,7 @@ public: * Play a particular song. * @param filename The name of file with the song to play. */ - virtual void PlaySong(const char *filename) = 0; + virtual void PlaySong(const MusicSongInfo &song) = 0; /** * Stop playing the current song. diff --git a/src/music/null_m.h b/src/music/null_m.h index df9f7d80d5..51e1a06656 100644 --- a/src/music/null_m.h +++ b/src/music/null_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop() { } - /* virtual */ void PlaySong(const char *filename) { } + /* virtual */ void PlaySong(const MusicSongInfo &song) { } /* virtual */ void StopSong() { } diff --git a/src/music/os2_m.cpp b/src/music/os2_m.cpp index d7fb97d2d3..e308bac0d2 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 "../base_media_base.h" #define INCL_DOS #define INCL_OS2MM @@ -49,11 +50,13 @@ static long CDECL MidiSendCommand(const char *cmd, ...) /** OS/2's music player's factory. */ static FMusicDriver_OS2 iFMusicDriver_OS2; -void MusicDriver_OS2::PlaySong(const char *filename) +void MusicDriver_OS2::PlaySong(const MusicSongInfo &song) { + if (song.filetype != MTT_STANDARDMIDI) return; + MidiSendCommand("close all"); - if (MidiSendCommand("open %s type sequencer alias song", filename) != 0) { + if (MidiSendCommand("open %s type sequencer alias song", song.filename) != 0) { return; } diff --git a/src/music/os2_m.h b/src/music/os2_m.h index f35e2fdcf6..ac7cd03197 100644 --- a/src/music/os2_m.h +++ b/src/music/os2_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/qtmidi.cpp b/src/music/qtmidi.cpp index 9bc6a61740..4cd01691d1 100644 --- a/src/music/qtmidi.cpp +++ b/src/music/qtmidi.cpp @@ -31,6 +31,7 @@ #include "../stdafx.h" #include "qtmidi.h" #include "../debug.h" +#include "../base_media_base.h" #define Rect OTTDRect #define Point OTTDPoint @@ -258,8 +259,9 @@ void MusicDriver_QtMidi::Stop() * * @param filename Path to a MIDI file. */ -void MusicDriver_QtMidi::PlaySong(const char *filename) +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); @@ -276,7 +278,7 @@ void MusicDriver_QtMidi::PlaySong(const char *filename) FALLTHROUGH; case QT_STATE_IDLE: - LoadMovieForMIDIFile(filename, &_quicktime_movie); + LoadMovieForMIDIFile(song.filename, &_quicktime_movie); SetMovieVolume(_quicktime_movie, VOLUME); StartMovie(_quicktime_movie); _quicktime_state = QT_STATE_PLAY; diff --git a/src/music/qtmidi.h b/src/music/qtmidi.h index f0e17086e4..32163db939 100644 --- a/src/music/qtmidi.h +++ b/src/music/qtmidi.h @@ -20,7 +20,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music/win32_m.cpp b/src/music/win32_m.cpp index edaae36fa2..8e5adeab2a 100644 --- a/src/music/win32_m.cpp +++ b/src/music/win32_m.cpp @@ -18,6 +18,7 @@ #include "../debug.h" #include "midifile.hpp" #include "midi.h" +#include "../base_media_base.h" #include "../safeguards.h" @@ -304,12 +305,14 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW } } -void MusicDriver_Win32::PlaySong(const char *filename) +void MusicDriver_Win32::PlaySong(const MusicSongInfo &song) { + if (song.filetype != MTT_STANDARDMIDI) return; + DEBUG(driver, 2, "Win32-MIDI: PlaySong: entry"); EnterCriticalSection(&_midi.lock); - _midi.next_file.LoadFile(filename); + _midi.next_file.LoadFile(song.filename); _midi.next_segment.start = 0; _midi.next_segment.end = 0; _midi.next_segment.loop = false; diff --git a/src/music/win32_m.h b/src/music/win32_m.h index 3efee3243a..1ac8ae69e4 100644 --- a/src/music/win32_m.h +++ b/src/music/win32_m.h @@ -21,7 +21,7 @@ public: /* virtual */ void Stop(); - /* virtual */ void PlaySong(const char *filename); + /* virtual */ void PlaySong(const MusicSongInfo &song); /* virtual */ void StopSong(); diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 25bb413146..4333e889c7 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -42,7 +42,7 @@ */ static const char *GetSongName(int index) { - return BaseMusic::GetUsedSet()->song_name[index]; + return BaseMusic::GetUsedSet()->songinfo[index].songname; } /** @@ -52,7 +52,7 @@ static const char *GetSongName(int index) */ static int GetTrackNumber(int index) { - return BaseMusic::GetUsedSet()->track_nr[index]; + return BaseMusic::GetUsedSet()->songinfo[index].tracknr; } /** The currently played song */ @@ -186,10 +186,12 @@ static void MusicVolumeChanged(byte new_vol) static void DoPlaySong() { char filename[MAX_PATH]; - if (FioFindFullPath(filename, lastof(filename), BASESET_DIR, BaseMusic::GetUsedSet()->files[_music_wnd_cursong - 1].filename) == NULL) { - FioFindFullPath(filename, lastof(filename), OLD_GM_DIR, BaseMusic::GetUsedSet()->files[_music_wnd_cursong - 1].filename); + MusicSongInfo songinfo = BaseMusic::GetUsedSet()->songinfo[_music_wnd_cursong - 1]; // copy + if (FioFindFullPath(filename, lastof(filename), BASESET_DIR, songinfo.filename) == NULL) { + FioFindFullPath(filename, lastof(filename), OLD_GM_DIR, songinfo.filename); } - MusicDriver::GetInstance()->PlaySong(filename); + songinfo.filename = filename; // non-owned pointer + MusicDriver::GetInstance()->PlaySong(songinfo); SetWindowDirty(WC_MUSIC_WINDOW, 0); }