From: <kla...@us...> - 2009-03-28 22:13:33
|
Revision: 12547 http://vegastrike.svn.sourceforge.net/vegastrike/?rev=12547&view=rev Author: klaussfreire Date: 2009-03-28 22:13:28 +0000 (Sat, 28 Mar 2009) Log Message: ----------- Incomplete stuff comitted - just a precaution Modified Paths: -------------- branches/audio/vegastrike/CMakeLists.txt branches/audio/vegastrike/objconv/CMakeLists.txt branches/audio/vegastrike/objconv/cargoconvert.cpp branches/audio/vegastrike/setup/CMakeLists.txt branches/audio/vegastrike/src/audio/Exceptions.h branches/audio/vegastrike/src/audio/Format.h branches/audio/vegastrike/src/audio/Listener.cpp branches/audio/vegastrike/src/audio/Listener.h branches/audio/vegastrike/src/audio/RenderableListener.h branches/audio/vegastrike/src/audio/RenderableSource.h branches/audio/vegastrike/src/audio/Renderer.cpp branches/audio/vegastrike/src/audio/Renderer.h branches/audio/vegastrike/src/audio/SceneManager.cpp branches/audio/vegastrike/src/audio/Source.cpp branches/audio/vegastrike/src/audio/Source.h branches/audio/vegastrike/src/audio/SourceTemplate.h branches/audio/vegastrike/src/audio/Types.h branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableListener.cpp branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.cpp branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.h branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALSimpleSound.cpp branches/audio/vegastrike/src/cmd/ai/firekeyboard.cpp branches/audio/vegastrike/src/cmd/script/mission.h branches/audio/vegastrike/src/cmd/script/script_callbacks.cpp branches/audio/vegastrike/src/cmd/unit.cpp branches/audio/vegastrike/src/cmd/unit_collide.cpp branches/audio/vegastrike/src/ffmpeg_init.cpp branches/audio/vegastrike/src/gfx/cockpit.cpp branches/audio/vegastrike/src/gfx/mesh.cpp branches/audio/vegastrike/src/gfx/mesh.h branches/audio/vegastrike/src/gfx/mesh_gfx.cpp branches/audio/vegastrike/src/gfx/nav/drawgalaxy.cpp branches/audio/vegastrike/src/gfx/vdu.cpp branches/audio/vegastrike/src/gfx/vid_file.cpp branches/audio/vegastrike/src/gldrv/gl_clip.cpp branches/audio/vegastrike/src/gldrv/gl_light_pick.cpp branches/audio/vegastrike/src/gldrv/gl_matrix_hack.cpp branches/audio/vegastrike/src/macosx_math.cpp branches/audio/vegastrike/src/python/star_system_exports.h branches/audio/vegastrike/src/star_system_generic.h branches/audio/vegastrike/src/star_system_xml.cpp branches/audio/vegastrike/src/universe_generic.cpp branches/audio/vegastrike/src/universe_util.cpp branches/audio/vegastrike/src/universe_util.h branches/audio/vegastrike/src/universe_util_server.cpp Added Paths: ----------- branches/audio/vegastrike/objconv/objscale.cpp branches/audio/vegastrike/src/audio/Matrix.h branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.cpp branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.h Modified: branches/audio/vegastrike/CMakeLists.txt =================================================================== --- branches/audio/vegastrike/CMakeLists.txt 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/CMakeLists.txt 2009-03-28 22:13:28 UTC (rev 12547) @@ -781,8 +781,12 @@ # End Debug Crap # Vssetup Sub build file -#add_subdirectory(setup) +add_subdirectory(setup) +ADD_CUSTOM_TARGET(vssetup DEPENDS setup/vssetup COMMAND ln -fs ${vsUTCS_BINARY_DIR}/setup/vssetup vssetup || true) + # Add other utilies here add_subdirectory(objconv) +ADD_CUSTOM_TARGET(mesher DEPENDS objconv/mesher COMMAND ln -fs ${vsUTCS_BINARY_DIR}/objconv/mesher mesher || true) + Modified: branches/audio/vegastrike/objconv/CMakeLists.txt =================================================================== --- branches/audio/vegastrike/objconv/CMakeLists.txt 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/objconv/CMakeLists.txt 2009-03-28 22:13:28 UTC (rev 12547) @@ -9,5 +9,35 @@ SET(REPLACE_SOURCES replace.cpp) add_executable(replace ${REPLACE_SOURCES}) +#find Expat +find_package(EXPAT REQUIRED) +IF(EXPAT_FOUND) + SET(MSH_INCLUDES ${MSH_INCLUDES} ${EXPAT_INCLUDE_DIRS}) + SET(MSH_LIBS ${MSH_LIBS} ${EXPAT_LIBRARIES}) +ELSE(EXPAT_FOUND) + message("We can't find expat for XML crap") +ENDIF(EXPAT_FOUND) +SET(MESHER_SOURCES + mesher/Converter.cpp + mesher/from_BFXM.cpp + mesher/from_obj.cpp + mesher/main.cpp + mesher/to_BFXM.cpp +# mesher/to_OgreMesh.cpp + mesher/to_obj.cpp + ../src/xml_support.cpp + mesher/Modules/BFXM_to_Wavefront.cpp + mesher/Modules/BFXM_to_XMesh.cpp + mesher/Modules/Convert.cpp + mesher/Modules/Dims.cpp + mesher/Modules/OldSyntax.cpp + mesher/Modules/Wavefront_to_BFXM.cpp + mesher/Modules/XMesh_to_BFXM.cpp +) +include_directories(${MSH_INCLUDES} mesher) +add_executable(mesher ${MESHER_SOURCES}) +target_link_libraries(mesher ${MSH_LIBS}) + + Modified: branches/audio/vegastrike/objconv/cargoconvert.cpp =================================================================== --- branches/audio/vegastrike/objconv/cargoconvert.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/objconv/cargoconvert.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -1,5 +1,7 @@ #include <stdio.h> -#include <iostream.h> +#include <string.h> +#include <stdlib.h> +#include <iostream> #include <map> #include <vector> #include <string> @@ -17,6 +19,7 @@ } Averaging& operator +=(int a) { samples.push_back(a); + return *this; } float spread() { int min=-1; Copied: branches/audio/vegastrike/objconv/objscale.cpp (from rev 12525, trunk/vegastrike/objconv/objscale.cpp) =================================================================== --- branches/audio/vegastrike/objconv/objscale.cpp (rev 0) +++ branches/audio/vegastrike/objconv/objscale.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +float huge=.5e38; +int main (int argc,char**argv) { + int i; + float scalex=1; + float scaley=1; + float scalez=1; + float transx=0; + float transy=0; + float transz=0; + float minx=huge; + float miny=huge; + float minz=huge; + float maxx=-huge; + float maxy=-huge; + float maxz=-huge; + for (i=0;i<(unsigned int)argc;++i) { + char match=1; + int j; + if (strncmp(argv[i],"-scalex",7)==0) { + scalex = (float)atof(argv[i]+7); + }else if (strncmp(argv[i],"-scaley",7)==0) { + scaley = (float)atof(argv[i]+7); + }else if (strncmp(argv[i],"-scalez",7)==0) { + scalez = (float)atof(argv[i]+7); + }else if (strncmp(argv[i],"-transx",7)==0) { + transx = (float)atof(argv[i]+7); + }else if (strncmp(argv[i],"-transy",7)==0) { + transy = (float)atof(argv[i]+7); + }else if (strncmp(argv[i],"-transz",7)==0) { + transz = (float)atof(argv[i]+7); + }else{ + match=0; + } + if (match==1) { + for (j=i+1;j<argc;++j) argv[j-1]=argv[j]; + argc--; + i--; + } + } + printf ("Scaling the mesh to (%f %f %f)\ntranslating to (%f %f %f)\n", + scalex,scaley,scalez,transx,transy,transz); + FILE * in=fopen(argv[1],"rb"); + FILE * out=fopen(argv[2],"wb"); + char line[16384]; + while (fgets(line,16384,in)) { + double x=0,y=0,z=0; + if (3==sscanf(line,"v %lf %lf %lf",&x,&y,&z)) { + if (x<minx) + minx=x; + if (y<miny) + miny=y; + if (z<minz) + minz=z; + if (x>maxx) + maxx=x; + if (y>maxy) + maxy=y; + if (z>maxz) + maxz=z; + x+=transx; + x*=scalex; + y+=transy; + y*=scaley; + z+=transz; + z*=scalez; + fprintf(out,"v %lf %lf %lf\n",x,y,z); + }else{ + fprintf (out,"%s",line); + } + } + printf ("Translating bounds of\n[(%f %f %f) - (%f %f %f) ]\nto bounds of\n[(%f %f %f) - (%f %f %f)]\n", + minx,miny,minz,maxx,maxy,maxz, + scalex*(minx+transx),scaley*(miny+transy),scalez*(minz+transz), + scalex*(maxx+transx),scaley*(maxy+transy),scalez*(maxz+transz)); + return 0; +} Modified: branches/audio/vegastrike/setup/CMakeLists.txt =================================================================== --- branches/audio/vegastrike/setup/CMakeLists.txt 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/setup/CMakeLists.txt 2009-03-28 22:13:28 UTC (rev 12547) @@ -22,3 +22,4 @@ add_definitions(${GTK_CFLAGS}) include_directories(${vsUTCS_SOURCE_DIR}/setup/src/include ${vsUTCS_SOURCE_DIR}/src/common ${vsUTCS_BINARY_DIR} ${GTK2_INCLUDE_DIRS}) target_link_libraries(vssetup ${GTK_LIBS}) + Modified: branches/audio/vegastrike/src/audio/Exceptions.h =================================================================== --- branches/audio/vegastrike/src/audio/Exceptions.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Exceptions.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -155,6 +155,20 @@ explicit NotImplementedException(const std::string &name) : Exception(name + " has not been implemented yet") {} }; + + /** + * Unsupported format requested + */ + class UnsupportedFormatException : public Exception { + Format format; + public: + explicit UnsupportedFormatException(const std::string &where, const Format &fmt) : + Exception(std::string("Unsupported format (" + where + ")")), + format(fmt) + {} + + const Format& getFormat() const throw() { return format; } + }; /** * Ran out of memory while performing some operation Modified: branches/audio/vegastrike/src/audio/Format.h =================================================================== --- branches/audio/vegastrike/src/audio/Format.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Format.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -44,4 +44,4 @@ }; -#endif//__AUDIO_STREAM_H__INCLUDED__ +#endif//__AUDIO_FORMAT_H__INCLUDED__ Modified: branches/audio/vegastrike/src/audio/Listener.cpp =================================================================== --- branches/audio/vegastrike/src/audio/Listener.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Listener.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -12,10 +12,11 @@ Listener::Listener() throw() : cosAngleRange(1,1), position(0,0,0), - atDirection(0,0,1), + atDirection(0,0,-1), upDirection(0,1,0), velocity(0,0,0), - radius(1) + radius(1), + worldToLocal(1) // set to identity, given default settings { } @@ -36,4 +37,33 @@ dirty.attributes = 1; } + void Listener::update(RenderableListener::UpdateFlags flags) throw() + { + if (!dirty.attributes) + flags &= ~RenderableListener::UPDATE_ATTRIBUTES; + if (!dirty.location) + flags &= ~RenderableListener::UPDATE_LOCATION; + + if (getRenderable().get() != 0) + getRenderable()->update(flags); + + if (flags & RenderableListener::UPDATE_ATTRIBUTES) + dirty.attributes = 0; + + if (flags & RenderableListener::UPDATE_LOCATION) { + worldToLocal = + Matrix3( + atDirection.cross(upDirection), + upDirection, + -atDirection + ).inverse(); + dirty.location = 0; + } + } + + Vector3 Listener::toLocalDirection(Vector3 dir) const throw() + { + return worldToLocal * dir; + } + }; Modified: branches/audio/vegastrike/src/audio/Listener.h =================================================================== --- branches/audio/vegastrike/src/audio/Listener.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Listener.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -6,12 +6,10 @@ #include "Exceptions.h" #include "Types.h" +#include "RenderableListener.h" namespace Audio { - // Some forward declarations of referenced-yet-unused classes - class RenderableListener; - /** * Listener class * @@ -34,6 +32,8 @@ SharedPtr<UserData> userDataPtr; SharedPtr<RenderableListener> rendererDataPtr; + Matrix3 worldToLocal; + protected: /** Notify implementations after position and/or attributes changes * @remarks Implementations use the "dirty" member struct to precisely know and @@ -118,6 +118,23 @@ void setUserData(SharedPtr<UserData> ptr) throw() { userDataPtr = ptr; } + /** @see RenderableListener::update + * @note It's not just a convenience, the abstract listener has to update + * its internal dirty flags and other things as well. + */ + void update(RenderableListener::UpdateFlags flags) throw(); + + + /** + * Return the direction 'dir' in a local coordinate system centered at + * the listener's position, with the -Z axis pointing forward, + * +X pointing rightward and +Y pointing upwards (the OpenGL way). + * @note The attributes used are those set during the last update() + * @note The behavior is unspecified if there was no previous call to update(). + */ + Vector3 toLocalDirection(Vector3 dir) const throw(); + + }; }; Added: branches/audio/vegastrike/src/audio/Matrix.h =================================================================== --- branches/audio/vegastrike/src/audio/Matrix.h (rev 0) +++ branches/audio/vegastrike/src/audio/Matrix.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -0,0 +1,213 @@ +// +// C++ Interface: Audio::Codec +// +#ifndef __AUDIO_MATRIX_H__INCLUDED__ +#define __AUDIO_MATRIX_H__INCLUDED__ + +#include <math.h> +#include "Vector.h" + +namespace Audio { + + template<typename T> class TMatrix3 { + public: + T m[3][3]; + + TMatrix3() {} + TMatrix3(T m11, T m12, T m13, T m21, T m22, T m23, T m31, T m32, T m33) + { + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; + } + explicit TMatrix3(T s) + { + m[0][0] = s; m[0][1] = 0; m[0][2] = 0; + m[1][0] = 0; m[1][1] = s; m[1][2] = 0; + m[2][0] = 0; m[2][1] = 0; m[2][2] = s; + } + + template<typename Y> + TMatrix3(const TMatrix3<Y> &o) + { + m[0][0] = o.m[0][0]; m[0][1] = o.m[0][1]; m[0][2] = o.m[0][2]; + m[1][0] = o.m[1][0]; m[1][1] = o.m[1][1]; m[1][2] = o.m[1][2]; + m[2][0] = o.m[2][0]; m[2][1] = o.m[2][1]; m[2][2] = o.m[2][2]; + } + + template<typename Y> + TMatrix3(const TVector3<Y> &c1, const TVector3<Y> &c2, const TVector3<Y> &c3) + { + m[0][0] = c1.x; m[0][1] = c2.x; m[0][2] = c3.x; + m[1][0] = c1.y; m[1][1] = c2.y; m[1][2] = c3.y; + m[2][0] = c1.z; m[2][1] = c2.z; m[2][2] = c3.z; + } + + template<typename Y> + TMatrix3<T>& operator=(const TMatrix<Y> &o) + { + m[0][0] = o.m[0][0]; m[0][1] = o.m[0][1]; m[0][2] = o.m[0][2]; + m[1][0] = o.m[1][0]; m[1][1] = o.m[1][1]; m[1][2] = o.m[1][2]; + m[2][0] = o.m[2][0]; m[2][1] = o.m[2][1]; m[2][2] = o.m[2][2]; + return *this; + } + + TMatrix3<T>& operator+=(const TMatrix3<T> &other) + { + m[0][0] += o.m[0][0]; m[0][1] += o.m[0][1]; m[0][2] += o.m[0][2]; + m[1][0] += o.m[1][0]; m[1][1] += o.m[1][1]; m[1][2] += o.m[1][2]; + m[2][0] += o.m[2][0]; m[2][1] += o.m[2][1]; m[2][2] += o.m[2][2]; + return *this; + } + + TMatrix3<T>& operator-=(const TMatrix3<T> &other) + { + m[0][0] -= o.m[0][0]; m[0][1] -= o.m[0][1]; m[0][2] -= o.m[0][2]; + m[1][0] -= o.m[1][0]; m[1][1] -= o.m[1][1]; m[1][2] -= o.m[1][2]; + m[2][0] -= o.m[2][0]; m[2][1] -= o.m[2][1]; m[2][2] -= o.m[2][2]; + return *this; + } + + TMatrix3<T>& operator*=(const TMatrix3<T> &other) + { + #define DOT(m,om,r,c) (m[r][0]*om[0][c] + m[r][1]*om[1][c] + m[r][2]*om[2][c]) + TMatrix3<T> rv; + rv.m[0][0] = DOT(m,o.m,0,0); + rv.m[0][1] = DOT(m,o.m,0,1); + rv.m[0][2] = DOT(m,o.m,0,2); + rv.m[1][0] = DOT(m,o.m,1,0); + rv.m[1][1] = DOT(m,o.m,1,1); + rv.m[1][2] = DOT(m,o.m,1,2); + rv.m[2][0] = DOT(m,o.m,2,0); + rv.m[2][1] = DOT(m,o.m,2,1); + rv.m[2][2] = DOT(m,o.m,2,2); + #undef DOT + return *this; + } + + TVector3<T>& operator*=(T t) + { + m[0][0] *= t; m[0][1] *= t; m[0][2] *= t; + m[1][0] *= t; m[1][1] *= t; m[1][2] *= t; + m[2][0] *= t; m[2][1] *= t; m[2][2] *= t; + return *this; + } + + TMatrix3<T>& operator/=(const TMatrix3<T> &other) + { + (*this) *= other.inverse(); + return *this; + } + + TMatrix3<T>& operator/=(T t) + { + (*this) *= T(1) / t; + return *this; + } + + TMatrix3<T> operator+(const TMatrix3<T> &o) const + { + return TMatrix3<T>( + m[0][0]+o.m[0][0], m[0][1]+o.m[0][1], m[0][2]+o.m[0][2], + m[1][0]+o.m[1][0], m[1][1]+o.m[1][1], m[1][2]+o.m[1][2], + m[2][0]+o.m[2][0], m[2][1]+o.m[2][1], m[2][2]+o.m[2][2] + ); + } + + TMatrix3<T> operator-(const TMatrix3<T> &o) const + { + return TMatrix3<T>( + m[0][0]-o.m[0][0], m[0][1]-o.m[0][1], m[0][2]-o.m[0][2], + m[1][0]-o.m[1][0], m[1][1]-o.m[1][1], m[1][2]-o.m[1][2], + m[2][0]-o.m[2][0], m[2][1]-o.m[2][1], m[2][2]-o.m[2][2] + ); + } + + TMatrix3<T> operator*(const TMatrix3<T> &o) const + { + #define DOT(m,om,r,c) (m[r][0]*om[0][c] + m[r][1]*om[1][c] + m[r][2]*om[2][c]) + return TMatrix3<T>( + DOT(m,o.m,0,0), DOT(m,o.m,0,1), DOT(m,o.m,0,2), + DOT(m,o.m,1,0), DOT(m,o.m,1,1), DOT(m,o.m,1,2), + DOT(m,o.m,2,0), DOT(m,o.m,2,1), DOT(m,o.m,2,2) + ); + #undef DOT + } + + TMatrix3<T> operator/(const TMatrix3<T> &other) const + { + return (*this) * other.inverse(); + } + + TMatrix3<T> operator*(T t) const + { + return TMatrix3<T>( + m[0][0]*t, m[0][1]*t, m[0][2]*t, + m[1][0]*t, m[1][1]*t, m[1][2]*t, + m[2][0]*t, m[2][1]*t, m[2][2]*t + ); + } + + TMatrix3<T> operator/(T t) const + { + return (*this) * (T(1) / t); + } + + template<typename Y> + TVector3<Y> operator*(const TVector3<Y> &t) const + { + return TVector3<Y>( + m[0][0]*t.x, m[0][1]*t.y, m[0][2]*t.z, + m[1][0]*t.x, m[1][1]*t.y, m[1][2]*t.z, + m[2][0]*t.x, m[2][1]*t.y, m[2][2]*t.z + ); + } + + TMatrix3<T> inverse() const + { + TMatrix3<T> rv; + + /* + compute adjoint matrix, + then divide by the determinant + */ + + //determinante + float det = + +m[0][0] * m[1][1] * m[2][2] + +m[1][0] * m[2][1] * m[0][2] + +m[2][0] * m[0][1] * m[1][2] + + -m[0][2] * m[1][1] * m[2][0] + -m[1][2] * m[2][1] * m[0][0] + -m[2][2] * m[0][1] * m[1][0]; + float idet = T(1) / det; + + rv.m[0][0] =+(m[1][1] * m[2][2] - m[1][2] * m[2][1]) * idet; + rv.m[0][1] =-(m[1][0] * m[2][2] - m[1][2] * m[2][0]) * idet; + rv.m[0][2] =+(m[1][0] * m[2][1] - m[1][1] * m[2][0]) * idet; + + rv.m[1][0] =-(m[0][1] * m[2][2] - m[0][2] * m[2][1]) * idet; + rv.m[1][1] =+(m[0][0] * m[2][2] - m[0][2] * m[2][0]) * idet; + rv.m[1][2] =-(m[0][0] * m[2][1] - m[0][1] * m[2][0]) * idet; + + rv.m[2][0] =+(m[0][1] * m[1][2] - m[0][2] * m[1][1]) * idet; + rv.m[2][1] =-(m[0][0] * m[1][2] - m[0][2] * m[1][0]) * idet; + rv.m[2][2] =+(m[0][0] * m[1][1] - m[0][1] * m[1][0]) * idet; + + return rv; + } + + TMatrix3<T> transpose() const + { + return TMatrix3<T>( + m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2] + ); + } + }; + +}; + +#endif//__AUDIO_VECTOR_H__INCLUDED__ Modified: branches/audio/vegastrike/src/audio/RenderableListener.h =================================================================== --- branches/audio/vegastrike/src/audio/RenderableListener.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/RenderableListener.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -40,10 +40,10 @@ virtual ~RenderableListener(); enum UpdateFlags { - UPDATE_ALL, - UPDATE_LOCATION, - UPDATE_ATTRIBUTES, - UPDATE_EFFECTS + UPDATE_ALL = 0x07, + UPDATE_LOCATION = 0x01, + UPDATE_ATTRIBUTES = 0x02, + UPDATE_EFFECTS = 0x04 }; /** Get the attached listener */ @@ -52,6 +52,7 @@ /** Update the underlying API with dirty attributes * @param flags You may specify which attributes to update. Not all attributes are * equally costly, so you'll want to ease up on some, pump up some others. + * You can or-combine flags. * @remarks Although the implementation may throw exceptions, the interface will * ignore them (just log them or something like that). Updates are non-critical * and may fail silently. Modified: branches/audio/vegastrike/src/audio/RenderableSource.h =================================================================== --- branches/audio/vegastrike/src/audio/RenderableSource.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/RenderableSource.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -44,10 +44,11 @@ virtual ~RenderableSource(); enum UpdateFlags { - UPDATE_ALL, - UPDATE_LOCATION, - UPDATE_ATTRIBUTES, - UPDATE_EFFECTS + UPDATE_ALL = 0x0F, + UPDATE_LOCATION = 0x01, + UPDATE_ATTRIBUTES = 0x02, + UPDATE_EFFECTS = 0x04, + UPDATE_GAIN = 0x08 }; /** Play the source from the specified timestamp @@ -76,6 +77,7 @@ /** Update the underlying API with dirty attributes * @param flags You may specify which attributes to update. Not all attributes are * equally costly, so you'll want to ease up on some, pump up some others. + * You may or-combine flags. * @param sceneListener A reference listener. If it is the root listener attached * to the renderer, no special translation is done, but if it is not, coordinates * will be first translated to listener-space. Modified: branches/audio/vegastrike/src/audio/Renderer.cpp =================================================================== --- branches/audio/vegastrike/src/audio/Renderer.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Renderer.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -26,4 +26,17 @@ { return meterDistance; } + + void Renderer::setOutputFormat(const Format &format) + throw() + { + outputFormat = format; + } + + const Format& Renderer::getOutputFormat() const + throw() + { + return outputFormat; + } + }; Modified: branches/audio/vegastrike/src/audio/Renderer.h =================================================================== --- branches/audio/vegastrike/src/audio/Renderer.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Renderer.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -10,6 +10,7 @@ #include "Exceptions.h" #include "Singleton.h" #include "Types.h" +#include "Format.h" #include "vsfilesystem.h" @@ -36,6 +37,7 @@ { private: Scalar meterDistance; + Format outputFormat; public: /** Initialize the renderer with default or config-driven settings. @@ -105,6 +107,24 @@ */ virtual Scalar getMeterDistance() const throw(); + + + /** Sets the (preferred) output format. + * @remarks Renderers are encouraged to set their effective output format + * to the closest "better" format, where better is defined as either + * having heigher sampling frequency, bit depth, or number of channels. + * The effective output format, if known, must be reflected in + * subsequent calls to getOutputFormat. + */ + virtual void setOutputFormat(const Format &format) throw(Exception); + + /** Gets the distance in world units that represents one meter. + * @see setMeterDistance + */ + virtual const Format& getOutputFormat() const throw(); + + + }; }; Modified: branches/audio/vegastrike/src/audio/SceneManager.cpp =================================================================== --- branches/audio/vegastrike/src/audio/SceneManager.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/SceneManager.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -31,9 +31,18 @@ SharedPtr<Source> source; SharedPtr<Scene> scene; + /** + * If true, an update phase will start playing the source. + * Set when the activation phase attaches a renderable (or decides to resume one), + * since it cannot do so immediately or positional glitches would be apparent. + */ + int needsActivation : 1; + + SourceRef(const SharedPtr<Source> &src, const SharedPtr<Scene> &scn) : source(src), - scene(scn) + scene(scn), + needsActivation(0) {} bool operator==(const SourceRef &o) const @@ -139,6 +148,8 @@ source->setPerFrequencyRadiusRatios( tpl->getPerFrequencyRadiusRatios() ); source->setReferenceFreqs( tpl->getReferenceFreqs() ); source->setGain( tpl->getGain() ); + source->setAttenuated( tpl->getAttenuated() ); + source->setRelative( tpl->getRelative() ); return source; } @@ -377,12 +388,24 @@ bool needListenerUpdate = ((realTime - getListenerUpdateFrequency()) >= data->lastListenerUpdateTime); bool needListenerAttUpdate = ((realTime - getAttributeUpdateFrequency()) >= data->lastListenerAttUpdateTime); + // If we have an activation phase, in order for it to be effective + // we'll need an update phase as well. + needPosUpdate = needPosUpdate || needActivation; + if (needActivation) { activationPhaseImpl(); data->lastActivationTime = realTime; } + if (needListenerUpdate) { + updateListenerImpl(needListenerAttUpdate); + + data->lastListenerUpdateTime = realTime; + if (needListenerAttUpdate) + data->lastListenerAttUpdateTime = realTime; + } + if (needPosUpdates || needAttUpdates) { updateSourcesImpl(needAttUpdates); @@ -390,14 +413,6 @@ if (needAttUpdates) data->lastAttributeUpdateTime = realTime; } - - if (needListenerUpdate) { - updateListenerImpl(needListenerAttUpdate); - - data->lastListenerUpdateTime = realTime; - if (needListenerAttUpdate) - data->lastListenerAttUpdateTime = realTime; - } } struct SourcePriorityRef { @@ -487,10 +502,26 @@ renderer->detach(sit->source); } - // Attach newly activated sources - for (SceneManagerData::SourceRefSet::iterator nit = newSources.begin(); nit != newSources.end(); ++nit) { - if (data->activeSources.find(*nit) == data->activeSources.end()) + // Attach newly activated sources, detach and remove finished ones + for (SceneManagerData::SourceRefSet::iterator nit = newSources.begin(); nit != newSources.end(); ) { + bool erase = false; + if (data->activeSources.find(*nit) == data->activeSources.end()) { + // Newly activated source renderer->attach(nit->source); + nit->needsActivation = true; + } else { + // Pre-existing source - check if it's finished + if (!nit->source->getRenderable()->isPlaying()) { + // Finished - detach stop and remove + renderer->detach(nit->source); + nit->source->stopPlaying(); + erase = true; + } + } + if (erase) + newSources.erase(nit++); + else + ++nit; } // Swap sets @@ -500,23 +531,42 @@ void SceneManager::updateSourcesImpl(bool withAttributes) throw(Exception) { + // Two-pass stuff. + + // First, update attributes (mostly location) RenderableSource::UpdateFlags updateFlags = withAttributes ? RenderableSource::UPDATE_ALL : RenderableSource::UPDATE_LOCATION; - for (SceneManagerData::SourceRefSet::const_iterator it = data->activeSources.begin(); it != data->activeSources.end(); ++it) - it->source->updateRenderable(updateFlags, it->scene->getListener()); + for (SceneManagerData::SourceRefSet::const_iterator it = data->activeSources.begin(); it != data->activeSources.end(); ++it) { + // Update the renderable (attributes) + it->source->updateRenderable( + updateFlags | (it->needsActivation ? RenderableSource::UPDATE_ALL : 0), + it->scene->getListener()); + + // Then, start playing if not playing and should be playing + if (it->needsActivation) { + nit->source->getRenderable()->startPlaying( + nit->source->getWouldbePlayingTime() ); + it->needsActivation = false; + } + } } void SceneManager::updateListenerImpl(bool withAttributes) throw(Exception) { + // Update root listener RenderableListener::UpdateFlags updateFlags = withAttributes ? RenderableListener::UPDATE_ALL : RenderableListener::UPDATE_LOCATION; if (data->rootListener.get()) - data->rootListener->getRenderable()->update(updateFlags); + data->rootListener->update(updateFlags); + + // And all scene listeners + for (SceneMap::const_iterator i = data->activeScenes.begin(); i != data->activeScenes.end(); ++i) + i->second.getListener().update(updateFlags); } Duration SceneManager::getPositionUpdateFrequency() const @@ -576,8 +626,13 @@ void SceneManager::notifySourcePlaying(SharedPtr<Source> source, SharedPtr<Scene> scene, bool playing) throw(Exception) { - // Schedule an immediate activation phase - data->lastActivationTime = -std::numeric_limits<Timestamp>::infinity(); + // If the source is within maxDistance from its scene's listener, + // schedule an immediate activation phase + double maxDistanceSq = getMaxDistance(); + maxDistanceSq *= maxDistanceSq; + + if (scene->getListener()->getPosition().distanceSquared(source->getPosition()) <= maxDistanceSq) + data->lastActivationTime = -std::numeric_limits<Timestamp>::infinity(); } }; Modified: branches/audio/vegastrike/src/audio/Source.cpp =================================================================== --- branches/audio/vegastrike/src/audio/Source.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Source.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -117,11 +117,29 @@ throw() { if (rendererDataPtr.get() && isActive()) { - if ((flags != RenderableSource::UPDATE_LOCATION) && !dirty.attributes) - flags = RenderableSource::UPDATE_LOCATION; - + RenderableSource::UpdateFlags oflags = flags; + + if (!dirty.attributes) + flags &= ~RenderableSource::UPDATE_ATTRIBUTES; + if (!dirty.gain) + flags &= ~RenderableSource::UPDATE_GAIN; + + // Must always update location... listeners might move around. + flags |= RenderableSource::UPDATE_LOCATION; + rendererDataPtr->update(flags, sceneListener); + if (oflags == RenderableSource::UPDATE_ALL) { + dirty.reset(); + } else { + if (flags & RenderableSource::UPDATE_LOCATION) + dirty.location = 0; + if (flags & RenderableSource::UPDATE_ATTRIBUTES) + dirty.attributes = 0; + if (flags & RenderableSource::UPDATE_GAIN) + dirty.gain = 0; + } + switch(flags) { case RenderableSource::UPDATE_ALL: dirty.reset(); Modified: branches/audio/vegastrike/src/audio/Source.h =================================================================== --- branches/audio/vegastrike/src/audio/Source.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Source.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -52,7 +52,11 @@ Scalar gain; - bool looping; + struct { + int looping : 1; + int attenuated : 1; + int relative : 1; + } flags; Timestamp lastKnownPlayingTime; Timestamp lastKnownPlayingTimeTime; @@ -65,7 +69,7 @@ /** position, velocity & direction */ int location : 1; - /** min/max angle, radius, pf radius ratios, reference freqs */ + /** min/max angle, radius, pf radius ratios, reference freqs, attenuation */ int attributes : 1; /** gain */ @@ -160,13 +164,29 @@ void setGain(Scalar g) throw() { gain = g; dirty.gain = 1; } /** Is the source in looping mode? */ - bool isLooping() const throw() { return looping; } + bool isLooping() const throw() { return flags.looping != 0; } /** Set the source's looping mode */ - void setLooping(bool loop) throw() { looping = loop; dirty.soundAttributes = 1; } + void setLooping(bool loop) throw() { flags.looping = loop ? 1 : 0; dirty.soundAttributes = 1; } + /** Is the source using distance attenuation? */ + bool isAttenuated() const throw() { return flags.attenuated != 0; } + + /** Set whether the source uses distance attenuation */ + void setAttenuated(bool attenuated) throw() { flags.attenuated = attenuated ? 1 : 0; dirty.attributes = 1; } + + /** Is the source's position always relative to the root listener? + * @remarks Relative sources are useful for interphase sounds, music, + * comm streams, and all those sources which are not anchored + * to a real 3D object, but rather to the listener itself. + */ + bool isRelative() const throw() { return flags.relative != 0; } + + /** Set whether the source's position is always relative to the root listener. */ + void setRelative(bool relative) throw() { flags.relative = relative ? 1 : 0; dirty.attributes = 1; } + /** Play the source - * @remarks If the source isn't playing, rewind and play from the beginning. + * @remarks Rewind and play from the beginning. If the source is playing, it is reset. * May not take effect immediately. */ void startPlaying() throw(Exception); Modified: branches/audio/vegastrike/src/audio/SourceTemplate.h =================================================================== --- branches/audio/vegastrike/src/audio/SourceTemplate.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/SourceTemplate.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -44,8 +44,12 @@ Scalar gain; - bool looping; - bool streaming; + struct { + int looping : 1; + int streaming : 1; + int attenuated : 1; + int relative : 1; + } flags; public: /** Construct a template @@ -112,16 +116,30 @@ void setGain(Scalar g) throw() { gain = g; } /** Is the source in looping mode? */ - bool isLooping() const throw() { return looping; } + bool isLooping() const throw() { return flags.looping != 0; } /** Set the source's looping mode */ - void setLooping(bool loop) throw() { looping = loop; } + void setLooping(bool loop) throw() { flags.looping = loop ? 1 : 0; } + /** Is the source's position always relative to the root listener? + * @see Source::isRelative() + */ + bool isRelative() const throw() { return flags.relative != 0; } + + /** Set whether the source's position is always relative to the root listener */ + void setRelative(bool relative) throw() { flags.relative = relative ? 1 : 0; } + + /** Is the source using distance attenuation? */ + bool isAttenuated() const throw() { return flags.attenuated != 0; } + + /** Set whether the source will use distance attenuation */ + void setAttenuated(bool loop) throw() { flags.attenuated = (loop ? 1 : 0); } + /** Is the source in streaming mode? */ - bool isStreaming() const throw() { return streaming; } + bool isStreaming() const throw() { return flags.streaming != 0; } /** Set the source's streaming mode */ - void setStreaming(bool stream) throw() { streaming = stream; } + void setStreaming(bool stream) throw() { flags.streaming = stream ? 1 : 0; } }; Modified: branches/audio/vegastrike/src/audio/Types.h =================================================================== --- branches/audio/vegastrike/src/audio/Types.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/Types.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -14,6 +14,7 @@ #define SharedFromThis boost::enable_shared_from_this #include "Vector.h" +#include "Matrix.h" namespace Audio { @@ -35,6 +36,12 @@ /** Long FP 3D vector */ typedef TVector3<LScalar> LVector3; + /** FP 3x3 matrix */ + typedef TMatrix3<Scalar> Matrix3; + + /** Long FP 3x3 matrix */ + typedef TMatrix3<LScalar> Matrix3; + /** Per-frequency data usually comes in lf/hf bundles */ template<typename T> struct PerFrequency { T lf; Modified: branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableListener.cpp =================================================================== --- branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableListener.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableListener.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -23,24 +23,16 @@ void OpenALRenderableListener::updateImpl(UpdateFlags flags) throw(Exception) { - switch(flags) { - case UPDATE_ALL: - case UPDATE_ATTRIBUTES: - case UPDATE_EFFECTS: - // Nothing to do without eax? :( - case UPDATE_LOCATION: - { - const Vector3 pos(getListener()->getPosition()); // no option but to cast it down to float :( - const Vector3 vel(getListener()->getVelocity()); - const Vector3 at (getListener()->getAtDirection()); - const Vector3 up (getListener()->getUpDirection()); - ALfloat ori[] = { at.x, at.y, at.z, up.x, up.y, up.z }; - - alListener3f(AL_POSITION, pos.x, pos.y, pos.z); - alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); - alListenerfv(AL_ORIENTATION, ori); - } - break; + if (flags & UPDATE_LOCATION) { + const Vector3 pos(getListener()->getPosition()); // no option but to cast it down to float :( + const Vector3 vel(getListener()->getVelocity()); + const Vector3 at (getListener()->getAtDirection()); + const Vector3 up (getListener()->getUpDirection()); + ALfloat ori[] = { at.x, at.y, at.z, up.x, up.y, up.z }; + + alListener3f(AL_POSITION, pos.x, pos.y, pos.z); + alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); + alListenerfv(AL_ORIENTATION, ori); } } Added: branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.cpp =================================================================== --- branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.cpp (rev 0) +++ branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -0,0 +1,118 @@ +// +// C++ Implementation: Audio::OpenALRenderableListener +// + +#include "OpenALRenderableSource.h" +#include "config.h" + +#include "al.h" + +#include "../../Source.h" + +namespace Audio { + + static inline alSource3f(ALuint source, ALenum param, const Vector3 &v) + { + alSource3f(source, param, ALfloat(v.x), ALfloat(v.y), ALfloat(v.z)); + } + + static inline alSource3f(ALuint source, ALenum param, const LVector3 &v) + { + alSource3f(source, param, ALfloat(v.x), ALfloat(v.y), ALfloat(v.z)); + } + + OpenALRenderableSource::OpenALRenderableSource(Source *source) + : RenderableSource(source), + alSource(0) + { + } + + OpenALRenderableSource::~OpenALRenderableSource() + { + } + + void OpenALRenderableSource::startPlayingImpl(Timestamp start) + throw(Exception) + { + if (!isPlayingImpl()) { + ALuint als = getALSource(); + alSourcePlay(als); + if (start != 0) + alSourcef(als, AL_SEC_OFFSET, start); + } + } + + void OpenALRenderableSource::stopPlayingImpl() + throw(Exception) + { + alSourceStop(als); + } + + bool OpenALRenderableSource::isPlayingImpl() const + throw(Exception) + { + ALint state = 0; + alGetSorucei(getALSource(), AL_SOURCE_STATE, &state); + return (state == AL_PLAYING); + } + + Timestamp OpenALRenderableSource::getPlayingTimeImpl() const + throw(Exception) + { + ALfloat offs = -1.f; + alGetSourcef(getALSource(), AL_SEC_OFFSET, &offs); + + if (offs < 0.f) + throw NotImplementedException("getPlayingTimeImpl"); + + return Timestamp(offs); + } + + void OpenALRenderableSource::updateImpl(UpdateFlags flags, const Listener& sceneListener) + throw(Exception) + { + Source *source = getSource(); + ALuint als = getALSource(); + + if (flags & UPDATE_ATTRIBUTES) { + // Distance attenuation + if (source->isAttenuated()) { + alSourcef(als, AL_REFERENCE_DISTANCE, source->getRadius()); + alSourcef(als, AL_ROLLOFF_FACTOR, 1.f / source->getRadius()); + } else { + alSourcef(als, AL_ROLLOFF_FACTOR, 0.f); + } + // Cone + { + Range<Scalar> angleRange = source->getAngleRange(); + alSourcef(als, AL_CONE_INNER_ANGLE, float(angleRange.min) * 2.f); + alSourcef(als, AL_CONE_OUTER_ANGLE, float(angleRange.max) * 2.f); + } + // Relativity + alSourcei(als, AL_SOURCE_RELATIVE, source->isRelative() ? AL_TRUE : AL_FALSE); + } + if (flags & UPDATE_GAIN) { + // Gain + alSourcef(als, AL_GAIN, source->getGain()); + } + if (flags & UPDATE_LOCATION) { + if (source->isRelative()) { + alSource3f(als, AL_POSITION, source->getPosition()); + alSource3f(als, AL_VELOCITY, source->getVelocity()); + alSource3f(als, AL_DIRECTION, source->getDirection()); + } else { + alSource3f(als, AL_POSITION, + source->getPosition() - sceneListener->getPosition() ); + alSource3f(als, AL_VELOCITY, + sceneListener->toLocalDirection( + source->getVelocity() - sceneListener->getVelocity() + ) ); + alSource3f(als, AL_DIRECTION, + sceneListener->toLocalDirection( + source->getDirection() + ) ); + } + } + } + +}; Added: branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.h =================================================================== --- branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.h (rev 0) +++ branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderableSource.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -0,0 +1,54 @@ +// +// C++ Interface: Audio::OpenALRenderableSource +// +#ifndef __AUDIO_OPENALRENDERABLESOURCE_H__INCLUDED__ +#define __AUDIO_OPENALRENDERABLESOURCE_H__INCLUDED__ + +#include "al.h" + +#include "../../RenderableSource.h" + +#include "../../Exceptions.h" +#include "../../Types.h" + +namespace Audio { + + /** + * OpenAL Renderable Source class + * + * @remarks This class implements the RenderableSource interface for the + * OpenAL renderer. + * + */ + class OpenALRenderableSource : public RenderableSource + { + ALuint alSource; + + public: + OpenALRenderableSource(Source *source); + + virtual ~OpenALRenderableSource(); + + protected: + /** @see RenderableSource::startPlayingImpl. */ + virtual void startPlayingImpl(Timestamp start) throw(Exception); + + /** @see RenderableSource::stopPlayingImpl. */ + virtual void stopPlayingImpl() throw(Exception); + + /** @see RenderableSource::isPlayingImpl. */ + virtual bool isPlayingImpl() const throw(Exception); + + /** @see RenderableSource::getPlayingTimeImpl. */ + virtual Timestamp getPlayingTimeImpl() const throw(Exception); + + /** @see RenderableSource::updateImpl. */ + virtual void updateImpl(UpdateFlags flags, const Listener& sceneListener) throw(Exception); + + /** Derived classes may use the underlying AL source handle to set additional attributes */ + ALunit getALSource() const { return alSource; } + }; + +}; + +#endif//__AUDIO_OPENALRENDERABLESOURCE_H__INCLUDED__ Modified: branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.cpp =================================================================== --- branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -4,6 +4,7 @@ #include "OpenALRenderer.h" #include "OpenALRenderableListener.h" +#include "OpenALRenderableSource.h" #include "config.h" #include "al.h" @@ -11,17 +12,168 @@ #include "../../Sound.h" #include "../../Listener.h" +#include "OpenALSimpleSound.h" + namespace Audio { namespace __impl { namespace OpenAL { + + void checkAlError() + throw (Exception) + { + ALenum error = alGetError(); + switch(error) { + case AL_NO_ERROR : return; + default: + throw Exception(std::string(alGetString(error))); + } + } + + void clearAlError() + throw() + { + alGetError(); + } + struct RendererData { // The many required indexes typedef std::map<std::string, SharedPtr<Sound> > SoundMap; SoundMap sounds; + + ALCdevice *alDevice; + ALCcontext *alContext; + + class SoundKey { + VSFileSystem::VSFileType type; + size_t nameLen; + std::string name; + public: + SoundKey() : + nameLen(0), + type(VSFileSystem::SoundFile) + {} + SoundKey(VSFileSystem::VSFileType _type, const std::string &_name) : + name(name), + type(_type), + nameLen(name.length()) + {} + + bool operator<(const SoundKey &other) const + { + return (type < other.type) || + ((type == other.type) && ( + (nameLen < other.nameLen) || + ((nameLen == other.nameLen) && ( + name < other.name + )) + )); + } + + bool operator==(const SoundKey &other) const + { + return (type == other.type) && + (nameLen == other.nameLen) && + (name == other.name); + } + }; + + typedef std::map<SoundKey, SharedPtr<Sound> > SoundMap; + + SoundMap loadedSounds; + + SharedPtr<Sound> lookupSound(VSFileSystem::VSFileType type, const std::string &name) const + { + SoundKey key(type,name); + SoundMap::const_iterator it = loadedSounds.find(key); + if (it != loadedSounds.end()) + return it->second; + else + return SharedPtr<Sound>(); + } + + void addSound(VSFileSystem::VSFileType type, const std::string &name, SharedPtr<Sound> sound) + { + loadedSounds[key] = sound; + } + + void openDevice(const char *deviceSpecifier) + throw (Exception) + { + if (alDevice) + throw Exception("Trying to open a device without closing the previous one first"); + + clearAlError(); + } + + void closeDevice() + throw (Exception) + { + if (alContext) + throw Exception("Trying to close device without closing the previous one first"); + if (alDevice) { + unloadSounds(); + alcCloseDevice(alDevice); + alDevice = NULL; + clearAlError(); + } + } + + void openContext(const Format &format) + throw (Exception) + { + if (alContext) + throw Exception("Trying to open context without closing the previous one first"); + if (!alDevice) + throw Exception("Trying to open context without opening a device first"); + + clearAlError(); + + ALCint params[] = { + ALC_FREQUENCY, format.sampleFrequency, + 0 + }; + + alContext = alcCreateContext(alDevice, params); + checkAlError(); + + alcMakeContextCurrent(alContext); + alcProcessContext(alContext); + checkAlError(); + } + + void closeContext() + throw (Exception) + { + if (alContext) { + alcSuspendContext(alContext); + alcMakeContextCurrent(NULL); + alcDestroyContext(alContext); + clearAlError(); + } + } + + void unloadSounds() + throw () + { + for (SoundMap::iterator it=loadedSounds.begin(); it != loadedSounds.end(); ++it) + it->second->unload(); + } + + RendererData() throw() : + alDevice(NULL), + alContext(NULL) + { + } + + ~RendererData() + { + closeContext(); + closeDevice(); + } }; }; }; @@ -44,6 +196,28 @@ bool streaming) throw(Exception) { + checkContext(); + SharedPtr<Sound> sound = data->lookupSound(type,name); + if (!sound.get() || (!streaming && sound->isStreaming())) { + // If a pre-existing sound is streaming, and we're required + // to load the sound in non-streaming fashion, we have to + // to load a new version of it, and forget about the old one. + // When all references to the streaming version are lost, + // resources will be freed automatically. + if (streaming) { + /* + data->addSound( + sound = SharedPtr<Sound>(new OpenALStreamingSound(name,type)) + ); + */ + throw NotImplementedException("OpenAL Streaming"); + } else { + data->addSound( + sound = SharedPtr<Sound>(new OpenALSimpleSound(name,type)) + ); + } + } + return sound; } bool OpenALRenderer::owns(SharedPtr<Sound> sound) @@ -54,11 +228,15 @@ void OpenALRenderer::attach(SharedPtr<Source> source) throw(Exception) { + checkContext(); + source->setRenderable( SharedPtr<RenderableSource>( + new OpenALRenderableSource(source.get()) ) ); } void OpenALRenderer::attach(SharedPtr<Listener> listener) throw(Exception) { + checkContext(); listener->setRenderable( SharedPtr<RenderableListener>( new OpenALRenderableListener(listener.get()) ) ); } @@ -66,16 +244,41 @@ void OpenALRenderer::detach(SharedPtr<Source> source) throw() { + // Just clear it... RenderableListener's destructor will handle everything fine. + source->setRenderable( SharedPtr<RenderableSource>() ); } void OpenALRenderer::detach(SharedPtr<Listener> listener) throw() { + // Just clear it... RenderableListener's destructor will handle everything fine. + listener->setRenderable( SharedPtr<RenderableListener>() ); } void OpenALRenderer::setMeterDistance(Scalar distance) throw() { + // ToDo + // Nothing yet - this is an extension to OpenAL 1.1's specs and in this phase + // we'll implement only basic functionality. } + + void OpenALRenderer::setOutputFormat(const Format &format) + throw(Exception) + { + if (!data->alDevice) + data->openDevice(NULL); + data->closeContext(); + data->openContext(format); + Renderer::setOutputFormat(format); + } + + void OpenALRenderer::checkContext() + { + if (!data->alDevice) + data->openDevice(NULL); + if (!data->alContext) + data->openContext(getFormat()); + } }; Modified: branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.h =================================================================== --- branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.h 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALRenderer.h 2009-03-28 22:13:28 UTC (rev 12547) @@ -7,6 +7,7 @@ #include "../../Exceptions.h" #include "../../Types.h" #include "../../Renderer.h" +#include "../../Format.h" namespace Audio { @@ -59,6 +60,12 @@ /** @copydoc Renderer::setMeterDistance */ virtual void setMeterDistance(Scalar distance) throw(); + /** @copydoc Renderer::setOutputFormat */ + virtual void setOutputFormat(const Format &format) throw(Exception); + + protected: + /** Makes sure the AL context is valid, creating one if necessary */ + void checkContext(); }; }; Modified: branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALSimpleSound.cpp =================================================================== --- branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALSimpleSound.cpp 2009-03-26 12:01:24 UTC (rev 12546) +++ branches/audio/vegastrike/src/audio/renderers/OpenAL/OpenALSimpleSound.cpp 2009-03-28 22:13:28 UTC (rev 12547) @@ -28,8 +28,21 @@ // just in case unloadImpl(); - // load the stream, and query stream format + // load the stream + try { + loadStream(); + } catch(ResourceAlreadyLoadedException e) { + // Weird... + getStream()->seek(0); + } + SharedPtr<Stream> stream = getStream(); + try { + + } catch(Exception e) { + unloadStream(); + throw e; + } } void unloadImpl() Modified: branches/audio/vegastrike/src/cmd/ai/firekeyboard.cpp ==============... [truncated message content] |