From ee276b12b829a675043bfd12a92e3cb82b4ca064 Mon Sep 17 00:00:00 2001 From: Joost Peters Date: Tue, 28 Oct 2003 15:26:05 +0000 Subject: add OGG playback to queen svn-id: r10993 --- queen/resource.cpp | 2 +- queen/resource.h | 4 +-- queen/sound.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++- queen/sound.h | 12 +++++-- 4 files changed, 116 insertions(+), 6 deletions(-) (limited to 'queen') diff --git a/queen/resource.cpp b/queen/resource.cpp index 8c29c35456..cafda9f1ce 100644 --- a/queen/resource.cpp +++ b/queen/resource.cpp @@ -276,7 +276,7 @@ void Resource::readTableCompResource() { } } -File *Resource::giveMP3(const char *filename) { +File *Resource::giveCompressedSound(const char *filename) { assert(strstr(filename, ".SB")); _resourceFile->seek(fileOffset(filename), SEEK_SET); return _resourceFile; diff --git a/queen/resource.h b/queen/resource.h index d5efe5e238..7681288469 100644 --- a/queen/resource.h +++ b/queen/resource.h @@ -68,7 +68,8 @@ public: bool isFloppy(); uint8 compression() { return _compression; } uint32 fileSize(const char *filename); - File *giveMP3(const char *filename); + uint32 fileOffset(const char *filename); + File *giveCompressedSound(const char *filename); Language getLanguage(); const char *JASVersion(); @@ -85,7 +86,6 @@ protected: static ResourceEntry _resourceTablePEM10[]; int32 resourceIndex(const char *filename); - uint32 fileOffset(const char *filename); bool readTableFile(); void readTableCompResource(); static const GameVersion *detectGameVersion(uint32 dataFilesize); diff --git a/queen/sound.cpp b/queen/sound.cpp index 1236da94a4..9938472d4e 100644 --- a/queen/sound.cpp +++ b/queen/sound.cpp @@ -30,6 +30,69 @@ namespace Queen { +#ifdef USE_VORBIS +// These are wrapper functions to allow using a File object to +// provide data to the OggVorbis_File object. + +struct file_info { + File *file; + int start, curr_pos; + size_t len; +}; + +static size_t read_wrap(void *ptr, size_t size, size_t nmemb, void *datasource) { + file_info *f = (file_info *) datasource; + int result; + + nmemb *= size; + if (f->curr_pos > (int) f->len) + nmemb = 0; + else if (nmemb > f->len - f->curr_pos) + nmemb = f->len - f->curr_pos; + result = f->file->read(ptr, nmemb); + if (result == -1) { + f->curr_pos = f->file->pos() - f->start; + return (size_t) -1; + } else { + f->curr_pos += result; + return result / size; + } +} + +static int seek_wrap(void *datasource, ogg_int64_t offset, int whence) { + file_info *f = (file_info *) datasource; + + if (whence == SEEK_SET) + offset += f->start; + else if (whence == SEEK_END) { + offset += f->start + f->len; + whence = SEEK_SET; + } + + f->file->seek(offset, whence); + f->curr_pos = f->file->pos() - f->start; + return f->curr_pos; +} + +static int close_wrap(void *datasource) { + file_info *f = (file_info *) datasource; + + f->file->close(); + delete f; + return 0; +} + +static long tell_wrap(void *datasource) { + file_info *f = (file_info *) datasource; + + return f->curr_pos; +} + +static ov_callbacks g_File_wrap = { + read_wrap, seek_wrap, close_wrap, tell_wrap +}; +#endif + Sound::Sound(SoundMixer *mixer, Input *input, Resource *resource) : _mixer(mixer), _input(input), _resource(resource), _sfxHandle(0) { } @@ -51,6 +114,13 @@ Sound *Sound::giveSound(SoundMixer *mixer, Input *input, Resource *resource, uin #endif break; + case COMPRESSION_OGG: + #ifndef USE_VORBIS + warning("Using OGG compressed datafile, but OGG support not compiled in"); + #else + return new OGGSound(mixer, input, resource); + #endif + break; default: warning("Unknown compression type"); return new SilentSound(mixer, input, resource); @@ -98,7 +168,39 @@ void MP3Sound::sfxPlay(const char *base) { _input->delay(10); if (_resource->exists(name)) - _mixer->playMP3(&_sfxHandle, _resource->giveMP3(name), _resource->fileSize(name)); + _mixer->playMP3(&_sfxHandle, _resource->giveCompressedSound(name), _resource->fileSize(name)); +} +#endif + +#ifdef USE_VORBIS +void OGGSound::sfxPlay(const char *base) { + char name[13]; + strcpy(name, base); + //alter filename to add zeros and append ".SB" + for (int i = 0; i < 8; i++) { + if (name[i] == ' ') + name[i] = '0'; + } + strcat(name, ".SB"); + + while(isPlaying()) + _input->delay(10); + + if (_resource->exists(name)) { + OggVorbis_File *oggFile = new OggVorbis_File; + file_info *f = new file_info; + + f->file = _resource->giveCompressedSound(name); + f->start = _resource->fileOffset(name); + f->len = _resource->fileSize(name); + f->curr_pos = 0; + + if (ov_open_callbacks((void *)f, oggFile, NULL, 0, g_File_wrap) < 0) { + delete oggFile; + delete f; + } else + _mixer->playVorbis(&_sfxHandle, oggFile, 0, false); + } } #endif diff --git a/queen/sound.h b/queen/sound.h index f6a4cb164e..d66c2cf690 100644 --- a/queen/sound.h +++ b/queen/sound.h @@ -41,7 +41,7 @@ public: protected: SoundMixer *_mixer; - Input *_input; + Input *_input; Resource *_resource; PlayingSoundHandle _sfxHandle; @@ -56,8 +56,9 @@ public: class SBSound : public Sound { public: SBSound(SoundMixer *mixer, Input *input, Resource *resource) : Sound(mixer, input, resource) {}; - int playSound(byte *sound, uint32 size); void sfxPlay(const char *base); +protected: + int playSound(byte *sound, uint32 size); }; #ifdef USE_MAD @@ -68,6 +69,13 @@ public: }; #endif +#ifdef USE_VORBIS +class OGGSound : public Sound { +public: + OGGSound(SoundMixer *mixer, Input *input, Resource *resource) : Sound(mixer, input, resource) {}; + void sfxPlay(const char *base); +}; +#endif } // End of namespace Queen #endif -- cgit v1.2.3