Index: /code/branches/mainloop/src/CMakeLists.txt
===================================================================
--- /code/branches/mainloop/src/CMakeLists.txt	(revision 76)
+++ /code/branches/mainloop/src/CMakeLists.txt	(revision 76)
@@ -0,0 +1,53 @@
+PROJECT(Tutorial)
+
+#Create some verbose output
+SET(CMAKE_VERBOSE_MAKEFILE TRUE)
+
+#force-set the compile on tardis machines, as default points to g++-3.3
+# only run this test on a lunix/unix machine
+IF (UNIX)
+  FIND_PROGRAM(UNAME_CMD "uname"
+	PATHS "/usr/bin /bin")
+  IF(NOT UNAME_CMD)
+	MESSAGE("Unable to find uname. Tardis-Check cannot be done.")
+  ENDIF(NOT UNAME_CMD)
+  EXECUTE_PROCESS(
+	COMMAND "${UNAME_CMD}" "-n"
+	RESULT_VARIABLE UNAME_RV
+	ERROR_VARIABLE UNAME_EV
+	OUTPUT_VARIABLE UNAME_OV)
+#MESSAGE("Print: UNAME_RV ${UNAME_RV}")
+  IF (NOT "${UNAME_RV}" STREQUAL "0")
+	MESSAGE("ERROR: uname terminated unclean.")
+  ENDIF (NOT "${UNAME_RV}" STREQUAL "0")
+  # check wheter we are on a tardis machine
+  IF ("${UNAME_OV}" MATCHES "tardis")
+    SET (IS_TARDIS "tardis")
+  ENDIF ("${UNAME_OV}" MATCHES "tardis")
+  # if on tardis change compiler
+  IF (IS_TARDIS)
+  MESSAGE("System is a TARDIS: Setting Compiler to g++-3.4.3")
+  SET(CMAKE_CXX_COMPILER "g++-3.4.3")
+  ENDIF(IS_TARDIS)
+ENDIF (UNIX)
+
+# create a few variables to simplify life
+SET(SRC_FILES orxonox.cc)
+SET(INC_FILES ExampleApplication.h  ExampleFrameListener.h  ExampleLoadingBar.h)
+
+#This sets where to look for "Find*.cmake" files
+SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
+#Performs the search and sets the variables
+FIND_PACKAGE(OGRE)
+FIND_PACKAGE(OIS)
+
+#Sets the search paths for the linking
+LINK_DIRECTORIES(${OGRE_LIB_DIR} ${OIS_LIB_DIR})
+#Sets the search path for include files
+INCLUDE_DIRECTORIES(${OGRE_INCLUDE_DIR} ${OIS_INCLUDE_DIR})
+
+#Creates an executable
+ADD_EXECUTABLE(bin/main ${SRC_FILES} ${INC_FILES})
+#Links the executable against OGRE and OIS
+TARGET_LINK_LIBRARIES(bin/main ${OGRE_LIBRARIES} ${OIS_LIBRARIES})
+
Index: /code/branches/mainloop/src/ExampleApplication.h
===================================================================
--- /code/branches/mainloop/src/ExampleApplication.h	(revision 76)
+++ /code/branches/mainloop/src/ExampleApplication.h	(revision 76)
@@ -0,0 +1,257 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2006 Torus Knot Software Ltd
+Also see acknowledgements in Readme.html
+
+You may use this sample code for anything you like, it is not covered by the
+LGPL like the rest of the engine.
+-----------------------------------------------------------------------------
+*/
+/*
+-----------------------------------------------------------------------------
+Filename:    ExampleApplication.h
+Description: Base class for all the OGRE examples
+-----------------------------------------------------------------------------
+*/
+
+#ifndef __ExampleApplication_H__
+#define __ExampleApplication_H__
+
+#include "Ogre.h"
+#include "OgreConfigFile.h"
+#include "ExampleFrameListener.h"
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
+#include <CoreFoundation/CoreFoundation.h>
+
+// This function will locate the path to our application on OS X,
+// unlike windows you can not rely on the curent working directory
+// for locating your configuration files and resources.
+std::string macBundlePath()
+{
+    char path[1024];
+    CFBundleRef mainBundle = CFBundleGetMainBundle();
+    assert(mainBundle);
+
+    CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
+    assert(mainBundleURL);
+
+    CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
+    assert(cfStringRef);
+
+    CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
+
+    CFRelease(mainBundleURL);
+    CFRelease(cfStringRef);
+
+    return std::string(path);
+}
+#endif
+
+using namespace Ogre;
+
+/** Base class which manages the standard startup of an Ogre application.
+    Designed to be subclassed for specific examples if required.
+*/
+class ExampleApplication
+{
+public:
+    /// Standard constructor
+    ExampleApplication()
+    {
+        mFrameListener = 0;
+        mRoot = 0;
+		// Provide a nice cross platform solution for locating the configuration files
+		// On windows files are searched for in the current working directory, on OS X however
+		// you must provide the full path, the helper function macBundlePath does this for us.
+#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
+		mResourcePath = macBundlePath() + "/Contents/Resources/";
+#else
+		mResourcePath = "";
+#endif
+    }
+    /// Standard destructor
+    virtual ~ExampleApplication()
+    {
+        if (mFrameListener)
+            delete mFrameListener;
+        if (mRoot)
+            delete mRoot;
+    }
+
+    /// Start the example
+    virtual void go(void)
+    {
+        if (!setup())
+            return;
+
+        mRoot->startRendering();
+
+        // clean up
+        destroyScene();
+    }
+
+protected:
+    Root *mRoot;
+    Camera* mCamera;
+    SceneManager* mSceneMgr;
+    ExampleFrameListener* mFrameListener;
+    RenderWindow* mWindow;
+	Ogre::String mResourcePath;
+
+    // These internal methods package up the stages in the startup process
+    /** Sets up the application - returns false if the user chooses to abandon configuration. */
+    virtual bool setup(void)
+    {
+
+		String pluginsPath;
+		// only use plugins.cfg if not static
+#ifndef OGRE_STATIC_LIB
+		pluginsPath = mResourcePath + "plugins.cfg";
+#endif
+		
+        mRoot = new Root(pluginsPath, 
+            mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");
+
+        setupResources();
+
+        bool carryOn = configure();
+        if (!carryOn) return false;
+
+        chooseSceneManager();
+        createCamera();
+        createViewports();
+
+        // Set default mipmap level (NB some APIs ignore this)
+        TextureManager::getSingleton().setDefaultNumMipmaps(5);
+
+		// Create any resource listeners (for loading screens)
+		createResourceListener();
+		// Load resources
+		loadResources();
+
+		// Create the scene
+        createScene();
+
+        createFrameListener();
+
+        return true;
+
+    }
+    /** Configures the application - returns false if the user chooses to abandon configuration. */
+    virtual bool configure(void)
+    {
+        // Show the configuration dialog and initialise the system
+        // You can skip this and use root.restoreConfig() to load configuration
+        // settings if you were sure there are valid ones saved in ogre.cfg
+        if(mRoot->showConfigDialog())
+        {
+            // If returned true, user clicked OK so initialise
+            // Here we choose to let the system create a default rendering window by passing 'true'
+            mWindow = mRoot->initialise(true);
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    virtual void chooseSceneManager(void)
+    {
+        // Create the SceneManager, in this case a generic one
+        mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");
+    }
+    virtual void createCamera(void)
+    {
+        // Create the camera
+        mCamera = mSceneMgr->createCamera("PlayerCam");
+
+        // Position it at 500 in Z direction
+        mCamera->setPosition(Vector3(0,0,500));
+        // Look back along -Z
+        mCamera->lookAt(Vector3(0,0,-300));
+        mCamera->setNearClipDistance(5);
+
+    }
+    virtual void createFrameListener(void)
+    {
+        mFrameListener= new ExampleFrameListener(mWindow, mCamera);
+        mFrameListener->showDebugOverlay(true);
+        mRoot->addFrameListener(mFrameListener);
+    }
+
+    virtual void createScene(void) = 0;    // pure virtual - this has to be overridden
+
+    virtual void destroyScene(void){}    // Optional to override this
+
+    virtual void createViewports(void)
+    {
+        // Create one viewport, entire window
+        Viewport* vp = mWindow->addViewport(mCamera);
+        vp->setBackgroundColour(ColourValue(0,0,0));
+
+        // Alter the camera aspect ratio to match the viewport
+        mCamera->setAspectRatio(
+            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
+    }
+
+    /// Method which will define the source of resources (other than current folder)
+    virtual void setupResources(void)
+    {
+        // Load resource paths from config file
+        ConfigFile cf;
+        cf.load(mResourcePath + "resources.cfg");
+
+        // Go through all sections & settings in the file
+        ConfigFile::SectionIterator seci = cf.getSectionIterator();
+
+        String secName, typeName, archName;
+        while (seci.hasMoreElements())
+        {
+            secName = seci.peekNextKey();
+            ConfigFile::SettingsMultiMap *settings = seci.getNext();
+            ConfigFile::SettingsMultiMap::iterator i;
+            for (i = settings->begin(); i != settings->end(); ++i)
+            {
+                typeName = i->first;
+                archName = i->second;
+#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
+                // OS X does not set the working directory relative to the app,
+                // In order to make things portable on OS X we need to provide
+                // the loading with it's own bundle path location
+                ResourceGroupManager::getSingleton().addResourceLocation(
+                    String(macBundlePath() + "/" + archName), typeName, secName);
+#else
+                ResourceGroupManager::getSingleton().addResourceLocation(
+                    archName, typeName, secName);
+#endif
+            }
+        }
+    }
+
+	/// Optional override method where you can create resource listeners (e.g. for loading screens)
+	virtual void createResourceListener(void)
+	{
+
+	}
+
+	/// Optional override method where you can perform resource group loading
+	/// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
+	virtual void loadResources(void)
+	{
+		// Initialise, parse scripts etc
+		ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
+
+	}
+
+
+
+};
+
+
+#endif
Index: /code/branches/mainloop/src/ExampleFrameListener.h
===================================================================
--- /code/branches/mainloop/src/ExampleFrameListener.h	(revision 76)
+++ /code/branches/mainloop/src/ExampleFrameListener.h	(revision 76)
@@ -0,0 +1,401 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2006 Torus Knot Software Ltd
+Also see acknowledgements in Readme.html
+
+You may use this sample code for anything you like, it is not covered by the
+LGPL like the rest of the engine.
+-----------------------------------------------------------------------------
+*/
+/*
+-----------------------------------------------------------------------------
+Filename:    ExampleFrameListener.h
+Description: Defines an example frame listener which responds to frame events.
+This frame listener just moves a specified camera around based on
+keyboard and mouse movements.
+Mouse:    Freelook
+W or Up:  Forward
+S or Down:Backward
+A:        Step left
+D:        Step right
+             PgUp:     Move upwards
+             PgDown:   Move downwards
+             F:        Toggle frame rate stats on/off
+			 R:        Render mode
+             T:        Cycle texture filtering
+                       Bilinear, Trilinear, Anisotropic(8)
+             P:        Toggle on/off display of camera position / orientation
+-----------------------------------------------------------------------------
+*/
+
+#ifndef __ExampleFrameListener_H__
+#define __ExampleFrameListener_H__
+
+#include "Ogre.h"
+#include "OgreStringConverter.h"
+#include "OgreException.h"
+
+//Use this define to signify OIS will be used as a DLL
+//(so that dll import/export macros are in effect)
+#define OIS_DYNAMIC_LIB
+#include <OIS/OIS.h>
+
+using namespace Ogre;
+
+class ExampleFrameListener: public FrameListener, public WindowEventListener
+{
+protected:
+	void updateStats(void)
+	{
+		static String currFps = "Current FPS: ";
+		static String avgFps = "Average FPS: ";
+		static String bestFps = "Best FPS: ";
+		static String worstFps = "Worst FPS: ";
+		static String tris = "Triangle Count: ";
+		static String batches = "Batch Count: ";
+
+		// update stats when necessary
+		try {
+			OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
+			OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
+			OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
+			OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
+
+			const RenderTarget::FrameStats& stats = mWindow->getStatistics();
+			guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
+			guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
+			guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
+				+" "+StringConverter::toString(stats.bestFrameTime)+" ms");
+			guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
+				+" "+StringConverter::toString(stats.worstFrameTime)+" ms");
+
+			OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
+			guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));
+
+			OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
+			guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));
+
+			OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
+			guiDbg->setCaption(mDebugText);
+		}
+		catch(...) { /* ignore */ }
+	}
+
+public:
+	// Constructor takes a RenderWindow because it uses that to determine input context
+	ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false,
+			     bool bufferedJoy = false ) :
+		mCamera(cam), mTranslateVector(Vector3::ZERO), mWindow(win), mStatsOn(true), mNumScreenShots(0),
+		mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),
+		mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),
+		mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)
+	{
+		using namespace OIS;
+
+		mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
+
+		LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
+		ParamList pl;
+		size_t windowHnd = 0;
+		std::ostringstream windowHndStr;
+
+		win->getCustomAttribute("WINDOW", &windowHnd);
+		windowHndStr << windowHnd;
+		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
+
+		mInputManager = InputManager::createInputSystem( pl );
+
+		//Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
+		mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, bufferedKeys ));
+		mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, bufferedMouse ));
+		try {
+			mJoy = static_cast<JoyStick*>(mInputManager->createInputObject( OISJoyStick, bufferedJoy ));
+		}
+		catch(...) {
+			mJoy = 0;
+		}
+
+		//Set initial mouse clipping size
+		windowResized(mWindow);
+
+		showDebugOverlay(true);
+
+		//Register as a Window listener
+		WindowEventUtilities::addWindowEventListener(mWindow, this);
+	}
+
+	//Adjust mouse clipping area
+	virtual void windowResized(RenderWindow* rw)
+	{
+		unsigned int width, height, depth;
+		int left, top;
+		rw->getMetrics(width, height, depth, left, top);
+
+		const OIS::MouseState &ms = mMouse->getMouseState();
+		ms.width = width;
+		ms.height = height;
+	}
+
+	//Unattach OIS before window shutdown (very important under Linux)
+	virtual void windowClosed(RenderWindow* rw)
+	{
+		//Only close for window that created OIS (the main window in these demos)
+		if( rw == mWindow )
+		{
+			if( mInputManager )
+			{
+				mInputManager->destroyInputObject( mMouse );
+				mInputManager->destroyInputObject( mKeyboard );
+				mInputManager->destroyInputObject( mJoy );
+
+				OIS::InputManager::destroyInputSystem(mInputManager);
+				mInputManager = 0;
+			}
+		}
+	}
+
+	virtual ~ExampleFrameListener()
+	{
+		//Remove ourself as a Window listener
+		WindowEventUtilities::removeWindowEventListener(mWindow, this);
+		windowClosed(mWindow);
+	}
+
+	virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
+	{
+		using namespace OIS;
+
+		if(mKeyboard->isKeyDown(KC_A))
+			mTranslateVector.x = -mMoveScale;	// Move camera left
+
+		if(mKeyboard->isKeyDown(KC_D))
+			mTranslateVector.x = mMoveScale;	// Move camera RIGHT
+
+		if(mKeyboard->isKeyDown(KC_UP) || mKeyboard->isKeyDown(KC_W) )
+			mTranslateVector.z = -mMoveScale;	// Move camera forward
+
+		if(mKeyboard->isKeyDown(KC_DOWN) || mKeyboard->isKeyDown(KC_S) )
+			mTranslateVector.z = mMoveScale;	// Move camera backward
+
+		if(mKeyboard->isKeyDown(KC_PGUP))
+			mTranslateVector.y = mMoveScale;	// Move camera up
+
+		if(mKeyboard->isKeyDown(KC_PGDOWN))
+			mTranslateVector.y = -mMoveScale;	// Move camera down
+
+		if(mKeyboard->isKeyDown(KC_RIGHT))
+			mCamera->yaw(-mRotScale);
+
+		if(mKeyboard->isKeyDown(KC_LEFT))
+			mCamera->yaw(mRotScale);
+
+		if( mKeyboard->isKeyDown(KC_ESCAPE) || mKeyboard->isKeyDown(KC_Q) )
+			return false;
+
+       	if( mKeyboard->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0 )
+		{
+			mStatsOn = !mStatsOn;
+			showDebugOverlay(mStatsOn);
+			mTimeUntilNextToggle = 1;
+		}
+
+		if( mKeyboard->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0 )
+		{
+			switch(mFiltering)
+			{
+			case TFO_BILINEAR:
+				mFiltering = TFO_TRILINEAR;
+				mAniso = 1;
+				break;
+			case TFO_TRILINEAR:
+				mFiltering = TFO_ANISOTROPIC;
+				mAniso = 8;
+				break;
+			case TFO_ANISOTROPIC:
+				mFiltering = TFO_BILINEAR;
+				mAniso = 1;
+				break;
+			default: break;
+			}
+			MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
+			MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
+
+			showDebugOverlay(mStatsOn);
+			mTimeUntilNextToggle = 1;
+		}
+
+		if(mKeyboard->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
+		{
+			std::ostringstream ss;
+			ss << "screenshot_" << ++mNumScreenShots << ".png";
+			mWindow->writeContentsToFile(ss.str());
+			mTimeUntilNextToggle = 0.5;
+			mDebugText = "Saved: " + ss.str();
+		}
+
+		if(mKeyboard->isKeyDown(KC_R) && mTimeUntilNextToggle <=0)
+		{
+			mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
+			switch(mSceneDetailIndex) {
+				case 0 : mCamera->setPolygonMode(PM_SOLID); break;
+				case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;
+				case 2 : mCamera->setPolygonMode(PM_POINTS); break;
+			}
+			mTimeUntilNextToggle = 0.5;
+		}
+
+		static bool displayCameraDetails = false;
+		if(mKeyboard->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
+		{
+			displayCameraDetails = !displayCameraDetails;
+			mTimeUntilNextToggle = 0.5;
+			if (!displayCameraDetails)
+				mDebugText = "";
+		}
+
+		// Print camera details
+		if(displayCameraDetails)
+			mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
+						 " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());
+
+		// Return true to continue rendering
+		return true;
+	}
+
+	bool processUnbufferedMouseInput(const FrameEvent& evt)
+	{
+		using namespace OIS;
+
+		// Rotation factors, may not be used if the second mouse button is pressed
+		// 2nd mouse button - slide, otherwise rotate
+		const MouseState &ms = mMouse->getMouseState();
+		if( ms.buttonDown( MB_Right ) )
+		{
+			mTranslateVector.x += ms.X.rel * 0.13;
+			mTranslateVector.y -= ms.Y.rel * 0.13;
+		}
+		else
+		{
+			mRotX = Degree(-ms.X.rel * 0.13);
+			mRotY = Degree(-ms.Y.rel * 0.13);
+		}
+
+		return true;
+	}
+
+	void moveCamera()
+	{
+		// Make all the changes to the camera
+		// Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW
+		//(e.g. airplane)
+		mCamera->yaw(mRotX);
+		mCamera->pitch(mRotY);
+		mCamera->moveRelative(mTranslateVector);
+	}
+
+	void showDebugOverlay(bool show)
+	{
+		if (mDebugOverlay)
+		{
+			if (show)
+				mDebugOverlay->show();
+			else
+				mDebugOverlay->hide();
+		}
+	}
+
+	// Override frameStarted event to process that (don't care about frameEnded)
+	bool frameStarted(const FrameEvent& evt)
+	{
+		using namespace OIS;
+
+		if(mWindow->isClosed())	return false;
+
+		//Need to capture/update each device
+		mKeyboard->capture();
+		mMouse->capture();
+		if( mJoy ) mJoy->capture();
+
+		bool buffJ = (mJoy) ? mJoy->buffered() : true;
+
+		//Check if one of the devices is not buffered
+		if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
+		{
+			// one of the input modes is immediate, so setup what is needed for immediate movement
+			if (mTimeUntilNextToggle >= 0)
+				mTimeUntilNextToggle -= evt.timeSinceLastFrame;
+
+			// If this is the first frame, pick a speed
+			if (evt.timeSinceLastFrame == 0)
+			{
+				mMoveScale = 1;
+				mRotScale = 0.1;
+			}
+			// Otherwise scale movement units by time passed since last frame
+			else
+			{
+				// Move about 100 units per second,
+				mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
+				// Take about 10 seconds for full rotation
+				mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
+			}
+			mRotX = 0;
+			mRotY = 0;
+			mTranslateVector = Ogre::Vector3::ZERO;
+		}
+
+		//Check to see which device is not buffered, and handle it
+		if( !mKeyboard->buffered() )
+			if( processUnbufferedKeyInput(evt) == false )
+				return false;
+		if( !mMouse->buffered() )
+			if( processUnbufferedMouseInput(evt) == false )
+				return false;
+
+		if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
+			moveCamera();
+
+		return true;
+	}
+
+	bool frameEnded(const FrameEvent& evt)
+	{
+		updateStats();
+		return true;
+	}
+
+protected:
+	Camera* mCamera;
+
+	Vector3 mTranslateVector;
+	RenderWindow* mWindow;
+	bool mStatsOn;
+
+	std::string mDebugText;
+
+	unsigned int mNumScreenShots;
+	float mMoveScale;
+	Degree mRotScale;
+	// just to stop toggles flipping too fast
+	Real mTimeUntilNextToggle ;
+	Radian mRotX, mRotY;
+	TextureFilterOptions mFiltering;
+	int mAniso;
+
+	int mSceneDetailIndex ;
+	Real mMoveSpeed;
+	Degree mRotateSpeed;
+	Overlay* mDebugOverlay;
+
+	//OIS Input devices
+	OIS::InputManager* mInputManager;
+	OIS::Mouse*    mMouse;
+	OIS::Keyboard* mKeyboard;
+	OIS::JoyStick* mJoy;
+};
+
+#endif
Index: /code/branches/mainloop/src/ExampleLoadingBar.h
===================================================================
--- /code/branches/mainloop/src/ExampleLoadingBar.h	(revision 76)
+++ /code/branches/mainloop/src/ExampleLoadingBar.h	(revision 76)
@@ -0,0 +1,182 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2006 Torus Knot Software Ltd
+Also see acknowledgements in Readme.html
+
+You may use this sample code for anything you like, it is not covered by the
+LGPL like the rest of the engine.
+-----------------------------------------------------------------------------
+*/
+/*
+-----------------------------------------------------------------------------
+Filename:    ExampleLoadingBar.h
+Description: Defines an example loading progress bar which you can use during 
+startup, level changes etc to display loading progress. 
+IMPORTANT: Note that this progress bar relies on you having the OgreCore.zip 
+package already added to a resource group called 'Bootstrap' - this provides
+the basic resources required for the progress bar and will be loaded automatically.
+*/
+#include "OgreResourceGroupManager.h"
+#include "OgreException.h"
+#include "OgreOverlay.h"
+#include "OgreOverlayManager.h"
+#include "OgreRenderWindow.h"
+
+using namespace Ogre;
+
+/** Defines an example loading progress bar which you can use during 
+	startup, level changes etc to display loading progress. 
+@remarks
+	Basically you just need to create an instance of this class, call start()
+	before loading and finish() afterwards. You may also need to stop areas of
+	your scene rendering in between since this method will call 
+	RenderWindow::update() to update the display of the bar - we advise using
+	SceneManager's 'special case render queues' for this, see
+	SceneManager::addSpecialCaseRenderQueue for details.
+@note 
+	This progress bar relies on you having the OgreCore.zip package already 
+	added to a resource group called 'Bootstrap' - this provides the basic 
+	resources required for the progress bar and will be loaded automatically.
+*/
+class ExampleLoadingBar : public ResourceGroupListener
+{
+protected:
+	RenderWindow* mWindow;
+	Overlay* mLoadOverlay;
+	Real mInitProportion;
+	unsigned short mNumGroupsInit;
+	unsigned short mNumGroupsLoad;
+	Real mProgressBarMaxSize;
+	Real mProgressBarScriptSize;
+	Real mProgressBarInc;
+	OverlayElement* mLoadingBarElement;
+	OverlayElement* mLoadingDescriptionElement;
+	OverlayElement* mLoadingCommentElement;
+
+public:
+	ExampleLoadingBar() {}
+	virtual ~ExampleLoadingBar(){}
+
+	/** Show the loading bar and start listening.
+	@param window The window to update 
+	@param numGroupsInit The number of groups you're going to be initialising
+	@param numGroupsLoad The number of groups you're going to be loading
+	@param initProportion The proportion of the progress which will be taken
+		up by initialisation (ie script parsing etc). Defaults to 0.7 since
+		script parsing can often take the majority of the time.
+	*/
+	virtual void start(RenderWindow* window, 
+		unsigned short numGroupsInit = 1, 
+		unsigned short numGroupsLoad = 1, 
+		Real initProportion = 0.70f)
+	{
+		mWindow = window;
+		mNumGroupsInit = numGroupsInit;
+		mNumGroupsLoad = numGroupsLoad;
+		mInitProportion = initProportion;
+		// We need to pre-initialise the 'Bootstrap' group so we can use
+		// the basic contents in the loading screen
+		ResourceGroupManager::getSingleton().initialiseResourceGroup("Bootstrap");
+
+		OverlayManager& omgr = OverlayManager::getSingleton();
+		mLoadOverlay = (Overlay*)omgr.getByName("Core/LoadOverlay");
+		if (!mLoadOverlay)
+		{
+			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
+				"Cannot find loading overlay", "ExampleLoadingBar::start");
+		}
+		mLoadOverlay->show();
+
+		// Save links to the bar and to the loading text, for updates as we go
+		mLoadingBarElement = omgr.getOverlayElement("Core/LoadPanel/Bar/Progress");
+		mLoadingCommentElement = omgr.getOverlayElement("Core/LoadPanel/Comment");
+		mLoadingDescriptionElement = omgr.getOverlayElement("Core/LoadPanel/Description");
+
+		OverlayElement* barContainer = omgr.getOverlayElement("Core/LoadPanel/Bar");
+		mProgressBarMaxSize = barContainer->getWidth();
+		mLoadingBarElement->setWidth(0);
+
+		// self is listener
+		ResourceGroupManager::getSingleton().addResourceGroupListener(this);
+
+
+
+	}
+
+	/** Hide the loading bar and stop listening. 
+	*/
+	virtual void finish(void)
+	{
+		// hide loading screen
+		mLoadOverlay->hide();
+
+		// Unregister listener
+		ResourceGroupManager::getSingleton().removeResourceGroupListener(this);
+
+	}
+
+
+	// ResourceGroupListener callbacks
+	void resourceGroupScriptingStarted(const String& groupName, size_t scriptCount)
+	{
+		assert(mNumGroupsInit > 0 && "You stated you were not going to init "
+			"any groups, but you did! Divide by zero would follow...");
+		// Lets assume script loading is 70%
+		mProgressBarInc = mProgressBarMaxSize * mInitProportion / (Real)scriptCount;
+		mProgressBarInc /= mNumGroupsInit;
+		mLoadingDescriptionElement->setCaption("Parsing scripts...");
+		mWindow->update();
+	}
+	void scriptParseStarted(const String& scriptName)
+	{
+		mLoadingCommentElement->setCaption(scriptName);
+		mWindow->update();
+	}
+	void scriptParseEnded(const String& scriptName)
+	{
+		mLoadingBarElement->setWidth(
+			mLoadingBarElement->getWidth() + mProgressBarInc);
+		mWindow->update();
+	}
+	void resourceGroupScriptingEnded(const String& groupName)
+	{
+	}
+	void resourceGroupLoadStarted(const String& groupName, size_t resourceCount)
+	{
+		assert(mNumGroupsLoad > 0 && "You stated you were not going to load "
+			"any groups, but you did! Divide by zero would follow...");
+		mProgressBarInc = mProgressBarMaxSize * (1-mInitProportion) / 
+			(Real)resourceCount;
+		mProgressBarInc /= mNumGroupsLoad;
+		mLoadingDescriptionElement->setCaption("Loading resources...");
+		mWindow->update();
+	}
+	void resourceLoadStarted(const ResourcePtr& resource)
+	{
+		mLoadingCommentElement->setCaption(resource->getName());
+		mWindow->update();
+	}
+	void resourceLoadEnded(void)
+	{
+	}
+	void worldGeometryStageStarted(const String& description)
+	{
+		mLoadingCommentElement->setCaption(description);
+		mWindow->update();
+	}
+	void worldGeometryStageEnded(void)
+	{
+		mLoadingBarElement->setWidth(
+			mLoadingBarElement->getWidth() + mProgressBarInc);
+		mWindow->update();
+	}
+	void resourceGroupLoadEnded(const String& groupName)
+	{
+	}
+
+};
+
Index: /code/branches/mainloop/src/bin/media.cfg
===================================================================
--- /code/branches/mainloop/src/bin/media.cfg	(revision 76)
+++ /code/branches/mainloop/src/bin/media.cfg	(revision 76)
@@ -0,0 +1,16 @@
+Mesh=ogrehead.mesh
+Mesh=geosphere4500.mesh
+Mesh=razor.mesh
+Mesh=knot.mesh
+Mesh=RZR-002.mesh
+Mesh=geosphere8000.mesh
+Mesh=sphere.mesh
+
+CubeMap=cubescene.jpg
+CubeMap=early_morning.jpg
+CubeMap=cubemap.jpg
+CubeMap=morning.jpg
+CubeMap=cloudy_noon.jpg
+CubeMap=evening.jpg
+CubeMap=stormy.jpg
+CubeMap=stevecube.jpg
Index: /code/branches/mainloop/src/bin/ogre.cfg-init
===================================================================
--- /code/branches/mainloop/src/bin/ogre.cfg-init	(revision 76)
+++ /code/branches/mainloop/src/bin/ogre.cfg-init	(revision 76)
@@ -0,0 +1,7 @@
+Render System=OpenGL Rendering Subsystem
+
+[OpenGL Rendering Subsystem]
+FSAA=4
+Full Screen=No
+RTT Preferred Mode=PBuffer
+Video Mode=1280 x 1024
Index: /code/branches/mainloop/src/bin/plugins.cfg-init
===================================================================
--- /code/branches/mainloop/src/bin/plugins.cfg-init	(revision 76)
+++ /code/branches/mainloop/src/bin/plugins.cfg-init	(revision 76)
@@ -0,0 +1,14 @@
+# Defines plugins to load
+
+# Define plugin folder
+PluginFolder=/usr/lib/OGRE
+
+# Define plugins
+#Plugin=RenderSystem_Direct3D9
+Plugin=RenderSystem_GL
+Plugin=Plugin_ParticleFX
+Plugin=Plugin_BSPSceneManager
+Plugin=Plugin_OctreeSceneManager
+Plugin=Plugin_CgProgramManager
+
+
Index: /code/branches/mainloop/src/bin/quake3settings.cfg
===================================================================
--- /code/branches/mainloop/src/bin/quake3settings.cfg	(revision 76)
+++ /code/branches/mainloop/src/bin/quake3settings.cfg	(revision 76)
@@ -0,0 +1,3 @@
+Pak0Location: f:\quake3levels\chiropteraDM.pk3
+Map: maps/chiropteradm.bsp
+
Index: /code/branches/mainloop/src/bin/resources.cfg
===================================================================
--- /code/branches/mainloop/src/bin/resources.cfg	(revision 76)
+++ /code/branches/mainloop/src/bin/resources.cfg	(revision 76)
@@ -0,0 +1,23 @@
+# Resource locations to be added to the 'boostrap' path
+# This also contains the minimum you need to use the Ogre example framework
+[Bootstrap]
+#Zip=../Media/packs/OgreCore.zip
+
+# Resource locations to be added to the default path
+[General]
+#FileSystem=../Media
+#FileSystem=../Media/fonts
+#FileSystem=../Media/materials/programs
+#FileSystem=../Media/materials/scripts
+#FileSystem=../Media/materials/textures
+#FileSystem=../Media/models
+#FileSystem=../Media/overlays
+#FileSystem=../Media/particle
+#FileSystem=../Media/gui
+#FileSystem=../Media/DeferredShading../Media
+#Zip=../Media/packs/cubemap.zip
+#Zip=../Media/packs/cubemapsJS.zip
+#Zip=../Media/packs/dragon.zip
+#Zip=../Media/packs/fresneldemo.zip
+#Zip=../Media/packs/ogretestmap.zip
+#Zip=../Media/packs/skybox.zip
Index: /code/branches/mainloop/src/bin/run-script
===================================================================
--- /code/branches/mainloop/src/bin/run-script	(revision 76)
+++ /code/branches/mainloop/src/bin/run-script	(revision 76)
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+if [[ !  -f main ]] ; then
+	echo "main does not exist"
+	echo "did you compile it?"
+
+	exit 1
+fi
+
+if [[ ! -f orge.cfg ]] ; then
+	cp ogre.cfg-init ogre.cfg
+fi
+
+# check if plugins.cfg exists, and of not create it
+# and modify 
+if [[ ! -f plugins.cfg ]] ; then 
+	if uname -n | grep "tardis" > /dev/null ; then
+		sed -e 's:PluginFolder=/usr/lib/OGRE:PluginFolder=/usr/pack/ogre-1.4.5-sd/i686-debian-linux3.1/lib/OGRE/:' \
+		-e 's:#Plugin=Plugin_CgProgramManager:Plugin=Plugin_CgProgramManager:' plugins.cfg-init > plugins.cfg
+	else
+                cp plugins.cfg-init plugins.cfg
+	fi
+fi
+exec ./main
