From 96a123200190782c35a3f7349a4ed5118d91823a Mon Sep 17 00:00:00 2001 From: Ivan Mogilko Date: Sat, 18 Feb 2017 21:12:13 +0300 Subject: [PATCH] Engine: implemented load_midi_pf - something that Allegro 4 should have --- Engine/libsrc/allegro-4.2.2-agspatch/midi.c | 98 +++++++++++++++++++++ Engine/media/audio/sound.cpp | 13 ++- Solutions/Engine.App/Engine.App.vcproj | 4 + 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 Engine/libsrc/allegro-4.2.2-agspatch/midi.c diff --git a/Engine/libsrc/allegro-4.2.2-agspatch/midi.c b/Engine/libsrc/allegro-4.2.2-agspatch/midi.c new file mode 100644 index 0000000000..06337811f2 --- /dev/null +++ b/Engine/libsrc/allegro-4.2.2-agspatch/midi.c @@ -0,0 +1,98 @@ +// +// Unfortunately, as of now Allegro 4 does not have a variant of MIDI +// constructor that takes PACKFILE stream as parameter. Hence our own +// version. This should be removed when either Allegro 4 gets patched +// or we switch to another backend library. +// +// Much of the code is plain copied from load_midi Allegro's function. +// + +#include +#include + +/* load_midi_pf: + * Reads a standard MIDI file from the packfile given, returning a MIDI + * structure, or NULL on error. + * + * If unsuccessful the offset into the file is unspecified, i.e. you must + * either reset the offset to some known place or close the packfile. The + * packfile is not closed by this function. + */ +MIDI *load_midi_pf(PACKFILE *fp) +{ + int c; + char buf[4]; + long data; + MIDI *midi; + int num_tracks; + ASSERT(fp); + + midi = _AL_MALLOC(sizeof(MIDI)); /* get some memory */ + if (!midi) + return NULL; + + for (c=0; ctrack[c].data = NULL; + midi->track[c].len = 0; + } + + pack_fread(buf, 4, fp); /* read midi header */ + + /* Is the midi inside a .rmi file? */ + if (memcmp(buf, "RIFF", 4) == 0) { /* check for RIFF header */ + pack_mgetl(fp); + + while (!pack_feof(fp)) { + pack_fread(buf, 4, fp); /* RMID chunk? */ + if (memcmp(buf, "RMID", 4) == 0) break; + + pack_fseek(fp, pack_igetl(fp)); /* skip to next chunk */ + } + + if (pack_feof(fp)) goto err; + + pack_mgetl(fp); + pack_mgetl(fp); + pack_fread(buf, 4, fp); /* read midi header */ + } + + if (memcmp(buf, "MThd", 4)) + goto err; + + pack_mgetl(fp); /* skip header chunk length */ + + data = pack_mgetw(fp); /* MIDI file type */ + if ((data != 0) && (data != 1)) + goto err; + + num_tracks = pack_mgetw(fp); /* number of tracks */ + if ((num_tracks < 1) || (num_tracks > MIDI_TRACKS)) + goto err; + + data = pack_mgetw(fp); /* beat divisions */ + midi->divisions = ABS(data); + + for (c=0; ctrack[c].len = data; + + midi->track[c].data = _AL_MALLOC_ATOMIC(data); /* allocate memory */ + if (!midi->track[c].data) + goto err; + /* finally, read track data */ + if (pack_fread(midi->track[c].data, data, fp) != data) + goto err; + } + + lock_midi(midi); + return midi; + + /* oh dear... */ + err: + destroy_midi(midi); + return NULL; +} diff --git a/Engine/media/audio/sound.cpp b/Engine/media/audio/sound.cpp index 577e152f5b..59fda8ba22 100644 --- a/Engine/media/audio/sound.cpp +++ b/Engine/media/audio/sound.cpp @@ -46,6 +46,12 @@ #error Either JGMOD_MOD_PLAYER or DUMB_MOD_PLAYER should be defined. #endif +extern "C" +{ +// Load MIDI from PACKFILE stream +MIDI *load_midi_pf(PACKFILE *pf); +} + int numSoundChannels = 8; @@ -254,7 +260,12 @@ SOUNDCLIP *my_load_midi(const AssetPath &asset_name, int repet) if (!thismidi && psp_midi_preload_patches) load_midi_patches(); - MIDI* midiPtr = load_midi(asset_name.second); + PACKFILE *pf = PackfileFromAsset(asset_name); + if (!pf) + return NULL; + + MIDI* midiPtr = load_midi_pf(pf); + pack_fclose(pf); if (midiPtr == NULL) return NULL; diff --git a/Solutions/Engine.App/Engine.App.vcproj b/Solutions/Engine.App/Engine.App.vcproj index 5effadc4b9..8646bbe2bf 100644 --- a/Solutions/Engine.App/Engine.App.vcproj +++ b/Solutions/Engine.App/Engine.App.vcproj @@ -2331,6 +2331,10 @@ RelativePath="..\..\Engine\libsrc\allegro-4.2.2-agspatch\c\cstretch.c" > + +