more featureful sound class
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 14 Sep 2009 00:18:10 +0000 (18:18 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 14 Sep 2009 00:18:10 +0000 (18:18 -0600)
23 files changed:
TODO [new file with mode: 0644]
configure.ac
data/sounds/NightFusionIntro.ogg [new file with mode: 0644]
data/sounds/NightFusionLoop.ogg [new file with mode: 0644]
extra/NightFusion.xm [moved from data/sounds/NightFusion.xm with 100% similarity]
extra/yoink.ebuild
extra/yoink.spec.in
src/Character.cc
src/Character.hh
src/Hud.cc
src/Moof/Camera.hh
src/Moof/Engine.cc
src/Moof/Engine.hh
src/Moof/Log.hh
src/Moof/Math.hh
src/Moof/Mippleton.hh
src/Moof/Octree.hh
src/Moof/OpenGL.hh
src/Moof/Sound.cc
src/Moof/Sound.hh
src/Moof/Timer.cc
src/YoinkApp.cc
src/YoinkApp.hh

diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..90c8f4d
--- /dev/null
+++ b/TODO
@@ -0,0 +1,3 @@
+
+The man page (doc/yoink.6) may have a list.
+
index 5a7791d518e0a576833437990b10453f56b44e79..a87d9817776f099b881d137dc74aaa26c3a0728f 100644 (file)
@@ -83,30 +83,33 @@ AC_ARG_WITH([log-level],
 if test x$developer = xyes
 then
        debug=yes
-       profile=yes
-       extra_warnings=yes
        log_level=4
+
+       if test x$WIN32 != xyes
+       then
+               profile=yes
+       fi
 fi
 
 if test x$debug = xyes
 then
-   CFLAGS="$CFLAGS -Wall -O0 -g -DDEBUG"
-   CXXFLAGS="$CXXFLAGS -Wall -O0 -g -DDEBUG"
+       CFLAGS="$CFLAGS -Wall -O0 -gstabs -DDEBUG"
+       CXXFLAGS="$CXXFLAGS -Wall -O0 -gstabs -DDEBUG"
 else
-   CFLAGS="$CFLAGS -O2 -DNDEBUG"
-   CXXFLAGS="$CXXFLAGS -O2 -DNDEBUG"
+       CFLAGS="$CFLAGS -O2 -DNDEBUG"
+       CXXFLAGS="$CXXFLAGS -O2 -DNDEBUG"
 fi
 
 if test x$profile = xyes
 then
-   CFLAGS="$CFLAGS -pg"
-   CXXFLAGS="$CXXFLAGS -pg"
+       CFLAGS="$CFLAGS -pg"
+       CXXFLAGS="$CXXFLAGS -pg"
 fi
 
 if test x$extra_warnings = xyes
 then
-   CFLAGS="$CFLAGS -Wextra"
-   CXXFLAGS="$CXXFLAGS -Wextra"
+       CFLAGS="$CFLAGS -Wextra -Wno-unused-parameter"
+       CXXFLAGS="$CXXFLAGS -Wextra -Wno-unused-parameter"
 fi
 
 AC_DEFINE_UNQUOTED([YOINK_LOGLEVEL], [$log_level],
diff --git a/data/sounds/NightFusionIntro.ogg b/data/sounds/NightFusionIntro.ogg
new file mode 100644 (file)
index 0000000..785ad8a
Binary files /dev/null and b/data/sounds/NightFusionIntro.ogg differ
diff --git a/data/sounds/NightFusionLoop.ogg b/data/sounds/NightFusionLoop.ogg
new file mode 100644 (file)
index 0000000..46a5b55
Binary files /dev/null and b/data/sounds/NightFusionLoop.ogg differ
index 6f7dd364973f1a476223abfd53efd47a7709a369..0f903162617648c920c0dc6aaed6a9e2be6c2162 100644 (file)
@@ -19,7 +19,7 @@ IUSE="debug profile"
 RDEPEND="media-libs/freealut
        media-libs/libsdl[opengl]
        media-libs/sdl-image[png]
-       media-libs/sdl-sound[mikmod,vorbis]
+       media-libs/sdl-sound[vorbis]
        media-libs/openal
        virtual/opengl"
 DEPEND="${RDEPEND}
index a1a433da80422686c7bdd3f12785563003fa5a40..6c39987660e80e224f2c35d80c83281b4032ddab 100644 (file)
@@ -12,10 +12,12 @@ BuildRequires: SDL_image-devel
 BuildRequires: SDL_sound-devel
 BuildRequires: mesa-libGL-devel
 BuildRequires: openal-devel
+BuildRequires: freealut-devel
 Requires: SDL
 Requires: SDL_image
 Requires: SDL_sound
 Requires: openal
+Requires: freealut
 %description
 Leap tall buildings!  Crush stupid robots beneath your feet!  Wield your
 extra-terrestrial powers in the defence of humanity, and send those alien
index 411c0327e641ba8c5ff0883f0efc0d4a22d6f366..1b184fa2d0160ad353ef3645823d25626397b3cf 100644 (file)
@@ -26,6 +26,8 @@
 
 *******************************************************************************/
 
+#include <iostream>
+
 #include "Character.hh"
 #include "Log.hh"
 
@@ -125,7 +127,8 @@ void Character::handleEvent(const Mf::Event& event)
                        break;
        }
 
-       Mf::logInfo("current force [%f %f]", current.force[0], current.force[1]);
+       //Mf::logInfo("current force [%f %f]", current.force[0], current.force[1]);
+       //std::cerr << "current force: " << current.force << std::endl;
 }
 
 
index b72e8c87e58910d6296218b2eff58696e8ac2ab1..5aeaeba0a7af1b8a5ea6e1c6f7f53fbee43c48e2 100644 (file)
@@ -90,6 +90,11 @@ struct Character : public Mf::Entity
                Mf::Scalar      mass;
                Mf::Scalar      inverseMass;
 
+               void recalculate()
+               {
+                       velocity = momentum * inverseMass;
+               }
+
 
                void getDerivative(Derivative& derivative, Mf::Scalar t) const
                {
@@ -99,11 +104,6 @@ struct Character : public Mf::Entity
                        derivative.force = force;
                }
 
-               void recalculate()
-               {
-                       velocity = momentum * inverseMass;
-               }
-
                void applyDerivative(const Derivative& derivative, Mf::Scalar dt)
                {
                        position += dt * derivative.velocity;
@@ -133,7 +133,7 @@ struct Character : public Mf::Entity
        State                   previous;
        State                   current;
 
-       stlplus::ntree<Mf::OctreeNode>::iterator treeNode;
+       Mf::OctreeNodeP treeNode;
 
 
 private:
@@ -164,7 +164,8 @@ public:
 };
 
 
-inline Character::State operator*(Mf::Scalar scalar, const Character::State& state)
+inline Character::State operator*(Mf::Scalar scalar,
+               const Character::State& state)
 {
        Character::State newState = state;
        newState.position *= scalar;
index ea0dfeaef564202a32af2e569fa847501d7354a8..d5ec7bcd8ebbc7222d30c2073f8184a8d9023abc 100644 (file)
@@ -130,9 +130,9 @@ Hud::Hud() :
 void Hud::resize(int width, int height)
 {
        cml::matrix_orthographic_RH( projection_, 
-                       0.0, 
-                       Mf::Scalar(width), 0.0, Mf::Scalar(height),
-                       1.0, -1.0, cml::z_clip_neg_one);
+                       0.0f
+                       Mf::Scalar(width), 0.0f, Mf::Scalar(height),
+                       1.0f, -1.0f, cml::z_clip_neg_one);
 
        // position the two progress bars at the top-left of the screen
        bar1_.resize(Mf::Rectangle(20, height - 51,
index 72df5db6703fcc3d90e3c25fb615ccc3c250f7d5..fae25079ec700d88d7e1a5edb1baff0e3324874e 100644 (file)
@@ -46,7 +46,7 @@ public:
        Camera() :
                position_(0.0, 0.0, 0.0)
        {
-               cml::quaternion_rotation_world_y(rotation_, 0.0);
+               cml::quaternion_rotation_world_y(rotation_, 0.0f);
                calculateSecondary();
        }
 
index 27406521da79693040a6e8b7bdc9e34dd141528e..51a3af0f5bfb6d75d71cdaed34cb7bdd9518c3ac 100644 (file)
@@ -27,7 +27,6 @@
 *******************************************************************************/
 
 #include <cstdlib>                     // exit
-#include <iostream>
 #include <string>
 
 #include <SDL/SDL.h>
@@ -35,7 +34,9 @@
 #include <SDL/SDL_sound.h>
 #include <AL/alut.h>
 
+#include "Dispatcher.hh"
 #include "Engine.hh"
+#include "Log.hh"
 #include "Random.hh"
 #include "Settings.hh"
 #include "Timer.hh"
@@ -59,18 +60,17 @@ public:
                if (SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_EVENTTHREAD) != 0)
 #endif
                {
-                       std::cerr << "sdl is complaining: " << SDL_GetError() << std::endl;
+                       logError("sdl is complaining: %s", SDL_GetError());
                        throw Exception(Exception::SDL_ERROR);
                }
                if (FE_Init() != 0)
                {
-                       std::cerr << "fast events error: " << FE_GetError() << std::endl;
+                       logError("fast events error: %s", FE_GetError());
                        throw Exception(Exception::SDL_ERROR);
                }
                if (Sound_Init() == 0)
                {
-                       std::cerr << "sound initialization failed: " << Sound_GetError()
-                               << std::endl;
+                       logError("sound initialization failed: %s", Sound_GetError());
                        throw Exception(Exception::SDL_ERROR);
                }
                alutInit(&argc, argv);
@@ -174,7 +174,7 @@ public:
 
                                        if (printFps)
                                        {
-                                               std::cout << "FPS: " << fps << std::endl;
+                                               logInfo("framerate: %d fps", fps);
                                        }
                                }
 
index f088dc56e85fcb663766594a2c9b454788e7c519..0617b1a5c3094025331233fe4c8ced0a5742010e 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include <Moof/Dispatcher.hh>
 #include <Moof/Event.hh>
 #include <Moof/Exception.hh>
 #include <Moof/Math.hh>
index cdd5cd4e751e8e4374b94babbcc2be10f249f991..263ede8fdff0d950743139b39a5f2159c166728b 100644 (file)
@@ -37,7 +37,6 @@
  */
 
 #include <cstdlib>             // exit
-#include <cstring>             // strerror
 
 
 /**
index a38af8b049dd77357c175aa79ecb2c5d5969c810..eb411e06d3299d90778117bafe81b08061c343ad 100644 (file)
@@ -49,6 +49,8 @@ typedef cml::vector< Scalar, cml::fixed<2> >  Vector2;
 typedef cml::vector< Scalar, cml::fixed<3> >   Vector3;
 typedef cml::vector< Scalar, cml::fixed<4> >   Vector4;
 
+typedef cml::matrix< Scalar, cml::fixed<2,2>,
+               cml::col_basis, cml::col_major >                Matrix2;
 typedef cml::matrix< Scalar, cml::fixed<3,3>,
                cml::col_basis, cml::col_major >                Matrix3;
 typedef cml::matrix< Scalar, cml::fixed<4,4>,
index e9b97328d351ae9de7e08527a49984f90030231b..cde68d2b4b99eeb7024c5f1f77eae469bfec198b 100644 (file)
@@ -51,8 +51,8 @@ namespace Mf {
 template <class T>
 class Mippleton
 {
-       typedef std::pair<unsigned,T*>                                                          PtrValue;
-       typedef stlplus::hash<std::string,PtrValue,getHash>     PtrMap;
+       typedef std::pair<unsigned,T*>                                                  PtrValue;
+       typedef stlplus::hash<std::string,PtrValue,getHash>             PtrMap;
 
        static PtrMap   ptrs_;
        std::string             name_;
index 3614606fd911882dc96195cb28cedd3f83282120..ade0a026fdddc13e4507c88a9605e7f28bfd959f 100644 (file)
@@ -141,9 +141,9 @@ public:
 
        inline void print(OctreeNodeP node)
        {
-               logDebug("-----");
-               logDebug("depth to node: %d", tree_.depth(node));
-               logDebug("size of node: %d", tree_.size(node));
+               //logDebug("-----");
+               //logDebug("depth to node: %d", tree_.depth(node));
+               //logDebug("size of node: %d", tree_.size(node));
        }
 
        inline static OctreeP alloc(const OctreeNode& rootNode)
index 0ac6612723025b65858cb6da55798b00f1127109..a5ae3a043f75100208d026fa386ab47d2fdd9878 100644 (file)
@@ -33,7 +33,7 @@
 
 
 /* Define to 1 if you want to use double precision floating-point numbers. */
-#define USE_DOUBLE_PRECISION 1 
+//#define USE_DOUBLE_PRECISION 1 
 
 
 #if USE_DOUBLE_PRECISION
index a0302fba003aaa6052e7e447f85a97d142ecd781..110dc4ba0416e03c268147097bd8e4c7f44821ee 100644 (file)
@@ -27,6 +27,8 @@
 *******************************************************************************/
 
 #include <string>
+#include <queue>
+#include <vector>
 
 #include <SDL/SDL.h>
 #include <SDL/SDL_sound.h>
@@ -36,7 +38,8 @@
 #include "Mippleton.hh"
 #include "Sound.hh"
 
-#define BUFFER_SIZE (8 * 4096)
+#define BUFFER_SIZE (64 * 1024)
+//#define BUFFER_SIZE (5*2048)
 
 namespace Mf {
 
@@ -58,39 +61,61 @@ struct Sound::Impl
                }
        }
        
-       struct Buffer : public Mippleton<Buffer>
+       class Buffer;
+       typedef boost::shared_ptr<Buffer> BufferP;
+       
+       class Buffer : public Mippleton<Buffer>
        {
+               Sound_Sample*                   sound;
+               std::vector<ALuint>             objects;
+
+       public:
+
                Buffer(const std::string& name) :
-                       Mippleton<Buffer>(name)
+                       Mippleton<Buffer>(name),
+                       sound(0)
                {
-                       sound = 0;
-                       objects[0] = 0;
-                       objects[1] = 0;
+                       openFile();
                }
 
                ~Buffer()
                {
-                       alDeleteBuffers(2, objects);
+                       while (!objects.empty())
+                       {
+                               alDeleteBuffers(1, &objects.back());
+                               objects.pop_back();
+                       }
 
                        if (sound) Sound_FreeSample(sound);
                }
 
 
-               void loadFromFile(const std::string& filePath, bool stream)
+               void openFile()
                {
-                       if (objects[0] != 0) return;
+                       if (sound) Sound_FreeSample(sound);
 
-                       sound = Sound_NewSampleFromFile(filePath.c_str(),
-                                       NULL, BUFFER_SIZE);
+                       sound = Sound_NewSampleFromFile(Sound::getPath(getName()).c_str(),
+                                       0, BUFFER_SIZE);
 
                        if (!sound)
                        {
-                               logWarning("error while loading sound %s: %s", getName().c_str(), Sound_GetError());
+                               logWarning("error while loading sound %s: %s",
+                                               getName().c_str(), Sound_GetError());
                                throw Exception(Exception::FILE_NOT_FOUND);
                        }
 
-                       if (!stream)
-                       {
+                       logDebug("buffer size: %d", sound->buffer_size);
+                       logDebug("   channels: %d", sound->actual.channels);
+                       logDebug("     format: %d", sound->actual.format);
+                       logDebug("  frequency: %d", sound->actual.rate);
+               }
+
+
+               void loadAll(ALuint source)
+               {
+                       if (!sound) openFile();
+                       if (!sound) return;
+
                        unsigned decoded = Sound_DecodeAll(sound);
                        if (decoded == 0)
                        {
@@ -99,89 +124,148 @@ struct Sound::Impl
                                return;
                        }
 
-                       alGenBuffers(2, objects);
-                       alBufferData(objects[0], getAudioFormat(sound->actual), sound->buffer,
+                       ALuint obj;
+                       alGenBuffers(1, &obj);
+
+                       alBufferData(obj, getAudioFormat(sound->actual), sound->buffer,
                                        sound->buffer_size, sound->actual.rate);
-                       logDebug("buffer size: %d", sound->buffer_size);
-                       logDebug("   channels: %d", sound->actual.channels);
-                       logDebug("     format: %d", sound->actual.format);
-                       logDebug("  frequency: %d", sound->actual.rate);
 
+                       objects.push_back(obj);
+
+                       alSourcei(source, AL_BUFFER, obj);
+
+                       // don't need t his anymore
                        Sound_FreeSample(sound);
                        sound = 0;
-                       }
-                       else
+               }
+
+
+               void beginStream(ALuint source, int nBuffers = 4)
+               {
+                       if (!sound) openFile();
+                       if (!sound) return;
+
+                       ALuint objs[nBuffers];
+                       alGenBuffers(nBuffers, objs);
+
+                       for (int i = 0; i < nBuffers; ++i)
                        {
-                       logDebug("buffer size: %d", sound->buffer_size);
-                       logDebug("   channels: %d", sound->actual.channels);
-                       logDebug("     format: %d", sound->actual.format);
-                       logDebug("  frequency: %d", sound->actual.rate);
-                               alGenBuffers(2, objects);
+                               objects.push_back(objs[i]);
+                               stream(objs[i]);
                        }
+
+                       alSourceQueueBuffers(source, nBuffers, objs);
                }
 
-               bool stream(ALuint buffer)
+               enum StreamStatus
+               {
+                       STREAM_OK               = 0,
+                       STREAM_EOF              = 1,
+                       STREAM_WRONG    = 2
+               };
+
+               StreamStatus stream(ALuint buffer)
                {
-                       int bytes = Sound_Decode(sound);
+                       std::vector<ALuint>::iterator it =
+                               std::find(objects.begin(), objects.end(), buffer);
 
-                       if (bytes < BUFFER_SIZE) return false;
+                       // that buffer doesn't belong to us
+                       if (it == objects.end()) return STREAM_WRONG;
+
+                       unsigned bytes = Sound_Decode(sound);
+
+                       if (bytes == 0) return STREAM_EOF;
 
                        alBufferData(buffer, getAudioFormat(sound->actual), sound->buffer,
-                                       sound->buffer_size, sound->actual.rate);
-                       return false;
+                                       bytes, sound->actual.rate);
+
+                       return STREAM_OK;
+               }
+
+               inline void rewind()
+               {
+                       if (!sound) openFile();
+                       else Sound_Rewind(sound);
                }
 
-               Sound_Sample* sound;
-               ALuint objects[2];
 
-       //ALfloat location[] = {0.0f, 0.0f, 0.0f};
-       //ALfloat location2[] = {0.0f, 0.0f, 0.0f};
-       //ALfloat orient[] = {0.0f, 0.0f, -1.0f, 0.0, 1.0, 0.0};
+               // delete unused buffers, return true if all buffers deleted
+               inline bool clear()
+               {
+                       // clear any openal errors
+                       alGetError();
+
+                       while (!objects.empty())
+                       {
+                               ALuint buffer = objects.back();
+                               alDeleteBuffers(1, &buffer);
 
+                               // if an error occured, the buffer was not deleted because it's
+                               // still in use by some source
+                               if (alGetError() != AL_NO_ERROR) return false;
 
-       //alListenerfv(AL_POSITION, location);
-       //alListenerfv(AL_VELOCITY, location);
-       //alListenerfv(AL_VELOCITY, orient);
+                               objects.pop_back();
+                       }
+
+                       return true;
+               }
        };
 
-       Impl(const std::string& name, bool stream = false) :
-               buffer_(Buffer::getInstance(name))
-       {
-               if (!stream) buffer_->loadFromFile(Sound::getPath(name), stream);
-               else         buffer_->loadFromFile(SoundStream::getPath(name), stream);
 
-               ALfloat location[] = {0.0f, 0.0f, 0.0f};
+       Impl(const std::string& name) :
+               buffer_(Buffer::getInstance(name)),
+               playing_(false),
+               looping_(false)
+       {
+               ALfloat zero[] = {0.0f, 0.0f, 0.0f};
                
                alGenSources(1, &source_);
 
                alSourcef(source_,  AL_PITCH, 1.0f);
                alSourcef(source_,  AL_GAIN, 1.0f);
-               alSourcefv(source_, AL_POSITION, location);
-               alSourcefv(source_, AL_VELOCITY, location);
-               alSourcei(source_,  AL_LOOPING, AL_FALSE);
+               alSourcefv(source_, AL_POSITION, zero);
+               alSourcefv(source_, AL_VELOCITY, zero);
+       }
 
-               if (!stream)
+       ~Impl()
+       {
+               alDeleteSources(1, &source_);
+       }
+
+
+       void play()
+       {
+               ALenum type;
+               alGetSourcei(source_, AL_SOURCE_TYPE, &type);
+
+               if (type != AL_STATIC)
                {
-                       alSourcei(source_, AL_BUFFER, buffer_->objects[0]);
+                       buffer_->loadAll(source_);
                }
-               else
-               {
-                       buffer_->stream(buffer_->objects[0]);
-                       buffer_->stream(buffer_->objects[1]);
 
-                       alSourceQueueBuffers(source_, 2, buffer_->objects);
-               }
+               alSourcei(source_, AL_LOOPING, looping_);
+               alSourcePlay(source_);
+               playing_ = true;
        }
 
-       ~Impl()
+
+       void stream()
        {
-               alDeleteSources(1, &source_);
-       }
+               ALenum type;
+               alGetSourcei(source_, AL_SOURCE_TYPE, &type);
+
+               alSourcei(source_, AL_BUFFER, AL_NONE);
+               buffer_->rewind();
+               buffer_->beginStream(source_);
 
+               alSourcei(source_, AL_LOOPING, AL_FALSE);
+               alSourcePlay(source_);
+               playing_ = true;
+       }
 
-       void update()
+       inline void update()
        {
-               int finished = 0;
+               ALint finished = 0;
 
                alGetSourcei(source_, AL_BUFFERS_PROCESSED, &finished);
 
@@ -190,17 +274,141 @@ struct Sound::Impl
                        ALuint buffer;
 
                        alSourceUnqueueBuffers(source_, 1, &buffer);
-                       buffer_->stream(buffer);
-                       alSourceQueueBuffers(source_, 1, &buffer);
+
+                       Buffer::StreamStatus status = buffer_->stream(buffer);
+
+                       if (status == Buffer::STREAM_OK)
+                       {
+                               alSourceQueueBuffers(source_, 1, &buffer);
+                       }
+                       else if (status == Buffer::STREAM_EOF)
+                       {
+                               if (!queue_.empty())
+                               {
+                                       // begin the next buffer in the queue
+                                       expired_.push_back(buffer_);
+                                       buffer_ = queue_.front();
+                                       queue_.pop();
+                                       buffer_->beginStream(source_, 1);
+                               }
+                               else if (looping_)
+                               {
+                                       // restart from the beginning
+                                       buffer_->rewind();
+                                       buffer_->stream(buffer);
+                                       alSourceQueueBuffers(source_, 1, &buffer);
+                               }
+                       }
+                       else if (status == Buffer::STREAM_WRONG)
+                       {
+                               clear();
+                               buffer_->beginStream(source_, 1);
+                       }
+               }
+
+               ALenum state;
+               alGetSourcei(source_, AL_SOURCE_STATE, &state);
+
+               // restart playing if we're stopped but supposed to be playing... this
+               // means we didn't queue enough and the audio skipped
+               if (playing_ && state != AL_PLAYING)
+               {
+                       alSourcePlay(source_);
                }
        }
 
+       inline void clear()
+       {
+               // try to remove expired buffers
+               std::vector<BufferP>::iterator it;
+               for (it = expired_.end() - 1; it >= expired_.begin(); --it)
+               {
+                       if ((*it)->clear()) expired_.erase(it);
+               }
+       }
 
-       boost::shared_ptr<Buffer>       buffer_;
-       ALuint                                          source_;
-       bool playing;
-};
 
+       void stop()
+       {
+               alSourceStop(source_);
+               playing_ = false;
+       }
+
+       inline void pause()
+       {
+               alSourcePause(source_);
+               playing_ = false;
+       }
+
+       inline void resume()
+       {
+               alSourcePlay(source_);
+               playing_ = true;
+       }
+
+
+       inline void setSample(const std::string& name)
+       {
+               bool playing = isPlaying();
+               ALenum type;
+               alGetSourcei(source_, AL_SOURCE_TYPE, &type);
+
+               stop();
+
+               //alSourcei(source_, AL_BUFFER, AL_NONE);
+               buffer_ = Buffer::getInstance(name);
+
+               if (type == AL_STREAMING)
+               {
+                       if (playing) stream();
+               }
+               else
+               {
+                       if (playing) play();
+               }
+       }
+
+       inline void enqueue(const std::string& name)
+       {
+               BufferP buffer = Buffer::getInstance(name);
+               queue_.push(buffer);
+       }
+
+
+       inline bool isPlaying() const
+       {
+               if (playing_) return true;
+
+               ALenum state;
+               alGetSourcei(source_, AL_SOURCE_STATE, &state);
+
+               return state == AL_PLAYING;
+       }
+
+
+       inline void setLooping(bool looping)
+       {
+               looping_ = looping;
+
+               ALenum type;
+               alGetSourcei(source_, AL_SOURCE_TYPE, &type);
+
+               if (type != AL_STREAMING)
+               {
+                       alSourcei(source_, AL_LOOPING, looping_);
+               }
+       }
+
+
+       ALuint                                  source_;
+       BufferP                                 buffer_;
+
+       bool                                    playing_;
+       bool                                    looping_;
+
+       std::queue<BufferP>             queue_;
+       std::vector<BufferP>    expired_;
+};
 
 Sound::Sound(const std::string& name) :
        // pass through
@@ -209,59 +417,100 @@ Sound::Sound(const std::string& name) :
 
 void Sound::play()
 {
-       if (!impl_->buffer_->sound) return;
+       // pass through
+       impl_->play();
+}
 
-       //alSourceRewind(impl_->source_);
-       alSourcePlay(impl_->source_);
-       impl_->playing = true;
+
+void Sound::stream()
+{
+       // pass through
+       impl_->stream();
 }
 
-void Sound::pause()
+void Sound::update(Scalar t, Scalar dt)
 {
-       alSourcePause(impl_->source_);
-       impl_->playing = false;
+       // pass through
+       impl_->update();
 }
 
-void Sound::togglePlayPause()
+
+void Sound::stop()
 {
-       if (impl_->playing) pause();
-       else play();
+       // pass through
+       impl_->stop();
 }
 
-void Sound::setGain(Scalar gain)
+void Sound::pause()
 {
-       alSourcef(impl_->source_, AL_GAIN, gain);
+       // pass through
+       impl_->pause();
 }
 
+void Sound::resume()
+{
+       // pass through
+       impl_->resume();
+}
 
-std::string Sound::getPath(const std::string& name)
+void Sound::toggle()
 {
-       std::string path = Resource::getPath("sounds/" + name + ".ogg");
-       return path;
+       if (impl_->playing_) pause();
+       else resume();
 }
 
 
-//##############################################################################
+void Sound::setSample(const std::string& name)
+{
+       // pass through
+       impl_->setSample(name);
+}
+
+void Sound::enqueue(const std::string& name)
+{
+       // pass through
+       impl_->enqueue(name);
+}
 
 
-SoundStream::SoundStream(const std::string& name)
+bool Sound::isPlaying() const
+{
        // pass through
-       //impl_(name, true) {}
+       return impl_->isPlaying();
+}
+
+void Sound::setPosition(Vector3 position)
 {
-       impl_ = boost::shared_ptr<Sound::Impl>(new Sound::Impl(name, true));
+       float p[3] = {position[0], position[1], position[2]};
+       alSourcefv(impl_->source_, AL_POSITION, p);
 }
 
+void Sound::setVelocity(Vector3 velocity)
+{
+       float v[3] = {velocity[0], velocity[1], velocity[2]};
+       alSourcefv(impl_->source_, AL_VELOCITY, v);
+}
 
-void SoundStream::update(Scalar t, Scalar dt)
+void Sound::setGain(Scalar gain)
+{
+       alSourcef(impl_->source_, AL_GAIN, float(gain));
+}
+
+void Sound::setPitch(Scalar pitch)
+{
+       alSourcef(impl_->source_, AL_PITCH, float(pitch));
+}
+
+void Sound::setLooping(bool looping)
 {
        // pass through
-       impl_->update();
+       impl_->setLooping(looping);
 }
 
 
-std::string SoundStream::getPath(const std::string& name)
+std::string Sound::getPath(const std::string& name)
 {
-       std::string path = Resource::getPath("sounds/" + name + ".xm");
+       std::string path = Resource::getPath("sounds/" + name + ".ogg");
        return path;
 }
 
index 3f64162f0ca4b2a690f3b7be7005095ee00a3f7c..32f4c87097fed36cf82c651c0a32dad75ad2082d 100644 (file)
@@ -34,8 +34,6 @@
  * Image-loading and OpenGL texture loading.
  */
 
-#include <stdexcept>
-
 #include <boost/shared_ptr.hpp>
 
 #include <Moof/Exception.hh>
@@ -52,25 +50,39 @@ typedef boost::shared_ptr<Sound> SoundP;
 
 class Sound : public Resource
 {
-protected:
-       Sound() {}
        class Impl;
        boost::shared_ptr<Impl> impl_;
 
 public:
 
-       static SoundP alloc(const std::string& name)
+       inline static SoundP alloc(const std::string& name)
        {
                return SoundP(new Sound(name));
        }
 
-       Sound(const std::string& name);
+       explicit Sound(const std::string& name);
+
 
        void play();
+
+       void stream();
+       void update(Scalar t, Scalar dt);
+
+       void stop();
        void pause();
-       void togglePlayPause();
+       void resume();
+       void toggle();
+
+       void setSample(const std::string& name);
+       void enqueue(const std::string& name);
 
+       bool isPlaying() const;
+
+       void setPosition(Vector3 position);
+       void setVelocity(Vector3 velocity);
        void setGain(Scalar gain);
+       void setPitch(Scalar pitch);
+       void setLooping(bool looping);
 
        static std::string getPath(const std::string& name);
 
@@ -103,17 +115,6 @@ public:
 };
 
 
-class SoundStream : public Sound
-{
-public:
-       SoundStream(const std::string& name);
-
-       void update(Scalar t, Scalar dt);
-
-       static std::string getPath(const std::string& name);
-};
-
-
 } // namespace Mf
 
 #endif // _MOOF_SOUND_HH_
index fb17f1d66e1ac3a89c99c95a4cec94d9412c0dde..bc7aae220416687747de6f29bf07c39fc39a3f67 100644 (file)
 #include <ctime>
 #include <stdexcept>
 
+#include "Log.hh"
 #include "Timer.hh"
 
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include <SDL/SDL.h>
+
 
 namespace Mf {
 
@@ -100,8 +103,6 @@ void sleep(Scalar seconds, bool absolute)
 // SDL only promises centisecond accuracy, but that's better than a kick in the
 // butt.
 
-#include <SDL/SDL.h>
-
 Scalar getTicks()
 {
        Uint32 ms = SDL_GetTicks();
@@ -111,8 +112,7 @@ Scalar getTicks()
 void sleep(Scalar seconds, bool absolute)
 {
        if (absolute) seconds -= getTicks();
-
-       SDL_Delay(Uint32(seconds * 1000.0));
+       SDL_Delay(Uint32(cml::clamp(int(seconds * 1000.0), 0, 1000)));
 }
 
 #endif // HAVE_CLOCK_GETTIME
index 9ea4b373d90ec15e2a53cb5eba8c03e8155cb359..d36f6da3ef8f52f9f8e61d82c85a4f5cb6f655b4 100644 (file)
 
 #include "YoinkApp.hh"
 
-#include <SDL/SDL_sound.h>
-#include <AL/al.h>
-#include <AL/alut.h>
-
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -106,18 +102,16 @@ static std::string iconFile()
 
 YoinkApp::YoinkApp(int argc, char* argv[]) :
        Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile()),
-       music("NightFusion"),
+       music("NightFusionIntro"),
        punchSound("RobotPunch")
 {
        Mf::dispatcher::addHandler("video.context_recreated",
                        boost::bind(&YoinkApp::contextRecreated, this, _1), this);
        setupGL();
 
-       Mf::Scalar fade[2] = {0.0, 1.0};
-       musicFade.init(fade, 0.0);
-       music.play();
-
-       state = 0.0;
+       music.setLooping(true);
+       music.enqueue("NightFusionLoop");
+       music.stream();
 
        heroine = Character::alloc("RobotTrooper");
        heroine->getAnimation().startSequence("Run");
@@ -189,17 +183,14 @@ void YoinkApp::contextRecreated(const Mf::Notification* note)
 
 void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt)
 {
-       //dt *= 0.2;
+       //dt *= 0.5;
 
-       musicFade.update(dt);
        music.update(t, dt);
-       music.setGain(musicFade.getValue());
-       
        fadeIn.update(dt);
-
        camera.update(t, dt);
-
        heroine->update(t, dt);
+
+       // reinsert heroine
        heroine->treeNode = testScene->getOctree()->reinsert(heroine, heroine->treeNode);
        testScene->getOctree()->print(heroine->treeNode);
        
@@ -209,45 +200,26 @@ void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt)
        interp.update(dt);
        hud.setBar1Progress(interp.getValue());
        hud.setBar2Progress(1.0 - interp.getValue());
-
-       prevstate = state;
-       state += dt;
 }
 
 
 void YoinkApp::draw(Mf::Scalar alpha)
 {
-       //Mf::Vector4 meh;
-       //meh.random(0.0, 1.0);
-       //static Mf::Vector4 c1(meh);
-
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-       //Mf::Scalar drawstate = cml::lerp(prevstate, state, alpha);
-       //Mf::Scalar sinstate = std::sin(drawstate);
-       //Mf::Scalar cosstate = std::cos(drawstate);
-       
-
        glMatrixMode(GL_MODELVIEW);
-       //glLoadIdentity();
-
-       //glRotatef(drawstate*15.0f, 0.0, 1.0, 0.0);
-       //glTranslatef(x, y, z);
        glLoadMatrix(camera.getModelviewMatrix().data());
 
        // DRAW THE SCENE
        Mf::Texture::resetBind();
        testScene->draw(alpha, camera);
 
-
-
        //heroine->draw(alpha);
        heroine->getAabb().draw();
 
-
        hud.draw();
 
-
+       // DRAW FADE
        glEnable(GL_BLEND);
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
@@ -272,123 +244,6 @@ void YoinkApp::draw(Mf::Scalar alpha)
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
-
-       /*
-       glLoadIdentity();
-       
-       someChar->getTilemap().bind();
-       glColor3f(1.0, 1.0, 1.0);
-
-       Mf::Tilemap::Index heroFrame = someChar->getAnimation().getFrame();
-
-       Mf::Scalar coords[8];
-       someChar->getTilemap().getTileCoords(heroFrame, coords);
-
-       glBegin(GL_QUADS);
-               glTexCoord2f(coords[0], coords[1]);
-               glVertex3f(-1.0, 0.0, 0.0);
-               glTexCoord2f(coords[2], coords[3]);
-               glVertex3f(0.0, 0.0, 0.0);
-               glTexCoord2f(coords[4], coords[5]);
-               glVertex3f(0.0, 1.0, 0.0);
-               glTexCoord2f(coords[6], coords[7]);
-               glVertex3f(-1.0, 1.0, 0.0);
-       glEnd();
-
-
-       someChar->getTilemap().getTileCoords(heroFrame, coords,
-                       Mf::Tilemap::REVERSE);
-
-       glBegin(GL_QUADS);
-               glTexCoord2f(coords[0], coords[1]);
-               glVertex3f(0.0, 0.0, 0.0);
-               glTexCoord2f(coords[2], coords[3]);
-               glVertex3f(1.0, 0.0, 0.0);
-               glTexCoord2f(coords[4], coords[5]);
-               glVertex3f(1.0, 1.0, 0.0);
-               glTexCoord2f(coords[6], coords[7]);
-               glVertex3f(0.0, 1.0, 0.0);
-       glEnd();
-
-       glColor4f(1.0,0.0,0.0,0.5);
-
-       glBindTexture(GL_TEXTURE_2D, 0);
-       glColor4v(c1.data());
-
-       glRectd(-cosstate, -sinstate, sinstate, cosstate);
-       glRectf(0.0f, 0.0f, sinstate, cosstate);
-
-       font->bind();
-       
-       font->getTileCoords('c', coords);
-
-       glBegin(GL_QUADS);
-               glTexCoord2f(coords[0], coords[1]);
-               glVertex3f(-1.0, 0.0, 0.0);
-               glTexCoord2f(coords[2], coords[3]);
-               glVertex3f(0.0, 0.0, 0.0);
-               glTexCoord2f(coords[4], coords[5]);
-               glVertex3f(0.0, 1.0, 0.0);
-               glTexCoord2f(coords[6], coords[7]);
-               glVertex3f(-1.0, 1.0, 0.0);
-       glEnd();
-
-       font->getTileCoords('h', coords);
-
-       glBegin(GL_QUADS);
-               glTexCoord2f(coords[0], coords[1]);
-               glVertex3f(0.0, 0.0, 0.0);
-               glTexCoord2f(coords[2], coords[3]);
-               glVertex3f(1.0, 0.0, 0.0);
-               glTexCoord2f(coords[4], coords[5]);
-               glVertex3f(1.0, 1.0, 0.0);
-               glTexCoord2f(coords[6], coords[7]);
-               glVertex3f(0.0, 1.0, 0.0);
-       glEnd();
-
-       font->getTileCoords('a', coords);
-
-       glBegin(GL_QUADS);
-               glTexCoord2f(coords[0], coords[1]);
-               glVertex3f(-1.0, -1.0, 0.0);
-               glTexCoord2f(coords[2], coords[3]);
-               glVertex3f(0.0, -1.0, 0.0);
-               glTexCoord2f(coords[4], coords[5]);
-               glVertex3f(0.0, 0.0, 0.0);
-               glTexCoord2f(coords[6], coords[7]);
-               glVertex3f(-1.0, 0.0, 0.0);
-       glEnd();
-
-       font->getTileCoords('z', coords);
-
-       glBegin(GL_QUADS);
-               glTexCoord2f(coords[0], coords[1]);
-               glVertex3(0.0, -1.0, 0.0);
-               glTexCoord2f(coords[2], coords[3]);
-               glVertex3(1.0, -1.0, 0.0);
-               glTexCoord2f(coords[4], coords[5]);
-               glVertex3(1.0, 0.0, 0.0);
-               glTexCoord2f(coords[6], coords[7]);
-               glVertex3(0.0, 0.0, 0.0);
-       glEnd();
-
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glDisable(GL_DEPTH_TEST);
-       
-       glBindTexture(GL_TEXTURE_2D, 0);
-       glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
-
-       glBegin(GL_LINES);
-               glVertex2f(0.0f, 0.0f);
-               glVertex2v(interp.getState(alpha).data());
-       glEnd();
-
-       glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
-       glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
-
-       glDisable(GL_BLEND);
-       glEnable(GL_DEPTH_TEST);*/
 }
 
 void YoinkApp::handleEvent(const Mf::Event& event)
@@ -424,7 +279,7 @@ void YoinkApp::handleEvent(const Mf::Event& event)
                        }
                        else if (event.key.keysym.sym == SDLK_p)
                        {
-                               music.togglePlayPause();
+                               music.toggle();
                                break;
                        }
                        else if (event.key.keysym.sym == SDLK_l)
@@ -464,8 +319,16 @@ int main(int argc, char* argv[])
                          << "Send patches and bug reports to <"
                          PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
 
-#if ! NDEBUG
+#if            YOINK_LOGLEVEL >= 4
        Mf::setLogLevel(Mf::LOG_DEBUG);
+#elif  YOINK_LOGLEVEL >= 3
+       Mf::setLogLevel(Mf::LOG_INFO);
+#elif  YOINK_LOGLEVEL >= 2
+       Mf::setLogLevel(Mf::LOG_WARNING);
+#elif  YOINK_LOGLEVEL >= 1
+       Mf::setLogLevel(Mf::LOG_ERROR);
+#elif  YOINK_LOGLEVEL
+       Mf::setLogLevel(Mf::LOG_NONE);
 #endif
 
        int status = 0;
index 6a947f9d8dfcb51408798258b2fea42f4c963589..ad8d694e62619aee1c947e50f901e864310db95d 100644 (file)
@@ -69,8 +69,7 @@ private:
        void setupGL();
        void contextRecreated(const Mf::Notification* note);
 
-       Mf::Lerps musicFade;
-       Mf::SoundStream music;
+       Mf::Sound music;
 
        CharacterP heroine;
        Mf::Sound punchSound;
@@ -82,9 +81,6 @@ private:
        Mf::Camera camera;
        Mf::SceneP testScene;
 
-       Mf::Scalar state;
-       Mf::Scalar prevstate;
-
        Hud hud;
 };
 
This page took 0.073279 seconds and 4 git commands to generate.