<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>cmake/FindALUT.cmake</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -94,25 +94,52 @@ SET(OPENC2E_CORE
 
 
 
-# Pass flags to the compiler
-ADD_DEFINITIONS(&quot;-W -Wall -Wno-conversion -Wno-unused -pthread -D_REENTRANT -DYYERROR_VERBOSE&quot;)
 
 FIND_PACKAGE(SDL REQUIRED)
 FIND_PACKAGE(SDL_mixer REQUIRED)
 FIND_PACKAGE(SDL_net REQUIRED)
 FIND_PACKAGE(SDL_gfx REQUIRED)
+FIND_PACKAGE(OpenAL)
+FIND_PACKAGE(ALUT)
 FIND_PACKAGE(Boost)
 
-ADD_EXECUTABLE(openc2e ${OPENC2E_CORE} caosVM_ser_stub.cpp main.cpp)
+SET(USE_OPENAL &quot;NO&quot;)
+
+IF(${OPENAL_FOUND} STREQUAL &quot;YES&quot;)
+    IF(${ALUT_FOUND} STREQUAL &quot;YES&quot;)
+        SET(USE_OPENAL &quot;YES&quot;)
+    ENDIF(${ALUT_FOUND} STREQUAL &quot;YES&quot;)
+ENDIF(${OPENAL_FOUND} STREQUAL &quot;YES&quot;)
+     
+IF(${USE_OPENAL} STREQUAL &quot;NO&quot;)
+    SET(ALUT_INCLUDE_DIR &quot;&quot;)
+    SET(OPENAL_INCLUDE_DIR &quot;&quot;)
+    SET(ALUT_LIBRARY &quot;&quot;)
+    SET(OPENAL_LIBRARY &quot;&quot;)
+    SET(OPENAL_SRC &quot;&quot;)
+    SET(OPENAL_DEF &quot;&quot;)
+ELSE(${OPENAL_SRC} STREQUAL &quot;&quot;)
+    SET(OPENAL_SRC &quot;OpenALBackend.cpp&quot;)
+    SET(OPENAL_DEF &quot;-DOPENAL_SUPPORT&quot;)
+ENDIF(${OPENAL_SRC} STREQUAL &quot;&quot;)
+
+# Pass flags to the compiler
+ADD_DEFINITIONS(&quot;-W -Wall -Wno-conversion -Wno-unused -pthread -D_REENTRANT -DYYERROR_VERBOSE ${OPENAL_DEF}&quot;)
+
+ADD_EXECUTABLE(openc2e ${OPENC2E_CORE} ${OPENAL_SRC} caosVM_ser_stub.cpp main.cpp)
 
 TARGET_LINK_LIBRARIES(openc2e z m pthread 
 	${SDL_LIBRARY}
 	${SDLMIXER_LIBRARY} 
 	${SDLNET_LIBRARY}
 	${SDLGFX_LIBRARY}
+	${OPENAL_LIBRARY}
+	${ALUT_LIBRARY}
 	boost_program_options-mt
 	boost_serialization-mt
-	boost_filesystem-mt)
+	boost_filesystem-mt
+	boost_thread-mt
+	)
 
 INCLUDE_DIRECTORIES(BEFORE
 	${BIN}
@@ -120,7 +147,10 @@ INCLUDE_DIRECTORIES(BEFORE
 	${SDL_INCLUDE_DIR}
 	${SDLMIXER_INCLUDE_DIR}
 	${SDLNET_INCLUDE_DIR}
-	${SDLGFX_INCLUDE_DIR})
+	${SDLGFX_INCLUDE_DIR}
+	${OPENAL_INCLUDE_DIR}
+	${ALUT_INCLUDE_DIR}
+	)
 
 FILE(GLOB CAOSVM_FILES ${SRC}/caosVM_*.cpp)
 ADD_CUSTOM_COMMAND(</diff>
      <filename>CMakeLists.txt</filename>
    </modified>
    <modified>
      <diff>@@ -75,14 +75,16 @@ public:
 	void setZoom(int pixels, int _x, int _y);
 };
 
+class Backend;
+
 class MainCamera : public Camera {
 protected:
-	class Backend *backend;
+	boost::shared_ptr&lt;Backend&gt; backend;
 	std::vector&lt;AgentRef&gt; floated;
 
 public:
-	MainCamera() { backend = 0; }
-	void setBackend(Backend *b) { backend = b; }
+	MainCamera() { }
+	void setBackend(boost::shared_ptr&lt;Backend&gt; b) { backend = b; }
 	unsigned int const getWidth();
 	unsigned int const getHeight();
 	void moveTo(int _x, int _y, panstyle pan = jump);</diff>
      <filename>Camera.h</filename>
    </modified>
    <modified>
      <diff>@@ -23,6 +23,8 @@
 #include &quot;caosVM.h&quot; // for setupCommandPointers()
 #include &quot;PointerAgent.h&quot;
 #include &quot;dialect.h&quot; // registerDelegates
+#include &quot;NullBackend.h&quot;
+#include &quot;NullAudioBackend.h&quot;
 
 #include &lt;boost/filesystem/path.hpp&gt;
 #include &lt;boost/filesystem/operations.hpp&gt;
@@ -40,7 +42,6 @@ namespace po = boost::program_options;
 Engine engine;
 
 Engine::Engine() {
-	backend = 0;
 	done = false;
 	tickdata = 0;
 	for (unsigned int i = 0; i &lt; 10; i++) ticktimes[i] = 0;
@@ -51,13 +52,27 @@ Engine::Engine() {
 	
 	cmdline_enable_sound = true;
 	cmdline_norun = false;
+
+	addPossibleBackend(&quot;null&quot;, shared_ptr&lt;Backend&gt;(new NullBackend()));
+	addPossibleAudioBackend(&quot;null&quot;, shared_ptr&lt;AudioBackend&gt;(new NullAudioBackend()));
 }
 
 Engine::~Engine() {
-	if (backend) delete backend;
 }
 
-void Engine::setBackend(Backend *b) {
+void Engine::addPossibleBackend(std::string s, boost::shared_ptr&lt;Backend&gt; b) {
+	assert(b);
+	preferred_backend = s;
+	possible_backends[s] = b;
+}
+
+void Engine::addPossibleAudioBackend(std::string s, boost::shared_ptr&lt;AudioBackend&gt; b) {
+	assert(b);
+	preferred_audiobackend = s;
+	possible_audiobackends[s] = b;
+}
+
+void Engine::setBackend(shared_ptr&lt;Backend&gt; b) {
 	backend = b;
 	lasttimestamp = backend-&gt;ticks();
 
@@ -387,7 +402,6 @@ void Engine::handleMouseButton(SomeEvent &amp;event) {
 }
 
 void Engine::handleKeyDown(SomeEvent &amp;event) {
-
 	switch (event.key) {
 		case 'w': w_down = true; break;
 		case 'a': a_down = true; break;
@@ -520,14 +534,31 @@ bool Engine::parseCommandLine(int argc, char *argv[]) {
 	int optret;
 	std::vector&lt;std::string&gt; data_vec;
 
+	// generate help for backend options
+	std::string available_backends;
+	for (std::map&lt;std::string, boost::shared_ptr&lt;Backend&gt; &gt;::iterator i = possible_backends.begin(); i != possible_backends.end(); i++) {
+		if (available_backends.empty()) available_backends = i-&gt;first;
+		else available_backends += &quot;, &quot; + i-&gt;first;
+	}
+	available_backends = &quot;Select the backend (options: &quot; + available_backends + &quot;), default is &quot; + preferred_backend;
+	
+	std::string available_audiobackends;
+	for (std::map&lt;std::string, boost::shared_ptr&lt;AudioBackend&gt; &gt;::iterator i = possible_audiobackends.begin(); i != possible_audiobackends.end(); i++) {
+		if (available_audiobackends.empty()) available_audiobackends = i-&gt;first;
+		else available_audiobackends += &quot;, &quot; + i-&gt;first;
+	}
+	available_audiobackends = &quot;Select the audio backend (options: &quot; + available_audiobackends + &quot;), default is &quot; + preferred_audiobackend;
+	
 	// parse the command-line flags
 	po::options_description desc;
 	desc.add_options()
 		(&quot;help,h&quot;, &quot;Display help on command-line options&quot;)
 		(&quot;version,V&quot;, &quot;Display openc2e version&quot;)
 		(&quot;silent,s&quot;, &quot;Disable all sounds&quot;)
+		(&quot;backend,k&quot;, po::value&lt;std::string&gt;(&amp;preferred_backend)-&gt;composing(), available_backends.c_str())
+		(&quot;audiobackend,o&quot;, po::value&lt;std::string&gt;(&amp;preferred_audiobackend)-&gt;composing(), available_audiobackends.c_str())
 		(&quot;data-path,d&quot;, po::value&lt; std::vector&lt;std::string&gt; &gt;(&amp;data_vec)-&gt;composing(),
-		 &quot;Set the path to the data directory&quot;)
+		 &quot;Sets or adds a path to a data directory&quot;)
 		(&quot;bootstrap,b&quot;, po::value&lt; std::vector&lt;std::string&gt; &gt;(&amp;cmdline_bootstrap)-&gt;composing(),
 		 &quot;Sets or adds a path or COS file to bootstrap from&quot;)
 		(&quot;gametype,g&quot;, po::value&lt; std::string &gt;(&amp;world.gametype), &quot;Set the game type (c1, c2, cv or c3)&quot;)
@@ -572,7 +603,7 @@ bool Engine::parseCommandLine(int argc, char *argv[]) {
 	return true;
 }
 
-bool Engine::initialSetup(Backend *b) {
+bool Engine::initialSetup() {
 	assert(world.data_directories.size() &gt; 0);
 
 	// autodetect gametype if necessary
@@ -603,13 +634,24 @@ bool Engine::initialSetup(Backend *b) {
 	world.init(); // just reads mouse cursor (we want this after the catalogue reading so we don't play &quot;guess the filename&quot;)
 	std::cout &lt;&lt; &quot;* Reading PRAY files...&quot; &lt;&lt; std::endl;
 	world.praymanager.update();
-	std::cout &lt;&lt; &quot;* Initialising backend...&quot; &lt;&lt; std::endl;
-	// TODO: ideally we shouldn't bother with the backend if norun is set (but we need one right now, for MainCamera/CAOS)
-	engine.setBackend(b);
-	engine.backend-&gt;init();
-	world.camera.setBackend(engine.backend); // TODO: hrr
+
+	if (cmdline_norun) preferred_backend = &quot;null&quot;;
+	if (preferred_backend != &quot;null&quot;) std::cout &lt;&lt; &quot;* Initialising backend &quot; &lt;&lt; preferred_backend &lt;&lt; &quot;...&quot; &lt;&lt; std::endl;	
+	shared_ptr&lt;Backend&gt; b = possible_backends[preferred_backend];
+	if (!b)	throw creaturesException(&quot;No such backend &quot; + preferred_backend);
+	b-&gt;init(); setBackend(b);
+	possible_backends.clear();
+
+	if (cmdline_norun || !cmdline_enable_sound) preferred_audiobackend = &quot;null&quot;;
+	if (preferred_audiobackend != &quot;null&quot;) std::cout &lt;&lt; &quot;* Initialising audio backend &quot; &lt;&lt; preferred_audiobackend &lt;&lt; &quot;...&quot; &lt;&lt; std::endl;	
+	shared_ptr&lt;AudioBackend&gt; a = possible_audiobackends[preferred_audiobackend];
+	if (!a)	throw creaturesException(&quot;No such audio backend &quot; + preferred_audiobackend);
+	a-&gt;init(); audio = a;
+	possible_audiobackends.clear();
+
+	world.camera.setBackend(backend); // TODO: hrr
 	
-	int listenport = engine.backend-&gt;networkInit();
+	int listenport = backend-&gt;networkInit();
 	if (listenport != -1) {
 		// inform the user of the port used, and store it in the relevant file
 		std::cout &lt;&lt; &quot;Listening for connections on port &quot; &lt;&lt; listenport &lt;&lt; &quot;.&quot; &lt;&lt; std::endl;
@@ -626,7 +668,7 @@ bool Engine::initialSetup(Backend *b) {
 		// TODO: This is a hack for DS, basically. Not sure if it works properly. - fuzzie
 		caosVar name; name.setString(&quot;engine_no_auxiliary_bootstrap_1&quot;);
 		caosVar contents; contents.setInt(1);
-		engine.eame_variables[name] = contents;
+		eame_variables[name] = contents;
 	}
 
 	// execute the initial scripts!
@@ -667,7 +709,8 @@ bool Engine::initialSetup(Backend *b) {
 
 void Engine::shutdown() {
 	world.shutdown();
-	engine.backend-&gt;shutdown();
+	backend-&gt;shutdown();
+	audio-&gt;shutdown();
 	freeDelegates(); // does nothing if there are none (ie, no call to initialSetup)
 }
 </diff>
      <filename>Engine.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -21,10 +21,13 @@
 #define _ENGINE_H
 
 #include &quot;caosVar.h&quot;
-#include &quot;Backend.h&quot;
 #include &lt;map&gt;
 #include &lt;boost/filesystem/path.hpp&gt;
 
+class Backend;
+class AudioBackend;
+struct SomeEvent;
+
 class Engine {
 protected:
 	unsigned int tickdata;
@@ -38,17 +41,21 @@ protected:
 	bool cmdline_norun;
 	std::vector&lt;std::string&gt; cmdline_bootstrap;
 
+	std::map&lt;std::string, boost::shared_ptr&lt;Backend&gt; &gt; possible_backends;
+	std::map&lt;std::string, boost::shared_ptr&lt;class AudioBackend&gt; &gt; possible_audiobackends;
+	std::string preferred_backend, preferred_audiobackend;
+
 public:
 	std::map&lt;caosVar, caosVar, caosVarCompare&gt; eame_variables; // non-serialised
 	
-	Backend *backend;
+	boost::shared_ptr&lt;Backend&gt; backend;
 	boost::shared_ptr&lt;class AudioBackend&gt; audio;
 	bool done;
 	unsigned int version;
 
 	Engine();
 	~Engine();
-	void setBackend(Backend *b);
+	void setBackend(boost::shared_ptr&lt;Backend&gt; b);
 	std::string executeNetwork(std::string in);
 	bool needsUpdate();
 	void update();
@@ -62,8 +69,11 @@ public:
 	void handleSpecialKeyDown(SomeEvent &amp;event);
 	void handleSpecialKeyUp(SomeEvent &amp;event);
 
+	void addPossibleBackend(std::string, boost::shared_ptr&lt;Backend&gt;);
+	void addPossibleAudioBackend(std::string, boost::shared_ptr&lt;AudioBackend&gt;);
+	
 	bool parseCommandLine(int argc, char *argv[]);
-	bool initialSetup(Backend *b);
+	bool initialSetup();
 	void shutdown();
 
 	bool noRun() { return cmdline_norun; }</diff>
      <filename>Engine.h</filename>
    </modified>
    <modified>
      <diff>@@ -73,6 +73,7 @@ OPENC2E_CORE = \
 	mngfile.o \
 	mngparser.tab.o \
 	oldBrain.o \
+	OpenALBackend.o \
 	PathResolver.o \
 	physics.o \
 	PointerAgent.o \
@@ -96,8 +97,8 @@ OPENC2E = $(OPENC2E_CORE) $(SERSTUB) main.o
 OPENC2E_S = $(OPENC2E_CORE) $(SERIALIZATION) main.o
 
 DEBUGFLAGS=-ggdb3 -O0
-CFLAGS += -W -Wall -Wno-conversion -Wno-unused -pthread -D_REENTRANT -DYYERROR_VERBOSE
-XLDFLAGS=$(LDFLAGS) -lboost_program_options-mt -lboost_serialization-mt -lboost_filesystem-mt $(SDL_LFLAGS) -lz -lm -lSDL_net -lSDL_gfx -lpthread
+CFLAGS += -W -Wall -Wno-conversion -Wno-unused -pthread -D_REENTRANT -DYYERROR_VERBOSE -DOPENAL_SUPPORT
+XLDFLAGS=$(LDFLAGS) -lboost_program_options-mt -lboost_serialization-mt -lboost_filesystem-mt -lboost_thread-mt $(SDL_LFLAGS) -lz -lm -lSDL_net -lSDL_gfx -lpthread -lopenal -lalut
 COREFLAGS=$(DEBUGFLAGS) $(SDL_CFLAGS) -I.
 XCFLAGS=$(CFLAGS) $(COREFLAGS)
 XCPPFLAGS=$(COREFLAGS) $(CPPFLAGS) $(CFLAGS)</diff>
      <filename>Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -27,6 +27,10 @@
 #include &quot;exceptions.h&quot;
 #include &quot;World.h&quot;
 
+#ifndef OPENAL_SUPPORT
+#error OPENAL_SUPPORT isn't set, so this file shouldn't be being compiled
+#endif
+
 const ALfloat zdist = -1.0;
 const ALfloat plnemul = 0.0;
 const ALfloat scale = 1.0/50;</diff>
      <filename>OpenALBackend.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -24,7 +24,7 @@
 #include &quot;World.h&quot;
 #include &quot;SDLBackend.h&quot;
 #include &quot;NullBackend.h&quot;
-#include &quot;NullAudioBackend.h&quot;
+#include &quot;OpenALBackend.h&quot;
 
 #if defined(_MSC_VER) &amp;&amp; defined(_DEBUG)
 #undef main // because SDL is stupid
@@ -34,19 +34,16 @@ extern &quot;C&quot; int main(int argc, char *argv[]) {
 	try {
 		std::cout &lt;&lt; &quot;openc2e (development build), built &quot; __DATE__ &quot; &quot; __TIME__ &quot;\nCopyright (c) 2004-2007 Alyssa Milburn and others\n\n&quot;;
 
+		engine.addPossibleBackend(&quot;sdl&quot;, shared_ptr&lt;Backend&gt;(new SDLBackend()));
+#ifdef OPENAL_SUPPORT
+		engine.addPossibleAudioBackend(&quot;openal&quot;, shared_ptr&lt;AudioBackend&gt;(new OpenALBackend()));
+#endif
+
 		// pass command-line flags to the engine, but do no other setup
 		if (!engine.parseCommandLine(argc, argv)) return 1;
 		
-		// depending on engine configuration, create either a null (does nothing) backend or a normal SDL one
-		Backend *b;
-		if (engine.noRun()) b = new NullBackend();
-		else b = new SDLBackend();
-	
-		engine.audio = shared_ptr&lt;AudioBackend&gt;(new NullAudioBackend());
-		engine.audio-&gt;init();
-		
 		// get the engine to do all the startup (read catalogue, loading world, etc)
-		if (!engine.initialSetup(b)) return 0;
+		if (!engine.initialSetup()) return 0;
 	
 		// do a first-pass draw of the world. TODO: correct?
 		world.drawWorld();</diff>
      <filename>main.cpp</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>bc69cdddd3b79121c96e7032bfb7b096859c5627</id>
    </parent>
  </parents>
  <author>
    <name>Alyssa Milburn</name>
    <email>fuzzie@fuzzie.org</email>
  </author>
  <url>http://github.com/ccdevnet/openc2e/commit/1549c9f136eb147476142e5fa7f64fe6f7899a21</url>
  <id>1549c9f136eb147476142e5fa7f64fe6f7899a21</id>
  <committed-date>2007-08-16T12:35:07-07:00</committed-date>
  <authored-date>2007-08-16T12:35:07-07:00</authored-date>
  <message>add multiple backend/audiobackend support, enable openal support, tweak makefile/cmake as necessary</message>
  <tree>aa7b98e89d5e70de29ecbbbe9ee69d5c78a94c77</tree>
  <committer>
    <name>Alyssa Milburn</name>
    <email>fuzzie@fuzzie.org</email>
  </committer>
</commit>
