summaryrefslogtreecommitdiff
path: root/src/music
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2018-03-21 17:12:29 +0100
committerMichael Lutz <michi@icosahedron.de>2018-06-05 22:58:35 +0200
commita8080f14a9c75a1175976ee8d0cd17c677b55119 (patch)
treedc57362c439d6958f01c680f8f538da28fd3bf4e /src/music
parent458e441a4ca5d451941958e056189a059f2eee76 (diff)
downloadopenttd-a8080f14a9c75a1175976ee8d0cd17c677b55119.tar.xz
Change: DOS music loading for non-Windows music drivers
Diffstat (limited to 'src/music')
-rw-r--r--src/music/allegro_m.cpp11
-rw-r--r--src/music/bemidi.cpp13
-rw-r--r--src/music/cocoa_m.cpp13
-rw-r--r--src/music/dmusic.cpp5
-rw-r--r--src/music/extmidi.cpp10
-rw-r--r--src/music/libtimidity.cpp6
-rw-r--r--src/music/midifile.cpp62
-rw-r--r--src/music/midifile.hpp2
-rw-r--r--src/music/os2_m.cpp6
-rw-r--r--src/music/qtmidi.cpp11
10 files changed, 111 insertions, 28 deletions
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 <allegro.h>
#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 <MidiSynthFile.h>
@@ -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 <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -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 <fcntl.h>
#include <sys/types.h>
@@ -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 <vector>
+#include <string>
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());
}