aboutsummaryrefslogtreecommitdiff
path: root/queen/sound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'queen/sound.cpp')
-rw-r--r--queen/sound.cpp104
1 files changed, 103 insertions, 1 deletions
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