From 0d000344ca914060e24115bd1fdf1a7173c9e4b0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 1 Jan 2020 22:54:27 +0100 Subject: [PATCH] - replaced the C++ based file access wrapper in ZMusic with a C compatible version. --- libraries/music_common/fileio.h | 18 +++---- libraries/timidityplus/common.cpp | 2 +- libraries/timidityplus/instrum.cpp | 14 +++--- libraries/timidityplus/sffile.cpp | 14 +++--- libraries/timidityplus/smplfile.cpp | 30 ++++++------ libraries/timidityplus/sndfont.cpp | 2 +- libraries/timidityplus/timiditypp/common.h | 4 +- libraries/zmusic/zmusic/zmusic.cpp | 56 +++++++++++++++++++++- libraries/zmusic/zmusic/zmusic.h | 18 +++++-- src/sound/music/i_music.cpp | 5 +- src/sound/s_music.cpp | 2 +- src/utility/filereadermusicinterface.h | 23 ++++++++- src/utility/files.h | 8 ++++ 13 files changed, 144 insertions(+), 52 deletions(-) diff --git a/libraries/music_common/fileio.h b/libraries/music_common/fileio.h index 0c592a3da..550c2e57a 100644 --- a/libraries/music_common/fileio.h +++ b/libraries/music_common/fileio.h @@ -60,8 +60,7 @@ protected: virtual ~FileInterface() {} public: virtual char* gets(char* buff, int n) = 0; - virtual long read(void* buff, int32_t size, int32_t nitems) = 0; - long read(void* buff, int32_t size) { return read(buff, 1, size); } + virtual long read(void* buff, int32_t size) = 0; virtual long seek(long offset, int whence) = 0; virtual long tell() = 0; virtual void close() @@ -101,10 +100,10 @@ struct StdioFileReader : public FileInterface if (!f) return nullptr; return fgets(buff, n, f); } - long read(void* buff, int32_t size, int32_t nitems) override + long read(void* buff, int32_t size) override { if (!f) return 0; - return (long)fread(buff, size, nitems, f); + return (long)fread(buff, 1, size, f); } long seek(long offset, int whence) override { @@ -165,9 +164,9 @@ struct MemoryReader : public FileInterface *p++ = 0; return strbuf; } - long read(void* buff, int32_t size, int32_t nitems) override + long read(void* buff, int32_t size) override { - long len = long(size) * nitems; + long len = long(size); if (len > mLength - mPos) len = mLength - mPos; if (len < 0) len = 0; memcpy(buff, mData + mPos, len); @@ -217,8 +216,11 @@ struct VectorReader : public MemoryReader mLength = (long)mVector.size(); mPos = 0; } - - + VectorReader(uint8_t* data, size_t size) + { + mVector.resize(size); + memcpy(mVector.data(), data, size); + } }; diff --git a/libraries/timidityplus/common.cpp b/libraries/timidityplus/common.cpp index 053a57f0c..c5d4b0318 100644 --- a/libraries/timidityplus/common.cpp +++ b/libraries/timidityplus/common.cpp @@ -149,7 +149,7 @@ void skip(timidity_file *tf, size_t len) int tf_getc(timidity_file *tf) { unsigned char c; - auto read = tf_read(&c, 1, 1, tf); + auto read = tf_read(&c, 1, tf); return read == 0 ? EOF : c; } diff --git a/libraries/timidityplus/instrum.cpp b/libraries/timidityplus/instrum.cpp index 431147dcf..94e55ad73 100644 --- a/libraries/timidityplus/instrum.cpp +++ b/libraries/timidityplus/instrum.cpp @@ -545,21 +545,21 @@ void Instruments::apply_bank_parameter(Instrument *ip, ToneBankElement *tone) #define READ_CHAR(thing) { \ uint8_t tmpchar; \ \ - if (tf_read(&tmpchar, 1, 1, tf) != 1) \ + if (tf_read(&tmpchar, 1, tf) != 1) \ goto fail; \ thing = tmpchar; \ } #define READ_SHORT(thing) { \ uint16_t tmpshort; \ \ - if (tf_read(&tmpshort, 2, 1, tf) != 1) \ + if (tf_read(&tmpshort, 2, tf) != 2) \ goto fail; \ thing = LE_SHORT(tmpshort); \ } #define READ_LONG(thing) { \ int32_t tmplong; \ \ - if (tf_read(&tmplong, 4, 1, tf) != 1) \ + if (tf_read(&tmplong, 4, tf) != 4) \ goto fail; \ thing = LE_LONG(tmplong); \ } @@ -661,7 +661,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr, skip(tf, 127); tmp[0] = tf_getc(tf); } - if ((tf_read(tmp + 1, 1, 238, tf) != 238) + if ((tf_read(tmp + 1, 238, tf) != 238) || (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) { /* don't know what the differences are */ @@ -689,7 +689,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr, memset(ip->sample, 0, sizeof(Sample) * ip->samples); for (i = 0; i < ip->samples; i++) { skip(tf, 7); /* Skip the wave name */ - if (tf_read(&fractions, 1, 1, tf) != 1) { + if (tf_read(&fractions, 1, tf) != 1) { fail: printMessage(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i); for (j = 0; j < i; j++) @@ -738,7 +738,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr, else sp->panning = (uint8_t)(panning & 0x7f); /* envelope, tremolo, and vibrato */ - if (tf_read(tmp, 1, 18, tf) != 18) + if (tf_read(tmp, 18, tf) != 18) goto fail; if (!tmp[13] || !tmp[14]) { sp->tremolo_sweep_increment = sp->tremolo_phase_increment = 0; @@ -845,7 +845,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr, /* Then read the sample data */ sp->data = (sample_t *)safe_malloc(sp->data_length + 4); sp->data_alloced = 1; - if ((j = tf_read(sp->data, 1, sp->data_length, tf)) != (int)sp->data_length) { + if ((j = tf_read(sp->data, sp->data_length, tf)) != (int)sp->data_length) { printMessage(CMSG_ERROR, VERB_NORMAL, "Too small this patch length: %d < %d", j, sp->data_length); goto fail; } diff --git a/libraries/timidityplus/sffile.cpp b/libraries/timidityplus/sffile.cpp index 254f0bfac..ecc32c53a 100644 --- a/libraries/timidityplus/sffile.cpp +++ b/libraries/timidityplus/sffile.cpp @@ -66,7 +66,7 @@ namespace TimidityPlus static int READCHUNK(SFChunk *vp, timidity_file *tf) { - if (tf_read(vp, 8, 1, tf) != 1) + if (tf_read(vp, 8, tf) != 8) return -1; vp->size = LE_LONG(vp->size); return 1; @@ -74,7 +74,7 @@ static int READCHUNK(SFChunk *vp, timidity_file *tf) static int READDW(uint32_t *vp, timidity_file *tf) { - if (tf_read(vp, 4, 1, tf) != 1) + if (tf_read(vp, 4, tf) != 4) return -1; *vp = LE_LONG(*vp); return 1; @@ -82,7 +82,7 @@ static int READDW(uint32_t *vp, timidity_file *tf) static int READW(uint16_t *vp, timidity_file *tf) { - if (tf_read(vp, 2, 1, tf) != 1) + if (tf_read(vp, 2, tf) != 2) return -1; *vp = LE_SHORT(*vp); return 1; @@ -92,7 +92,7 @@ static int READSTR(char *str, timidity_file *tf) { int n; - if (tf_read(str, 20, 1, tf) != 1) + if (tf_read(str, 20, tf) != 20) return -1; str[19] = '\0'; n = (int)strlen(str); @@ -102,8 +102,8 @@ static int READSTR(char *str, timidity_file *tf) return n; } -#define READID(var,tf) tf_read(var, 4, 1, tf) -#define READB(var,tf) tf_read(&var, 1, 1, tf) +#define READID(var,tf) tf_read(var, 4, tf) +#define READB(var,tf) tf_read(&var, 1, tf) #define SKIPB(tf) skip(tf, 1) #define SKIPW(tf) skip(tf, 2) #define SKIPDW(tf) skip(tf, 4) @@ -327,7 +327,7 @@ int Instruments::process_info(int size, SFInfo *sf, timidity_file *fd) case INAM_ID: /* name of the font */ sf->sf_name = (char*)safe_malloc(chunk.size + 1); - tf_read(sf->sf_name, 1, chunk.size, fd); + tf_read(sf->sf_name, chunk.size, fd); sf->sf_name[chunk.size] = 0; printMessage(CMSG_INFO, VERB_DEBUG, " name %s", sf->sf_name); diff --git a/libraries/timidityplus/smplfile.cpp b/libraries/timidityplus/smplfile.cpp index 2480dd450..fd7189189 100644 --- a/libraries/timidityplus/smplfile.cpp +++ b/libraries/timidityplus/smplfile.cpp @@ -204,20 +204,20 @@ int Instruments::get_next_importer(char *sample_file, int start, int count, Samp /* from instrum.c */ #define READ_CHAR(thing) \ - if (1 != tf_read(&tmpchar, 1, 1, tf)) goto fail; \ + if (1 != tf_read(&tmpchar, 1, tf)) goto fail; \ thing = tmpchar; #define READ_SHORT_LE(thing) \ - if (1 != tf_read(&tmpshort, 2, 1, tf)) goto fail; \ + if (2 != tf_read(&tmpshort, 2, tf)) goto fail; \ thing = LE_SHORT(tmpshort); #define READ_LONG_LE(thing) \ - if (1 != tf_read(&tmplong, 4, 1, tf)) goto fail; \ + if (4 != tf_read(&tmplong, 4, tf)) goto fail; \ thing = LE_LONG(tmplong); #define READ_SHORT_BE(thing) \ - if (1 != tf_read(&tmpshort, 2, 1, tf)) goto fail; \ + if (2 != tf_read(&tmpshort, 2, tf)) goto fail; \ thing = BE_SHORT(tmpshort); #define READ_LONG_BE(thing) \ - if (1 != tf_read(&tmplong, 4, 1, tf)) goto fail; \ + if (4 != tf_read(&tmplong, 4, tf)) goto fail; \ thing = BE_LONG(tmplong); const uint8_t pan_mono[] = {64}; /* center */ @@ -280,7 +280,7 @@ int Instruments::import_wave_discriminant(char *sample_file) if ((tf = open_file(sample_file, sfreader)) == NULL) return 1; - if (tf_read(buf, 12, 1, tf) != 1 + if (tf_read(buf, 12, tf) != 12 || memcmp(&buf[0], "RIFF", 4) != 0 || memcmp(&buf[8], "WAVE", 4) != 0) { tf_close(tf); @@ -311,7 +311,7 @@ int Instruments::import_wave_load(char *sample_file, Instrument *inst) if ((tf = open_file(sample_file, sfreader)) == NULL) return 1; - if (tf_read(buf, 12, 1, tf) != 1 + if (tf_read(buf, 12, tf) != 12 || memcmp(&buf[0], "RIFF", 4) != 0 || memcmp(&buf[8], "WAVE", 4) != 0) { tf_close(tf); @@ -321,7 +321,7 @@ int Instruments::import_wave_load(char *sample_file, Instrument *inst) state = chunk_flags = 0; type_index = 4, type_size = 8; for(;;) { - if (tf_read(&buf[type_index], type_size, 1, tf) != 1) + if (tf_read(&buf[type_index], type_size, tf) != type_size) break; chunk_size = LE_LONG(xbuf.i[2]); if (memcmp(&buf[4 + 0], "fmt ", 4) == 0) @@ -553,7 +553,7 @@ int Instruments::import_aiff_discriminant(char *sample_file) if ((tf = open_file(sample_file, sfreader)) == NULL) return 1; - if (tf_read(buf, 12, 1, tf) != 1 + if (tf_read(buf, 12, tf) != 12 || memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0 || (buf[8 + 3] != 'F' && buf[8 + 3] != 'C')) { @@ -593,7 +593,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst) if ((tf = open_file(sample_file, sfreader)) == NULL) return 1; - if (tf_read(buf, 12, 1, tf) != 1 + if (tf_read(buf, 12, tf) != 12 || memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0 || (buf[8 + 3] != 'F' && buf[8 + 3] != 'C')) { @@ -608,7 +608,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst) sound.common = &common; marker_data = NULL; for(;;) { - if (tf_read(&buf[type_index], type_size, 1, tf) != 1) + if (tf_read(&buf[type_index], type_size, tf) != type_size) break; chunk_size = BE_LONG(xbuf.i[2]); if (memcmp(&buf[4 + 0], "COMM", 4) == 0) @@ -666,7 +666,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst) else if (inst->instname == NULL && memcmp(&buf[4 + 0], "NAME", 4) == 0) { inst->instname = (char*)malloc(chunk_size + 1); - if (tf_read(inst->instname, chunk_size, 1, tf) != 1) + if (tf_read(inst->instname, chunk_size, tf) != chunk_size) { chunk_flags |= AIFF_CHUNKFLAG_READERR; break; @@ -744,7 +744,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst) READ_SHORT_BE(comm->numChannels); READ_LONG_BE(comm->numSampleFrames); READ_SHORT_BE(comm->sampleSize); - if (tf_read(sampleRate, 10, 1, tf) != 1) + if (tf_read(sampleRate, 10, tf) != 10) goto fail; comm->sampleRate = ConvertFromIeeeExtended(sampleRate); csize -= 8 + 10; @@ -758,7 +758,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst) uint8_t compressionNameLength; READ_CHAR(compressionNameLength); - if (tf_read(compressionName, compressionNameLength, 1, tf) != 1) + if (tf_read(compressionName, compressionNameLength, tf) != compressionNameLength) goto fail; compressionName[compressionNameLength] = '\0'; printMessage(CMSG_WARNING, VERB_VERBOSE, "AIFF-C unknown compression type: %s", compressionName); @@ -924,7 +924,7 @@ static int AIFFGetMarkerPosition(int16_t id, const AIFFMarkerData *markers, uint #define WAVE_BUF_SIZE (1 << 11) /* should be power of 2 */ #define READ_WAVE_SAMPLE(dest, b, s) \ - if (tf_read(dest, (b) * (s), 1, tf) != 1) \ + if (tf_read(dest, (b) * (s), tf) != (b) * (s)) \ goto fail #define READ_WAVE_FRAME(dest, b, f) \ READ_WAVE_SAMPLE(dest, b, (f) * channels) diff --git a/libraries/timidityplus/sndfont.cpp b/libraries/timidityplus/sndfont.cpp index 13223efca..854529c0d 100644 --- a/libraries/timidityplus/sndfont.cpp +++ b/libraries/timidityplus/sndfont.cpp @@ -550,7 +550,7 @@ Instrument *Instruments::load_from_file(SFInsts *rec, InstList *ip) sample->data_alloced = 1; tf_seek(rec->tf, sp->start, SEEK_SET); - tf_read(sample->data, sp->len, 1, rec->tf); + tf_read(sample->data, sp->len, rec->tf); #ifdef _BIG_ENDIAN_ tmp = (int16_t*)sample->data; diff --git a/libraries/timidityplus/timiditypp/common.h b/libraries/timidityplus/timiditypp/common.h index 1c6116b7c..503d0710a 100644 --- a/libraries/timidityplus/timiditypp/common.h +++ b/libraries/timidityplus/timiditypp/common.h @@ -39,9 +39,9 @@ inline char* tf_gets(char* buff, int n, timidity_file* tf) return tf->gets(buff, n); } -inline long tf_read(void* buff, int32_t size, int32_t nitems, timidity_file* tf) +inline long tf_read(void* buff, int32_t size, timidity_file* tf) { - return (long)tf->read(buff, size, nitems); + return (long)tf->read(buff, size); } inline long tf_seek(timidity_file* tf, long offset, int whence) diff --git a/libraries/zmusic/zmusic/zmusic.cpp b/libraries/zmusic/zmusic/zmusic.cpp index 305c876ab..efb5b67b3 100644 --- a/libraries/zmusic/zmusic/zmusic.cpp +++ b/libraries/zmusic/zmusic/zmusic.cpp @@ -149,7 +149,7 @@ static bool ungzip(uint8_t *data, int complen, std::vector &newdata) // //========================================================================== -DLL_EXPORT MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, const char *Args) +static MusInfo *ZMusic_OpenSongInternal (MusicIO::FileInterface *reader, EMidiDevice device, const char *Args) { MusInfo *info = nullptr; StreamSource *streamsource = nullptr; @@ -294,6 +294,60 @@ DLL_EXPORT MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice } } +DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char* filename, EMidiDevice device, const char* Args) +{ + auto f = MusicIO::utf8_fopen(filename, "rb"); + if (!f) + { + SetError("File not found"); + return nullptr; + } + auto fr = new MusicIO::StdioFileReader; + fr->f = f; + return ZMusic_OpenSongInternal(fr, device, Args); +} + +DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void* mem, size_t size, EMidiDevice device, const char* Args) +{ + if (!mem || !size) + { + SetError("Invalid data"); + return nullptr; + } + // Data must be copied because it may be used as a streaming source and we cannot guarantee that the client memory stays valid. We also have no means to free it. + auto mr = new MusicIO::VectorReader((uint8_t*)mem, (long)size); + return ZMusic_OpenSongInternal(mr, device, Args); +} + +struct CustomFileReader : public MusicIO::FileInterface +{ + ZMusicCustomReader* cr; + + CustomFileReader(ZMusicCustomReader* zr) : cr(zr) {} + virtual char* gets(char* buff, int n) { return cr->gets(cr, buff, n); } + virtual long read(void* buff, int32_t size) { return cr->read(cr, buff, size); } + virtual long seek(long offset, int whence) { return cr->seek(cr, offset, whence); } + virtual long tell() { return cr->tell(cr); } + virtual void close() + { + cr->close(cr); + delete this; + } + +}; + +DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EMidiDevice device, const char* Args) +{ + if (!reader) + { + SetError("No reader protocol specified"); + return nullptr; + } + auto cr = new CustomFileReader(reader); // Oh no! We just put another wrapper around the client's wrapper! + return ZMusic_OpenSongInternal(cr, device, Args); +} + + //========================================================================== // // play CD music diff --git a/libraries/zmusic/zmusic/zmusic.h b/libraries/zmusic/zmusic/zmusic.h index 5ada68500..35a978bcf 100644 --- a/libraries/zmusic/zmusic/zmusic.h +++ b/libraries/zmusic/zmusic/zmusic.h @@ -128,11 +128,17 @@ struct Callbacks MusicIO::SoundFontReaderInterface *(*OpenSoundFont)(const char* name, int type) = nullptr; // Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion. - std::string (*NicePath)(const char *path) = nullptr; - - // For playing modules with compressed samples. - short* (*DumbVorbisDecode)(int outlen, const void* oggstream, int sizebytes); + const char *(*NicePath)(const char* path) = nullptr; +}; +struct ZMusicCustomReader +{ + void* handle; + char* (*gets)(ZMusicCustomReader*handle, char* buff, int n); + long (*read)(ZMusicCustomReader* handle, void* buff, int32_t size); + long (*seek)(ZMusicCustomReader* handle, long offset, int whence); + long (*tell)(ZMusicCustomReader* handle); + void (*close)(ZMusicCustomReader* handle); }; @@ -162,7 +168,9 @@ extern "C" DLL_IMPORT ZMusic_MidiSource ZMusic_CreateMIDISource(const uint8_t* data, size_t length, EMIDIType miditype); DLL_IMPORT bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate); - DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(MusicIO::FileInterface* reader, EMidiDevice device, const char* Args); + DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EMidiDevice device, const char* Args); + DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char *filename, EMidiDevice device, const char* Args); + DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void *mem, size_t size, EMidiDevice device, const char* Args); DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid = 0); DLL_IMPORT bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len); diff --git a/src/sound/music/i_music.cpp b/src/sound/music/i_music.cpp index edc5da424..9045e9994 100644 --- a/src/sound/music/i_music.cpp +++ b/src/sound/music/i_music.cpp @@ -180,9 +180,10 @@ static void wm_printfunc(const char* wmfmt, va_list args) } -static std::string mus_NicePath(const char* str) +static FString strv; +static const char *mus_NicePath(const char* str) { - FString strv = NicePath(str); + strv = NicePath(str); return strv.GetChars(); } diff --git a/src/sound/s_music.cpp b/src/sound/s_music.cpp index f383d9b40..d36f7678e 100644 --- a/src/sound/s_music.cpp +++ b/src/sound/s_music.cpp @@ -509,7 +509,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) } else { - auto mreader = new FileReaderMusicInterface(reader); + auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper. mus_playing.handle = ZMusic_OpenSong(mreader, devp? (EMidiDevice)devp->device : MDEV_DEFAULT, devp? devp->args.GetChars() : ""); if (mus_playing.handle == nullptr) { diff --git a/src/utility/filereadermusicinterface.h b/src/utility/filereadermusicinterface.h index 1de766590..095f8528a 100644 --- a/src/utility/filereadermusicinterface.h +++ b/src/utility/filereadermusicinterface.h @@ -1,8 +1,10 @@ #pragma once #include "../libraries/music_common/fileio.h" +#include "zmusic/zmusic.h" #include "files.h" + struct FileReaderMusicInterface : public MusicIO::FileInterface { FileReader fr; @@ -16,10 +18,10 @@ struct FileReaderMusicInterface : public MusicIO::FileInterface if (!fr.isOpen()) return nullptr; return fr.Gets(buff, n); } - long read(void* buff, int32_t size, int32_t nitems) override + long read(void* buff, int32_t size) override { if (!fr.isOpen()) return 0; - return (long)fr.Read(buff, size * nitems) / size; + return (long)fr.Read(buff, size); } long seek(long offset, int whence) override { @@ -37,3 +39,20 @@ struct FileReaderMusicInterface : public MusicIO::FileInterface } }; + +inline ZMusicCustomReader *GetMusicReader(FileReader& fr) +{ + auto zcr = new ZMusicCustomReader; + + zcr->handle = fr.GetInterface(); + zcr->gets = [](ZMusicCustomReader* zr, char* buff, int n) { return reinterpret_cast(zr->handle)->Gets(buff, n); }; + zcr->read = [](ZMusicCustomReader* zr, void* buff, int32_t size) { return reinterpret_cast(zr->handle)->Read(buff, (long)size); }; + zcr->seek = [](ZMusicCustomReader* zr, long offset, int whence) { return reinterpret_cast(zr->handle)->Seek(offset, whence); }; + zcr->tell = [](ZMusicCustomReader* zr) { return reinterpret_cast(zr->handle)->Tell(); }; + zcr->close = [](ZMusicCustomReader* zr) + { + delete reinterpret_cast(zr->handle); + delete zr; + }; + return zcr; +} \ No newline at end of file diff --git a/src/utility/files.h b/src/utility/files.h index d363b51bf..a82e5e8e2 100644 --- a/src/utility/files.h +++ b/src/utility/files.h @@ -154,6 +154,14 @@ public: return *this; } + // This is for wrapping the actual reader for custom access where a managed FileReader won't work. + FileReaderInterface* GetInterface() + { + auto i = mReader; + mReader = nullptr; + return i; + } + ~FileReader() {