<commit_before>/*
-----------------------------------------------------------------------------
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

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
/*
-----------------------------------------------------------------------------
Filename:    Fresnel.cpp
Description: Fresnel reflections and refractions
-----------------------------------------------------------------------------
*/

#include "ExampleApplication.h"
#include "OgreHardwarePixelBuffer.h"
// Hacky globals
Camera* theCam;
Entity* pPlaneEnt;
std::vector<Entity*> aboveWaterEnts;
std::vector<Entity*> belowWaterEnts;

// Fish!
#define NUM_FISH 30
#define NUM_FISH_WAYPOINTS 10
#define FISH_PATH_LENGTH 200
#define FISH_SCALE 1.2
AnimationState* fishAnimations[NUM_FISH];
SimpleSpline fishSplines[NUM_FISH];
Vector3 fishLastPosition[NUM_FISH];
SceneNode* fishNodes[NUM_FISH];
Real animTime = 0.0f;

Plane reflectionPlane;

class RefractionTextureListener : public RenderTargetListener
{
public:
    void preRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Hide plane and objects above the water
        pPlaneEnt->setVisible(false);
        std::vector<Entity*>::iterator i, iend;
        iend = aboveWaterEnts.end();
        for (i = aboveWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(false);
        }

    }
    void postRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Show plane and objects above the water
        pPlaneEnt->setVisible(true);
        std::vector<Entity*>::iterator i, iend;
        iend = aboveWaterEnts.end();
        for (i = aboveWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(true);
        }
    }

};
class ReflectionTextureListener : public RenderTargetListener
{
public:
    void preRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Hide plane and objects below the water
        pPlaneEnt->setVisible(false);
        std::vector<Entity*>::iterator i, iend;
        iend = belowWaterEnts.end();
        for (i = belowWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(false);
        }
        theCam->enableReflection(reflectionPlane);

    }
    void postRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Show plane and objects below the water
        pPlaneEnt->setVisible(true);
        std::vector<Entity*>::iterator i, iend;
        iend = belowWaterEnts.end();
        for (i = belowWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(true);
        }
        theCam->disableReflection();
    }

};

class FresnelFrameListener : public ExampleFrameListener
{
public:

    FresnelFrameListener(RenderWindow* win, Camera* cam)
        : ExampleFrameListener(win, cam, false, false)
    {}
    bool frameRenderingQueued(const FrameEvent &evt)
    {
        animTime += evt.timeSinceLastFrame;
        while (animTime > FISH_PATH_LENGTH)
            animTime -= FISH_PATH_LENGTH;

        for (size_t fish = 0; fish < NUM_FISH; ++fish)
        {
            // Animate the fish
            fishAnimations[fish]->addTime(evt.timeSinceLastFrame*2);
            // Move the fish
            Vector3 newPos = fishSplines[fish].interpolate(animTime / FISH_PATH_LENGTH);
            fishNodes[fish]->setPosition(newPos);
            // Work out the direction
            Vector3 direction = fishLastPosition[fish] - newPos;
            direction.normalise();
			// Test for opposite vectors
			Real d = 1.0f + Vector3::UNIT_X.dotProduct(direction);
			if (fabs(d) < 0.00001)
			{
				// Diametrically opposed vectors
				Quaternion orientation;
				orientation.FromAxes(Vector3::NEGATIVE_UNIT_X,
					Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_Z);
				fishNodes[fish]->setOrientation(orientation);
			}
			else
			{
				fishNodes[fish]->setOrientation(
					Vector3::UNIT_X.getRotationTo(direction));
			}
            fishLastPosition[fish] = newPos;

        }

        return ExampleFrameListener::frameRenderingQueued(evt);
    }

};

class FresnelApplication : public ExampleApplication
{
protected:
    RefractionTextureListener mRefractionListener;
    ReflectionTextureListener mReflectionListener;
public:
    FresnelApplication() {

    }

    ~FresnelApplication()
    {
    }
protected:

    // Just override the mandatory create scene method
    void createScene(void)
    {

        // Check prerequisites first
		const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
        {
            OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs, so cannot "
                "run this demo. Sorry!",
                "Fresnel::createScene");
        }
        else
        {
            if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") &&
                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") &&
				!GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4")
				)
            {
                OGRE_EXCEPT(1, "Your card does not support advanced fragment programs, "
                    "so cannot run this demo. Sorry!",
                "Fresnel::createScene");
            }
        }

        theCam = mCamera;
        theCam->setPosition(-50,125,760);
		theCam->setDirection (0,0,-1);
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

        // Create a point light
        Light* l = mSceneMgr->createLight("MainLight");
        l->setType(Light::LT_DIRECTIONAL);
        l->setDirection(-Vector3::UNIT_Y);

        Entity* pEnt;

        TexturePtr mTexture = TextureManager::getSingleton().createManual( "Refraction",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
			512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
        //RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
        RenderTarget *rttTex = mTexture->getBuffer()->getRenderTarget();

        {
            Viewport *v = rttTex->addViewport( mCamera );
            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
            v->setOverlaysEnabled(false);
            rttTex->addListener(&mRefractionListener);
        }

		mTexture = TextureManager::getSingleton().createManual( "Reflection",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
			512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
        //rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
        rttTex = mTexture->getBuffer()->getRenderTarget();
        {
            Viewport *v = rttTex->addViewport( mCamera );
            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
            v->setOverlaysEnabled(false);
            rttTex->addListener(&mReflectionListener);
        }

        // Define a floor plane mesh
        reflectionPlane.normal = Vector3::UNIT_Y;
        reflectionPlane.d = 0;
        MeshManager::getSingleton().createPlane("ReflectPlane",
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
            reflectionPlane,
            700,1300,10,10,true,1,3,5,Vector3::UNIT_Z);
        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);

        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");

        // My node to which all objects will be attached
        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		// above water entities
        pEnt = mSceneMgr->createEntity( "RomanBathUpper", "RomanBathUpper.mesh" );
		myRootNode->attachObject(pEnt);
        aboveWaterEnts.push_back(pEnt);

        pEnt = mSceneMgr->createEntity( "Columns", "Columns.mesh" );
		myRootNode->attachObject(pEnt);
        aboveWaterEnts.push_back(pEnt);

		Ogre::SceneNode *headNode = myRootNode->createChildSceneNode ();
		pEnt = mSceneMgr->createEntity( "OgreHead", "ogrehead.mesh" );
		pEnt->setMaterialName ("RomanBath/OgreStone");
        headNode->attachObject(pEnt);
		headNode->setPosition(-350,55,130);
		headNode->rotate(Vector3::UNIT_Y, Degree (90));
        aboveWaterEnts.push_back(pEnt);

		// below water entities
		pEnt = mSceneMgr->createEntity( "RomanBathLower", "RomanBathLower.mesh" );
        myRootNode->attachObject(pEnt);
        belowWaterEnts.push_back(pEnt);

		for (size_t fishNo = 0; fishNo < NUM_FISH; ++fishNo)
        {
            pEnt = mSceneMgr->createEntity("fish" + StringConverter::toString(fishNo), "fish.mesh");
            fishNodes[fishNo] = myRootNode->createChildSceneNode();
			fishNodes[fishNo]->setScale(FISH_SCALE, FISH_SCALE, FISH_SCALE);
            fishAnimations[fishNo] = pEnt->getAnimationState("swim");
            fishAnimations[fishNo]->setEnabled(true);
            fishNodes[fishNo]->attachObject(pEnt);
            belowWaterEnts.push_back(pEnt);

            // Generate a random selection of points for the fish to swim to
            fishSplines[fishNo].setAutoCalculate(false);
            Vector3 lastPos;
            for (size_t waypoint = 0; waypoint < NUM_FISH_WAYPOINTS; ++waypoint)
            {
                Vector3 pos = Vector3(
                    Math::SymmetricRandom() * 270, -10, Math::SymmetricRandom() * 700);
                if (waypoint > 0)
                {
                    // check this waypoint isn't too far, we don't want turbo-fish ;)
                    // since the waypoints are achieved every 5 seconds, half the length
                    // of the pond is ok
                    while ((lastPos - pos).length() > 750)
                    {
                        pos = Vector3(
                            Math::SymmetricRandom() * 270, -10, Math::SymmetricRandom() * 700);
                    }
                }
                fishSplines[fishNo].addPoint(pos);
                lastPos = pos;
            }
            // close the spline
            fishSplines[fishNo].addPoint(fishSplines[fishNo].getPoint(0));
            // recalc
            fishSplines[fishNo].recalcTangents();

        }

    }

    void createFrameListener(void)
    {
        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
        mFrameListener->showDebugOverlay(true);
        mRoot->addFrameListener(mFrameListener);
    }

};

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    FresnelApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}

#ifdef __cplusplus
}
#endif
<commit_msg>Fix license statement on Fresnel demo code - all samples are supposed to be public domain / free use.<commit_after>/*
-----------------------------------------------------------------------------
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:    Fresnel.cpp
Description: Fresnel reflections and refractions
-----------------------------------------------------------------------------
*/

#include "ExampleApplication.h"
#include "OgreHardwarePixelBuffer.h"
// Hacky globals
Camera* theCam;
Entity* pPlaneEnt;
std::vector<Entity*> aboveWaterEnts;
std::vector<Entity*> belowWaterEnts;

// Fish!
#define NUM_FISH 30
#define NUM_FISH_WAYPOINTS 10
#define FISH_PATH_LENGTH 200
#define FISH_SCALE 1.2
AnimationState* fishAnimations[NUM_FISH];
SimpleSpline fishSplines[NUM_FISH];
Vector3 fishLastPosition[NUM_FISH];
SceneNode* fishNodes[NUM_FISH];
Real animTime = 0.0f;

Plane reflectionPlane;

class RefractionTextureListener : public RenderTargetListener
{
public:
    void preRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Hide plane and objects above the water
        pPlaneEnt->setVisible(false);
        std::vector<Entity*>::iterator i, iend;
        iend = aboveWaterEnts.end();
        for (i = aboveWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(false);
        }

    }
    void postRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Show plane and objects above the water
        pPlaneEnt->setVisible(true);
        std::vector<Entity*>::iterator i, iend;
        iend = aboveWaterEnts.end();
        for (i = aboveWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(true);
        }
    }

};
class ReflectionTextureListener : public RenderTargetListener
{
public:
    void preRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Hide plane and objects below the water
        pPlaneEnt->setVisible(false);
        std::vector<Entity*>::iterator i, iend;
        iend = belowWaterEnts.end();
        for (i = belowWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(false);
        }
        theCam->enableReflection(reflectionPlane);

    }
    void postRenderTargetUpdate(const RenderTargetEvent& evt)
    {
        // Show plane and objects below the water
        pPlaneEnt->setVisible(true);
        std::vector<Entity*>::iterator i, iend;
        iend = belowWaterEnts.end();
        for (i = belowWaterEnts.begin(); i != iend; ++i)
        {
            (*i)->setVisible(true);
        }
        theCam->disableReflection();
    }

};

class FresnelFrameListener : public ExampleFrameListener
{
public:

    FresnelFrameListener(RenderWindow* win, Camera* cam)
        : ExampleFrameListener(win, cam, false, false)
    {}
    bool frameRenderingQueued(const FrameEvent &evt)
    {
        animTime += evt.timeSinceLastFrame;
        while (animTime > FISH_PATH_LENGTH)
            animTime -= FISH_PATH_LENGTH;

        for (size_t fish = 0; fish < NUM_FISH; ++fish)
        {
            // Animate the fish
            fishAnimations[fish]->addTime(evt.timeSinceLastFrame*2);
            // Move the fish
            Vector3 newPos = fishSplines[fish].interpolate(animTime / FISH_PATH_LENGTH);
            fishNodes[fish]->setPosition(newPos);
            // Work out the direction
            Vector3 direction = fishLastPosition[fish] - newPos;
            direction.normalise();
			// Test for opposite vectors
			Real d = 1.0f + Vector3::UNIT_X.dotProduct(direction);
			if (fabs(d) < 0.00001)
			{
				// Diametrically opposed vectors
				Quaternion orientation;
				orientation.FromAxes(Vector3::NEGATIVE_UNIT_X,
					Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_Z);
				fishNodes[fish]->setOrientation(orientation);
			}
			else
			{
				fishNodes[fish]->setOrientation(
					Vector3::UNIT_X.getRotationTo(direction));
			}
            fishLastPosition[fish] = newPos;

        }

        return ExampleFrameListener::frameRenderingQueued(evt);
    }

};

class FresnelApplication : public ExampleApplication
{
protected:
    RefractionTextureListener mRefractionListener;
    ReflectionTextureListener mReflectionListener;
public:
    FresnelApplication() {

    }

    ~FresnelApplication()
    {
    }
protected:

    // Just override the mandatory create scene method
    void createScene(void)
    {

        // Check prerequisites first
		const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
        {
            OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs, so cannot "
                "run this demo. Sorry!",
                "Fresnel::createScene");
        }
        else
        {
            if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") &&
                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") &&
				!GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4")
				)
            {
                OGRE_EXCEPT(1, "Your card does not support advanced fragment programs, "
                    "so cannot run this demo. Sorry!",
                "Fresnel::createScene");
            }
        }

        theCam = mCamera;
        theCam->setPosition(-50,125,760);
		theCam->setDirection (0,0,-1);
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

        // Create a point light
        Light* l = mSceneMgr->createLight("MainLight");
        l->setType(Light::LT_DIRECTIONAL);
        l->setDirection(-Vector3::UNIT_Y);

        Entity* pEnt;

        TexturePtr mTexture = TextureManager::getSingleton().createManual( "Refraction",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
			512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
        //RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
        RenderTarget *rttTex = mTexture->getBuffer()->getRenderTarget();

        {
            Viewport *v = rttTex->addViewport( mCamera );
            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
            v->setOverlaysEnabled(false);
            rttTex->addListener(&mRefractionListener);
        }

		mTexture = TextureManager::getSingleton().createManual( "Reflection",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
			512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
        //rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
        rttTex = mTexture->getBuffer()->getRenderTarget();
        {
            Viewport *v = rttTex->addViewport( mCamera );
            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
            v->setOverlaysEnabled(false);
            rttTex->addListener(&mReflectionListener);
        }

        // Define a floor plane mesh
        reflectionPlane.normal = Vector3::UNIT_Y;
        reflectionPlane.d = 0;
        MeshManager::getSingleton().createPlane("ReflectPlane",
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
            reflectionPlane,
            700,1300,10,10,true,1,3,5,Vector3::UNIT_Z);
        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);

        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");

        // My node to which all objects will be attached
        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		// above water entities
        pEnt = mSceneMgr->createEntity( "RomanBathUpper", "RomanBathUpper.mesh" );
		myRootNode->attachObject(pEnt);
        aboveWaterEnts.push_back(pEnt);

        pEnt = mSceneMgr->createEntity( "Columns", "Columns.mesh" );
		myRootNode->attachObject(pEnt);
        aboveWaterEnts.push_back(pEnt);

		Ogre::SceneNode *headNode = myRootNode->createChildSceneNode ();
		pEnt = mSceneMgr->createEntity( "OgreHead", "ogrehead.mesh" );
		pEnt->setMaterialName ("RomanBath/OgreStone");
        headNode->attachObject(pEnt);
		headNode->setPosition(-350,55,130);
		headNode->rotate(Vector3::UNIT_Y, Degree (90));
        aboveWaterEnts.push_back(pEnt);

		// below water entities
		pEnt = mSceneMgr->createEntity( "RomanBathLower", "RomanBathLower.mesh" );
        myRootNode->attachObject(pEnt);
        belowWaterEnts.push_back(pEnt);

		for (size_t fishNo = 0; fishNo < NUM_FISH; ++fishNo)
        {
            pEnt = mSceneMgr->createEntity("fish" + StringConverter::toString(fishNo), "fish.mesh");
            fishNodes[fishNo] = myRootNode->createChildSceneNode();
			fishNodes[fishNo]->setScale(FISH_SCALE, FISH_SCALE, FISH_SCALE);
            fishAnimations[fishNo] = pEnt->getAnimationState("swim");
            fishAnimations[fishNo]->setEnabled(true);
            fishNodes[fishNo]->attachObject(pEnt);
            belowWaterEnts.push_back(pEnt);

            // Generate a random selection of points for the fish to swim to
            fishSplines[fishNo].setAutoCalculate(false);
            Vector3 lastPos;
            for (size_t waypoint = 0; waypoint < NUM_FISH_WAYPOINTS; ++waypoint)
            {
                Vector3 pos = Vector3(
                    Math::SymmetricRandom() * 270, -10, Math::SymmetricRandom() * 700);
                if (waypoint > 0)
                {
                    // check this waypoint isn't too far, we don't want turbo-fish ;)
                    // since the waypoints are achieved every 5 seconds, half the length
                    // of the pond is ok
                    while ((lastPos - pos).length() > 750)
                    {
                        pos = Vector3(
                            Math::SymmetricRandom() * 270, -10, Math::SymmetricRandom() * 700);
                    }
                }
                fishSplines[fishNo].addPoint(pos);
                lastPos = pos;
            }
            // close the spline
            fishSplines[fishNo].addPoint(fishSplines[fishNo].getPoint(0));
            // recalc
            fishSplines[fishNo].recalcTangents();

        }

    }

    void createFrameListener(void)
    {
        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
        mFrameListener->showDebugOverlay(true);
        mRoot->addFrameListener(mFrameListener);
    }

};

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    FresnelApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}

#ifdef __cplusplus
}
#endif
<|endoftext|>


<commit_before>#include <OpcodeBase.hpp>
#include <cmath>
#include <iostream>
#include <list>
#include <vector>

// Why not use the constants already defined?
static MYFLT pi = std::atan(1.0) * MYFLT(4.0);

class RCLowpassFilter
{
public:
  void initialize(MYFLT sampleRate, MYFLT cutoffHz, MYFLT initialValue)
  {
    MYFLT tau = MYFLT(1.0) / (MYFLT(2.0) * pi * cutoffHz);
    alpha = MYFLT(1.0) / (MYFLT(1.0) + (tau * sampleRate));
    value = initialValue;
  }
  MYFLT update(MYFLT inputValue)
  {
    value += alpha * (inputValue - value);
    return value;
  }
protected:
  MYFLT alpha;
  MYFLT value;
};

class LinearInterpolator
{
public:
  LinearInterpolator() :
    priorValue(MYFLT(0.0)),
    currentValue(MYFLT(0.0))
  {
  }
  virtual void put(MYFLT inputValue)
  {
    priorValue = currentValue;
    currentValue = inputValue;
  }
  virtual MYFLT get(MYFLT fraction)
  {
    return priorValue + (fraction * (currentValue - priorValue));
  }
protected:
  MYFLT priorValue;
  MYFLT currentValue;
};

class DelayLine : public std::vector<MYFLT>
{
public:
  MYFLT sampleRate;
  int writingFrame;
  int size_;
  void initialize(size_t sampleRate_, MYFLT maximumDelay = 10.0)
  {
    sampleRate = (MYFLT) sampleRate_;
    size_ = (int) std::ceil(maximumDelay * sampleRate);
    std::cout << "DelayLine::initialize: size: " << size_ << std::endl;
    std::cout << "DelayLine::initialize: sampleRate: " << sampleRate << std::endl;
    resize(size_);
    writingFrame = 0;
  }
  void write(MYFLT value)
  {
    while (writingFrame >= size_) {
      writingFrame -= size_;
    }
    (*this)[(size_t) writingFrame] = value;
    //std::cout << "DelayLine::write: writingFrame: " << writingFrame << std::endl;
    writingFrame++;
  }
  MYFLT delaySeconds(MYFLT delaySeconds)
  {
    int delayFrames_ = (int) (delaySeconds * sampleRate);
    return delayFrames(delayFrames_);
  }
  MYFLT delayFrames(int delayFrames_)
  {
    //std::cout << "DelayLine::delayFrames: delayFrames: " << delayFrames_ << std::endl;
    int readingFrame = writingFrame - delayFrames_;
    while (readingFrame < 0) {
      readingFrame += size_;
    }
    while (readingFrame >= size_) {
      readingFrame -= size_;
    }
    // std::cout << "DelayLine::delayFrames: readingFrame: " << readingFrame << std::endl;
    return (*this)[(size_t) readingFrame];
  }
};

std::list<RCLowpassFilter *> smoothingFilterInstances;
std::list<DelayLine *> delayLineInstances;

class Doppler : public OpcodeBase<Doppler>
{
public:
  // Csound opcode outputs.
  MYFLT *audioOutput;
  // Csound opcode inputs.
  MYFLT *audioInput;
  MYFLT *kSourcePosition;     // usually meters
  MYFLT *kMicPosition;        // usually meters
  MYFLT *jSpeedOfSound;       // usually meters/second
  MYFLT *jUpdateFilterCutoff; // Hz
  // Doppler internal state.
  MYFLT speedOfSound;         // usually meters/second
  MYFLT smoothingFilterCutoff;   // Hz
  MYFLT sampleRate;           // Hz
  MYFLT samplesPerDistance;   // usually samples/meter
  MYFLT blockRate;            // Hz
  int blockSize;              // samples
  RCLowpassFilter *smoothingFilter;
  LinearInterpolator *audioInterpolator;
  std::list< std::vector<MYFLT> *> *audioBufferQueue;
  std::list<MYFLT> *sourcePositionQueue;
  int relativeIndex;
  int currentIndex;

  int init(CSOUND *csound)
  {
    sampleRate = csound->GetSr(csound);
    blockSize = csound->GetKsmps(csound);
    blockRate = sampleRate / blockSize;
    // Take care of default values.
    if (*jSpeedOfSound == MYFLT(-1.0)) {
      *jSpeedOfSound = MYFLT(340.29);
    }
    speedOfSound = *jSpeedOfSound;
    if (*jUpdateFilterCutoff == MYFLT(-1.0)) {
//    MYFLT blockRateNyquist = blockRate / MYFLT(2.0);
//    *jUpdateFilterCutoff = blockRateNyquist / MYFLT(2.0);
      *jUpdateFilterCutoff = MYFLT(6.0); // very conservative
    }
    smoothingFilterCutoff = *jUpdateFilterCutoff;
    samplesPerDistance = sampleRate / speedOfSound;
    audioInterpolator = new LinearInterpolator;
    smoothingFilter = NULL;
    audioBufferQueue = new std::list< std::vector<MYFLT> *>;
    sourcePositionQueue = new std::list<MYFLT>;
    currentIndex = 0;
    relativeIndex = 0;
    return OK;
  }
  int kontrol(CSOUND *csound)
  {
    MYFLT sourcePosition = *kSourcePosition;
    MYFLT micPosition = *kMicPosition;

    std::vector<MYFLT> *sourceBuffer = new std::vector<MYFLT>;
    sourceBuffer->resize(blockSize);
    for (size_t inputFrame = 0; inputFrame < blockSize; inputFrame++) {
      (*sourceBuffer)[inputFrame] = audioInput[inputFrame];
    }
    audioBufferQueue->push_back(sourceBuffer);
    sourcePositionQueue->push_back(sourcePosition);

    std::vector<MYFLT> *currentBuffer = audioBufferQueue->front();
    MYFLT targetPosition = sourcePositionQueue->front() - micPosition;

    // The smoothing filter cannot be initialized at i-time,
    // because it must be initialized from a k-rate variable.
    if (!smoothingFilter) {
      smoothingFilter = new RCLowpassFilter();
      smoothingFilter->initialize(sampleRate, smoothingFilterCutoff, targetPosition);
      log(csound, "Doppler::kontrol: sizeof(MYFLT):         %10d\n", sizeof(MYFLT));
      log(csound, "Doppler::kontrol: PI:                    %10.3f\n", pi);
      log(csound, "Doppler::kontrol: this:                  %10p\n", this);
      log(csound, "Doppler::kontrol: sampleRate:            %10.3f\n", sampleRate);
      log(csound, "Doppler::kontrol: blockSize:             %10.3f\n", blockSize);
      log(csound, "Doppler::kontrol: blockRate:             %10.3f\n", blockRate);
      log(csound, "Doppler::kontrol: speedOfSound:          %10.3f\n", speedOfSound);
      log(csound, "Doppler::kontrol: samplesPerDistance:    %10.3f\n", samplesPerDistance);
      log(csound, "Doppler::kontrol: smoothingFilterCutoff: %10.3f\n", smoothingFilterCutoff);
      log(csound, "Doppler::kontrol: kMicPosition:          %10.3f\n", *kMicPosition);
      log(csound, "Doppler::kontrol: kSourcePosition:       %10.3f\n", *kSourcePosition);
    }

    for (size_t outputFrame = 0; outputFrame < blockSize; outputFrame++) {
      MYFLT position = smoothingFilter->update(targetPosition);
      MYFLT distance = std::fabs(position);
      MYFLT sourceTime = relativeIndex - (distance * samplesPerDistance);
      int targetIndex = int(sourceTime);
      MYFLT fraction = sourceTime - targetIndex;
      relativeIndex++;
      for ( ; targetIndex >= currentIndex; currentIndex++) {
        if (currentIndex >= blockSize) {
          relativeIndex -= blockSize;
          currentIndex -= blockSize;
          targetIndex -= blockSize;
                delete audioBufferQueue->front();
          audioBufferQueue->pop_front();
          sourcePositionQueue->pop_front();
          currentBuffer = audioBufferQueue->front();
          targetPosition = sourcePositionQueue->front() - micPosition;
        }
        audioInterpolator->put((*currentBuffer)[currentIndex]);
      }
      MYFLT currentSample = audioInterpolator->get(fraction);
      audioOutput[outputFrame] = currentSample;
    }
    return OK;
  }
};

#ifdef NEVER
struct Doppler2 : public OpcodeBase<Doppler2>
{
  // Csound opcode outputs.
  MYFLT *audioOutput;
  // Csound opcode inputs.
  MYFLT *audioInput;
  MYFLT *kSourcePosition;
  MYFLT *kMicPosition;
  MYFLT *jSpeedOfSound;
  MYFLT *jUpdateFilterCutoff;
  // Doppler internal state.
  MYFLT speedOfSound;
  MYFLT smoothingFilterCutoff;
  MYFLT sampleRate;
  MYFLT samplesPerDistance;
  MYFLT blockSize;
  MYFLT blockRate;
  RCLowpassFilter *smoothingFilter;
  LinearInterpolator *audioInterpolator;
  DelayLine *delayLine;
  int init(CSOUND *csound)
  {
    sampleRate = csound->GetSr(csound);
    blockSize = csound->GetKsmps(csound);
    blockRate = sampleRate / blockSize;
    // Take care of default values.
    if (*jSpeedOfSound == MYFLT(-1.0)) {
      *jSpeedOfSound = MYFLT(340.29);
    }
    speedOfSound = *jSpeedOfSound;
    if (*jUpdateFilterCutoff == MYFLT(-1.0)) {
      MYFLT blockRateNyquist = blockRate / MYFLT(2.0);
      *jUpdateFilterCutoff = blockRateNyquist / MYFLT(2.0);
    }
    smoothingFilterCutoff = *jUpdateFilterCutoff;
    samplesPerDistance = sampleRate / speedOfSound;
    audioInterpolator = new LinearInterpolator;
    // The smoothing filter cannot be initialized at i-time,
    // because it must be initialized from a k-rate variable.
    smoothingFilter = 0;
    delayLine = new DelayLine;
    return OK;
  }
  int kontrol(CSOUND *csound)
  {
    MYFLT sourcePosition = *kSourcePosition;
    MYFLT micPosition = *kMicPosition;
    MYFLT position = sourcePosition - micPosition;
    // On the very first block only, initialize the smoothing filter.
    if (!smoothingFilter) {
      smoothingFilter = new RCLowpassFilter();
      smoothingFilter->initialize(sampleRate, smoothingFilterCutoff, *kSourcePosition);
      log(csound, "Doppler::kontrol: sizeof(MYFLT):                  %10d\n", sizeof(MYFLT));
      log(csound, "Doppler::kontrol: PI:                             %10.3f\n", pi);
      log(csound, "Doppler::kontrol: this:                           %10p\n", this);
      log(csound, "Doppler::kontrol: sampleRate:                       %10.3f\n", sampleRate);
      log(csound, "Doppler::kontrol: blockSize:                 %10.3f\n", blockSize);
      log(csound, "Doppler::kontrol: blockRate:                       %10.3f\n", blockRate);
      log(csound, "Doppler::kontrol: speedOfSound:           %10.3f\n", speedOfSound);
      log(csound, "Doppler::kontrol: samplesPerDistance:                 %10.3f\n", samplesPerDistance);
      log(csound, "Doppler::kontrol: smoothingFilterCutoff:  %10.3f\n", smoothingFilterCutoff);
      log(csound, "Doppler::kontrol: kMicPosition:             %10.3f\n", *kMicPosition);
      log(csound, "Doppler::kontrol: kSourcePosition:          %10.3f\n", *kSourcePosition);
      delayLine->initialize(sampleRate, 10.0);
    }
    for (size_t frame = 0; frame < blockSize; frame++) {
      delayLine->write(audioInput[frame]);
      MYFLT distance = std::fabs(position);
      MYFLT delayFrames = distance * samplesPerDistance;
      MYFLT delayFramesFloor = int(delayFrames);
      MYFLT fraction = delayFrames - delayFramesFloor;
      MYFLT currentValue = delayLine->delayFrames((int) delayFrames);
      audioInterpolator->put(currentValue);
      currentValue = audioInterpolator->get(fraction);
      position = smoothingFilter->update(position);
      audioOutput[frame] = currentValue;
    }
    return OK;
  }
};
#endif

extern "C"
{
  OENTRY oentries[] =
    {
      {
        (char*)"doppler",
        sizeof(Doppler),
        3,
        (char*)"a",
        (char*)"akkjj",
        (SUBR) Doppler::init_,
        (SUBR) Doppler::kontrol_,
        0,
      },
#ifdef NEVER
      {
        (char*)"doppler2",
        sizeof(Doppler2),
        3,
        (char*)"a",
        (char*)"akkjj",
        (SUBR) Doppler2::init_,
        (SUBR) Doppler2::kontrol_,
        0,
      },
#endif
      {
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
      }
    };

  PUBLIC int csoundModuleCreate(CSOUND *csound)
  {
    return 0;
  }

  PUBLIC int csoundModuleInit(CSOUND *csound)
  {
    int status = 0;
    for(OENTRY *oentry = &oentries[0]; oentry->opname; oentry++)
      {
        status |= csound->AppendOpcode(csound, oentry->opname,
                                       oentry->dsblksiz, oentry->thread,
                                       oentry->outypes, oentry->intypes,
                                       (int (*)(CSOUND*,void*)) oentry->iopadr,
                                       (int (*)(CSOUND*,void*)) oentry->kopadr,
                                       (int (*)(CSOUND*,void*)) oentry->aopadr);
      }
    return status;
  }

  PUBLIC int csoundModuleDestroy(CSOUND *csound)
  {
    //csound->Message(csound, "Deleting C++ objects from doppler...\n");
    for (std::list<RCLowpassFilter *>::iterator it = smoothingFilterInstances.begin();
         it != smoothingFilterInstances.end();
         ++it) {
      delete *it;
    }
    smoothingFilterInstances.clear();
    for (std::list<DelayLine *>::iterator it = delayLineInstances.begin();
         it != delayLineInstances.end();
         ++it) {
      delete *it;
    }
    delayLineInstances.clear();
    return 0;
  }
}

<commit_msg>stop overwriting arguem,nts<commit_after>#include <OpcodeBase.hpp>
#include <cmath>
#include <iostream>
#include <list>
#include <vector>

// Why not use the constants already defined?
static MYFLT pi = std::atan(1.0) * MYFLT(4.0);

class RCLowpassFilter
{
public:
  void initialize(MYFLT sampleRate, MYFLT cutoffHz, MYFLT initialValue)
  {
    MYFLT tau = MYFLT(1.0) / (MYFLT(2.0) * pi * cutoffHz);
    alpha = MYFLT(1.0) / (MYFLT(1.0) + (tau * sampleRate));
    value = initialValue;
  }
  MYFLT update(MYFLT inputValue)
  {
    value += alpha * (inputValue - value);
    return value;
  }
protected:
  MYFLT alpha;
  MYFLT value;
};

class LinearInterpolator
{
public:
  LinearInterpolator() :
    priorValue(MYFLT(0.0)),
    currentValue(MYFLT(0.0))
  {
  }
  virtual void put(MYFLT inputValue)
  {
    priorValue = currentValue;
    currentValue = inputValue;
  }
  virtual MYFLT get(MYFLT fraction)
  {
    return priorValue + (fraction * (currentValue - priorValue));
  }
protected:
  MYFLT priorValue;
  MYFLT currentValue;
};

class DelayLine : public std::vector<MYFLT>
{
public:
  MYFLT sampleRate;
  int writingFrame;
  int size_;
  void initialize(size_t sampleRate_, MYFLT maximumDelay = 10.0)
  {
    sampleRate = (MYFLT) sampleRate_;
    size_ = (int) std::ceil(maximumDelay * sampleRate);
    std::cout << "DelayLine::initialize: size: " << size_ << std::endl;
    std::cout << "DelayLine::initialize: sampleRate: " << sampleRate << std::endl;
    resize(size_);
    writingFrame = 0;
  }
  void write(MYFLT value)
  {
    while (writingFrame >= size_) {
      writingFrame -= size_;
    }
    (*this)[(size_t) writingFrame] = value;
    //std::cout << "DelayLine::write: writingFrame: " << writingFrame << std::endl;
    writingFrame++;
  }
  MYFLT delaySeconds(MYFLT delaySeconds)
  {
    int delayFrames_ = (int) (delaySeconds * sampleRate);
    return delayFrames(delayFrames_);
  }
  MYFLT delayFrames(int delayFrames_)
  {
    //std::cout << "DelayLine::delayFrames: delayFrames: " << delayFrames_ << std::endl;
    int readingFrame = writingFrame - delayFrames_;
    while (readingFrame < 0) {
      readingFrame += size_;
    }
    while (readingFrame >= size_) {
      readingFrame -= size_;
    }
    // std::cout << "DelayLine::delayFrames: readingFrame: " << readingFrame << std::endl;
    return (*this)[(size_t) readingFrame];
  }
};

std::list<RCLowpassFilter *> smoothingFilterInstances;
std::list<DelayLine *> delayLineInstances;

class Doppler : public OpcodeBase<Doppler>
{
public:
  // Csound opcode outputs.
  MYFLT *audioOutput;
  // Csound opcode inputs.
  MYFLT *audioInput;
  MYFLT *kSourcePosition;     // usually meters
  MYFLT *kMicPosition;        // usually meters
  MYFLT *jSpeedOfSound;       // usually meters/second
  MYFLT *jUpdateFilterCutoff; // Hz
  // Doppler internal state.
  MYFLT speedOfSound;         // usually meters/second
  MYFLT smoothingFilterCutoff;   // Hz
  MYFLT sampleRate;           // Hz
  MYFLT samplesPerDistance;   // usually samples/meter
  MYFLT blockRate;            // Hz
  int blockSize;              // samples
  RCLowpassFilter *smoothingFilter;
  LinearInterpolator *audioInterpolator;
  std::list< std::vector<MYFLT> *> *audioBufferQueue;
  std::list<MYFLT> *sourcePositionQueue;
  int relativeIndex;
  int currentIndex;

  int init(CSOUND *csound)
  {
    sampleRate = csound->GetSr(csound);
    blockSize = csound->GetKsmps(csound);
    blockRate = sampleRate / blockSize;
    // Take care of default values.
    if (*jSpeedOfSound == MYFLT(-1.0)) {
      speedOfSound = MYFLT(340.29);
    }
    else speedOfSound = *jSpeedOfSound;
    if (*jUpdateFilterCutoff == MYFLT(-1.0)) {
//    MYFLT blockRateNyquist = blockRate / MYFLT(2.0);
//    *jUpdateFilterCutoff = blockRateNyquist / MYFLT(2.0);
      smoothingFilterCutoff = MYFLT(6.0); // very conservative
    }
    else smoothingFilterCutoff = *jUpdateFilterCutoff;
    samplesPerDistance = sampleRate / speedOfSound;
    audioInterpolator = new LinearInterpolator;
    smoothingFilter = NULL;
    audioBufferQueue = new std::list< std::vector<MYFLT> *>;
    sourcePositionQueue = new std::list<MYFLT>;
    currentIndex = 0;
    relativeIndex = 0;
    return OK;
  }
  int kontrol(CSOUND *csound)
  {
    MYFLT sourcePosition = *kSourcePosition;
    MYFLT micPosition = *kMicPosition;

    std::vector<MYFLT> *sourceBuffer = new std::vector<MYFLT>;
    sourceBuffer->resize(blockSize);
    for (size_t inputFrame = 0; inputFrame < blockSize; inputFrame++) {
      (*sourceBuffer)[inputFrame] = audioInput[inputFrame];
    }
    audioBufferQueue->push_back(sourceBuffer);
    sourcePositionQueue->push_back(sourcePosition);

    std::vector<MYFLT> *currentBuffer = audioBufferQueue->front();
    MYFLT targetPosition = sourcePositionQueue->front() - micPosition;

    // The smoothing filter cannot be initialized at i-time,
    // because it must be initialized from a k-rate variable.
    if (!smoothingFilter) {
      smoothingFilter = new RCLowpassFilter();
      smoothingFilter->initialize(sampleRate, smoothingFilterCutoff, targetPosition);
      log(csound, "Doppler::kontrol: sizeof(MYFLT):         %10d\n", sizeof(MYFLT));
      log(csound, "Doppler::kontrol: PI:                    %10.3f\n", pi);
      log(csound, "Doppler::kontrol: this:                  %10p\n", this);
      log(csound, "Doppler::kontrol: sampleRate:            %10.3f\n", sampleRate);
      log(csound, "Doppler::kontrol: blockSize:             %10.3f\n", blockSize);
      log(csound, "Doppler::kontrol: blockRate:             %10.3f\n", blockRate);
      log(csound, "Doppler::kontrol: speedOfSound:          %10.3f\n", speedOfSound);
      log(csound, "Doppler::kontrol: samplesPerDistance:    %10.3f\n", samplesPerDistance);
      log(csound, "Doppler::kontrol: smoothingFilterCutoff: %10.3f\n", smoothingFilterCutoff);
      log(csound, "Doppler::kontrol: kMicPosition:          %10.3f\n", *kMicPosition);
      log(csound, "Doppler::kontrol: kSourcePosition:       %10.3f\n", *kSourcePosition);
    }

    for (size_t outputFrame = 0; outputFrame < blockSize; outputFrame++) {
      MYFLT position = smoothingFilter->update(targetPosition);
      MYFLT distance = std::fabs(position);
      MYFLT sourceTime = relativeIndex - (distance * samplesPerDistance);
      int targetIndex = int(sourceTime);
      MYFLT fraction = sourceTime - targetIndex;
      relativeIndex++;
      for ( ; targetIndex >= currentIndex; currentIndex++) {
        if (currentIndex >= blockSize) {
          relativeIndex -= blockSize;
          currentIndex -= blockSize;
          targetIndex -= blockSize;
                delete audioBufferQueue->front();
          audioBufferQueue->pop_front();
          sourcePositionQueue->pop_front();
          currentBuffer = audioBufferQueue->front();
          targetPosition = sourcePositionQueue->front() - micPosition;
        }
        audioInterpolator->put((*currentBuffer)[currentIndex]);
      }
      MYFLT currentSample = audioInterpolator->get(fraction);
      audioOutput[outputFrame] = currentSample;
    }
    return OK;
  }
};

#ifdef NEVER
struct Doppler2 : public OpcodeBase<Doppler2>
{
  // Csound opcode outputs.
  MYFLT *audioOutput;
  // Csound opcode inputs.
  MYFLT *audioInput;
  MYFLT *kSourcePosition;
  MYFLT *kMicPosition;
  MYFLT *jSpeedOfSound;
  MYFLT *jUpdateFilterCutoff;
  // Doppler internal state.
  MYFLT speedOfSound;
  MYFLT smoothingFilterCutoff;
  MYFLT sampleRate;
  MYFLT samplesPerDistance;
  MYFLT blockSize;
  MYFLT blockRate;
  RCLowpassFilter *smoothingFilter;
  LinearInterpolator *audioInterpolator;
  DelayLine *delayLine;
  int init(CSOUND *csound)
  {
    sampleRate = csound->GetSr(csound);
    blockSize = csound->GetKsmps(csound);
    blockRate = sampleRate / blockSize;
    // Take care of default values.
    if (*jSpeedOfSound == MYFLT(-1.0)) {
      SpeedOfSound = MYFLT(340.29);
    }
    else speedOfSound = *jSpeedOfSound;
    if (*jUpdateFilterCutoff == MYFLT(-1.0)) {
      MYFLT blockRateNyquist = blockRate / MYFLT(2.0);
      smoothingFilterCutoff = blockRateNyquist / MYFLT(2.0);
    }
    else smoothingFilterCutoff = *jUpdateFilterCutoff;
    samplesPerDistance = sampleRate / speedOfSound;
    audioInterpolator = new LinearInterpolator;
    // The smoothing filter cannot be initialized at i-time,
    // because it must be initialized from a k-rate variable.
    smoothingFilter = 0;
    delayLine = new DelayLine;
    return OK;
  }
  int kontrol(CSOUND *csound)
  {
    MYFLT sourcePosition = *kSourcePosition;
    MYFLT micPosition = *kMicPosition;
    MYFLT position = sourcePosition - micPosition;
    // On the very first block only, initialize the smoothing filter.
    if (!smoothingFilter) {
      smoothingFilter = new RCLowpassFilter();
      smoothingFilter->initialize(sampleRate, smoothingFilterCutoff, *kSourcePosition);
      log(csound, "Doppler::kontrol: sizeof(MYFLT):                  %10d\n", sizeof(MYFLT));
      log(csound, "Doppler::kontrol: PI:                             %10.3f\n", pi);
      log(csound, "Doppler::kontrol: this:                           %10p\n", this);
      log(csound, "Doppler::kontrol: sampleRate:                       %10.3f\n", sampleRate);
      log(csound, "Doppler::kontrol: blockSize:                 %10.3f\n", blockSize);
      log(csound, "Doppler::kontrol: blockRate:                       %10.3f\n", blockRate);
      log(csound, "Doppler::kontrol: speedOfSound:           %10.3f\n", speedOfSound);
      log(csound, "Doppler::kontrol: samplesPerDistance:                 %10.3f\n", samplesPerDistance);
      log(csound, "Doppler::kontrol: smoothingFilterCutoff:  %10.3f\n", smoothingFilterCutoff);
      log(csound, "Doppler::kontrol: kMicPosition:             %10.3f\n", *kMicPosition);
      log(csound, "Doppler::kontrol: kSourcePosition:          %10.3f\n", *kSourcePosition);
      delayLine->initialize(sampleRate, 10.0);
    }
    for (size_t frame = 0; frame < blockSize; frame++) {
      delayLine->write(audioInput[frame]);
      MYFLT distance = std::fabs(position);
      MYFLT delayFrames = distance * samplesPerDistance;
      MYFLT delayFramesFloor = int(delayFrames);
      MYFLT fraction = delayFrames - delayFramesFloor;
      MYFLT currentValue = delayLine->delayFrames((int) delayFrames);
      audioInterpolator->put(currentValue);
      currentValue = audioInterpolator->get(fraction);
      position = smoothingFilter->update(position);
      audioOutput[frame] = currentValue;
    }
    return OK;
  }
};
#endif

extern "C"
{
  OENTRY oentries[] =
    {
      {
        (char*)"doppler",
        sizeof(Doppler),
        3,
        (char*)"a",
        (char*)"akkjj",
        (SUBR) Doppler::init_,
        (SUBR) Doppler::kontrol_,
        0,
      },
#ifdef NEVER
      {
        (char*)"doppler2",
        sizeof(Doppler2),
        3,
        (char*)"a",
        (char*)"akkjj",
        (SUBR) Doppler2::init_,
        (SUBR) Doppler2::kontrol_,
        0,
      },
#endif
      {
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
      }
    };

  PUBLIC int csoundModuleCreate(CSOUND *csound)
  {
    return 0;
  }

  PUBLIC int csoundModuleInit(CSOUND *csound)
  {
    int status = 0;
    for(OENTRY *oentry = &oentries[0]; oentry->opname; oentry++)
      {
        status |= csound->AppendOpcode(csound, oentry->opname,
                                       oentry->dsblksiz, oentry->thread,
                                       oentry->outypes, oentry->intypes,
                                       (int (*)(CSOUND*,void*)) oentry->iopadr,
                                       (int (*)(CSOUND*,void*)) oentry->kopadr,
                                       (int (*)(CSOUND*,void*)) oentry->aopadr);
      }
    return status;
  }

  PUBLIC int csoundModuleDestroy(CSOUND *csound)
  {
    //csound->Message(csound, "Deleting C++ objects from doppler...\n");
    for (std::list<RCLowpassFilter *>::iterator it = smoothingFilterInstances.begin();
         it != smoothingFilterInstances.end();
         ++it) {
      delete *it;
    }
    smoothingFilterInstances.clear();
    for (std::list<DelayLine *>::iterator it = delayLineInstances.begin();
         it != delayLineInstances.end();
         ++it) {
      delete *it;
    }
    delayLineInstances.clear();
    return 0;
  }
}

<|endoftext|>


<commit_before>#include "General.h"

#include <shellapi.h>

#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "../3RVX/SkinInfo.h"

#include "UIContext.h"

#define KEY_NAME L"3RVX"
#define STARTUP_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"

void General::Command(unsigned short nCode, unsigned short ctrlId) {
    switch (nCode) {
    case BN_CLICKED:
        if (ctrlId == BTN_WEBSITE && _url != L"") {
            ShellExecute(NULL, L"open", _url.c_str(),
                NULL, NULL, SW_SHOWNORMAL);
        }
        break;

    case CBN_SELCHANGE:
        switch (ctrlId) {
        case CMB_SKIN:
            LoadSkinInfo(_ctxt->GetComboSelection(CMB_SKIN));
            break;

        case CMB_LANG:
            // Language selection
            break;
        }
    }
}

void General::LoadSettings() {
    Settings *settings = Settings::Instance();
    _ctxt->SetCheck(CHK_STARTUP, RunOnStartup());
    _ctxt->SetCheck(CHK_NOTIFY, settings->NotifyIconEnabled());
    _ctxt->SetCheck(CHK_SOUNDS, settings->SoundEffectsEnabled());

    /* Determine which skins are available */
    std::list<std::wstring> skins = FindSkins(Settings::SkinDir().c_str());
    for (std::wstring skin : skins) {
        _ctxt->AddComboItem(CMB_SKIN, skin);
    }

    /* Update the combo box with the current skin */
    std::wstring current = settings->CurrentSkin();
    int idx = _ctxt->SelectComboItem(CMB_SKIN, current);
    if (idx == CB_ERR) {
        _ctxt->SelectComboItem(CMB_SKIN, DEFAULT_SKIN);
    }
    LoadSkinInfo(current);

//    /* Populate the language box */
//    std::list<CString> languages = FindLanguages(
//        settings->LanguagesDir().c_str());

//    for (CString language : languages) {
//        _lang.AddString(language);
//    }
//    std::wstring currentLang = settings->LanguageName();
//    _lang.SelectString(0, currentLang.c_str());
}

void General::SaveSettings() {
    RunOnStartup(true);
}

bool General::RunOnStartup() {
    long res;
    HKEY key;
    bool run = false;

    res = RegOpenKeyEx(HKEY_CURRENT_USER, STARTUP_KEY, NULL, KEY_READ, &key);
    if (res == ERROR_SUCCESS) {
        res = RegQueryValueEx(key, KEY_NAME, NULL, NULL, NULL, NULL);
        run = (res == ERROR_SUCCESS);
    }

    RegCloseKey(key);
    return run;
}

bool General::RunOnStartup(bool enable) {
    long res;
    HKEY key;
    bool ok = false;

    std::wstring path = Settings::AppDir() + L"\\3RVX.exe";

    res = RegOpenKeyEx(HKEY_CURRENT_USER, STARTUP_KEY, NULL, KEY_ALL_ACCESS, &key);
    if (res == ERROR_SUCCESS) {
        if (enable) {
            res = RegSetValueEx(key, KEY_NAME, NULL, REG_SZ,
                (LPBYTE) path.c_str(), path.size() + 1);
            ok = (res == ERROR_SUCCESS);
        } else {
            res = RegDeleteValue(key, KEY_NAME);
            ok = (res == ERROR_SUCCESS);
        }
    }
    RegCloseKey(key);
    return ok;
}

std::list<std::wstring> General::FindSkins(std::wstring dir) {
    std::list<std::wstring> skins;
    WIN32_FIND_DATA ffd;
    HANDLE hFind;

    CLOG(L"Finding skins in: %s", dir.c_str());
    dir += L"\\*";
    hFind = FindFirstFile(dir.c_str(), &ffd);
    if (hFind == INVALID_HANDLE_VALUE) {
        return skins;
    }

    do {
        std::wstring fName(ffd.cFileName);
        if (fName.at(0) == L'.') {
            continue;
        }
        QCLOG(L"%s", fName.c_str());
        skins.push_back(fName);
    } while (FindNextFile(hFind, &ffd));
    FindClose(hFind);

    return skins;
}

void General::LoadSkinInfo(std::wstring skinName) {
    std::wstring skinXML = Settings::Instance()->SkinXML(skinName);
    SkinInfo s(skinXML);

    std::wstring authorText(L"Author: ");
    authorText.append(s.Author());
    _ctxt->SetText(LBL_AUTHOR, authorText);

    std::wstring url = s.URL();
    if (url == L"") {
        _ctxt->Disable(BTN_WEBSITE);
    } else {
        _url = s.URL();
        _ctxt->Enable(BTN_WEBSITE);
    }
}

std::list<std::wstring> General::FindLanguages(std::wstring dir) {
    std::list<std::wstring> languages;
    WIN32_FIND_DATA ffd;
    HANDLE hFind;

    CLOG(L"Finding language translations in: %s", dir.c_str());
    dir += L"\\*.xml";
    hFind = FindFirstFile(dir.c_str(), &ffd);
    if (hFind == INVALID_HANDLE_VALUE) {
        CLOG(L"FindFirstFile() failed");
        return languages;
    }

    do {
        std::wstring fName(ffd.cFileName);

        if (fName.at(0) == L'.') {
            continue;
        }

        if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            continue;
        }

        QCLOG(L"%s", fName.c_str());
        languages.push_back(fName);
    } while (FindNextFile(hFind, &ffd));
    FindClose(hFind);

    return languages;
}

<commit_msg>Populate the language box<commit_after>#include "General.h"

#include <shellapi.h>

#include "../3RVX/Logger.h"
#include "../3RVX/Settings.h"
#include "../3RVX/SkinInfo.h"

#include "UIContext.h"

#define KEY_NAME L"3RVX"
#define STARTUP_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"

void General::Command(unsigned short nCode, unsigned short ctrlId) {
    switch (nCode) {
    case BN_CLICKED:
        if (ctrlId == BTN_WEBSITE && _url != L"") {
            ShellExecute(NULL, L"open", _url.c_str(),
                NULL, NULL, SW_SHOWNORMAL);
        }
        break;

    case CBN_SELCHANGE:
        switch (ctrlId) {
        case CMB_SKIN:
            LoadSkinInfo(_ctxt->GetComboSelection(CMB_SKIN));
            break;

        case CMB_LANG:
            // Language selection
            break;
        }
    }
}

void General::LoadSettings() {
    Settings *settings = Settings::Instance();
    _ctxt->SetCheck(CHK_STARTUP, RunOnStartup());
    _ctxt->SetCheck(CHK_NOTIFY, settings->NotifyIconEnabled());
    _ctxt->SetCheck(CHK_SOUNDS, settings->SoundEffectsEnabled());

    /* Determine which skins are available */
    std::list<std::wstring> skins = FindSkins(Settings::SkinDir().c_str());
    for (std::wstring skin : skins) {
        _ctxt->AddComboItem(CMB_SKIN, skin);
    }

    /* Update the combo box with the current skin */
    std::wstring current = settings->CurrentSkin();
    int idx = _ctxt->SelectComboItem(CMB_SKIN, current);
    if (idx == CB_ERR) {
        _ctxt->SelectComboItem(CMB_SKIN, DEFAULT_SKIN);
    }
    LoadSkinInfo(current);

    /* Populate the language box */
    std::list<std::wstring> languages = FindLanguages(
        settings->LanguagesDir().c_str());
    for (std::wstring language : languages) {
        _ctxt->AddComboItem(CMB_LANG, language);
    }
    std::wstring currentLang = settings->LanguageName();
    _ctxt->SelectComboItem(CMB_LANG, currentLang);
}

void General::SaveSettings() {
    RunOnStartup(true);
}

bool General::RunOnStartup() {
    long res;
    HKEY key;
    bool run = false;

    res = RegOpenKeyEx(HKEY_CURRENT_USER, STARTUP_KEY, NULL, KEY_READ, &key);
    if (res == ERROR_SUCCESS) {
        res = RegQueryValueEx(key, KEY_NAME, NULL, NULL, NULL, NULL);
        run = (res == ERROR_SUCCESS);
    }

    RegCloseKey(key);
    return run;
}

bool General::RunOnStartup(bool enable) {
    long res;
    HKEY key;
    bool ok = false;

    std::wstring path = Settings::AppDir() + L"\\3RVX.exe";

    res = RegOpenKeyEx(HKEY_CURRENT_USER, STARTUP_KEY, NULL, KEY_ALL_ACCESS, &key);
    if (res == ERROR_SUCCESS) {
        if (enable) {
            res = RegSetValueEx(key, KEY_NAME, NULL, REG_SZ,
                (LPBYTE) path.c_str(), path.size() + 1);
            ok = (res == ERROR_SUCCESS);
        } else {
            res = RegDeleteValue(key, KEY_NAME);
            ok = (res == ERROR_SUCCESS);
        }
    }
    RegCloseKey(key);
    return ok;
}

std::list<std::wstring> General::FindSkins(std::wstring dir) {
    std::list<std::wstring> skins;
    WIN32_FIND_DATA ffd;
    HANDLE hFind;

    CLOG(L"Finding skins in: %s", dir.c_str());
    dir += L"\\*";
    hFind = FindFirstFile(dir.c_str(), &ffd);
    if (hFind == INVALID_HANDLE_VALUE) {
        return skins;
    }

    do {
        std::wstring fName(ffd.cFileName);
        if (fName.at(0) == L'.') {
            continue;
        }
        QCLOG(L"%s", fName.c_str());
        skins.push_back(fName);
    } while (FindNextFile(hFind, &ffd));
    FindClose(hFind);

    return skins;
}

void General::LoadSkinInfo(std::wstring skinName) {
    std::wstring skinXML = Settings::Instance()->SkinXML(skinName);
    SkinInfo s(skinXML);

    std::wstring authorText(L"Author: ");
    authorText.append(s.Author());
    _ctxt->SetText(LBL_AUTHOR, authorText);

    std::wstring url = s.URL();
    if (url == L"") {
        _ctxt->Disable(BTN_WEBSITE);
    } else {
        _url = s.URL();
        _ctxt->Enable(BTN_WEBSITE);
    }
}

std::list<std::wstring> General::FindLanguages(std::wstring dir) {
    std::list<std::wstring> languages;
    WIN32_FIND_DATA ffd;
    HANDLE hFind;

    CLOG(L"Finding language translations in: %s", dir.c_str());
    dir += L"\\*.xml";
    hFind = FindFirstFile(dir.c_str(), &ffd);
    if (hFind == INVALID_HANDLE_VALUE) {
        CLOG(L"FindFirstFile() failed");
        return languages;
    }

    do {
        std::wstring fName(ffd.cFileName);

        if (fName.at(0) == L'.') {
            continue;
        }

        if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            continue;
        }

        QCLOG(L"%s", fName.c_str());
        languages.push_back(fName);
    } while (FindNextFile(hFind, &ffd));
    FindClose(hFind);

    return languages;
}

<|endoftext|>


<commit_before>#include "cbase.h"
//#include "asw_objective_escape.h"
#include "mod_objective_escape.h"
#include "asw_game_resource.h"
#include "asw_marine_resource.h"
#include "asw_marine.h"
#include "triggers.h"
#include "mod_player_performance.h"

#include "missionchooser/iasw_random_missions.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

LINK_ENTITY_TO_CLASS( mod_objective_escape, CMOD_Objective_Escape );

BEGIN_DATADESC( CMOD_Objective_Escape )
	DEFINE_FIELD( m_hTrigger, FIELD_EHANDLE ),
	DEFINE_INPUTFUNC( FIELD_VOID, "MarineInEscapeArea", InputMarineInEscapeArea ),
END_DATADESC()

CUtlVector<CMOD_Objective_Escape*> g_aEscapeObjectives;

//CASW_Objective_Escape * m_aswEscape;

CMOD_Objective_Escape::CMOD_Objective_Escape() : CASW_Objective()
{
	m_hTrigger = NULL;
	g_aEscapeObjectives.AddToTail( this );
	//m_aswEscape = new CASW_Objective_Escape();
}

CMOD_Objective_Escape::~CMOD_Objective_Escape()
{
	g_aEscapeObjectives.FindAndRemove( this );
}

void CMOD_Objective_Escape::Spawn(){
	//m_aswEscape = new CASW_Objective_Escape();
}

void CMOD_Objective_Escape::InputMarineInEscapeArea( inputdata_t &inputdata ){
	Msg("Maine in Escape Area");

	CBaseTrigger* pTrig = dynamic_cast<CBaseTrigger*>(inputdata.pCaller);
	if (!pTrig)
	{
		Msg("Error: Escape objective input called by something that wasn't a trigger\n");
		return;
	}
	if (pTrig != GetTrigger() && GetTrigger()!= NULL)
	{
		Msg("Error: Escape objective input called by two different triggers.  Only 1 escape area is allowed per map.\n");
		return;
	}
	m_hTrigger = pTrig;

	CheckEscapeStatus();
}

void CMOD_Objective_Escape::CheckEscapeStatus()
{
	if (OtherObjectivesComplete() && AllLiveMarinesInExit())
	{
		//Dynamically build the map for the next mission.
		BuildMapForNextMission();

		//Fires ASW_Objective::OnObjectiveComplete
		Msg("Setting Objective to Complete\n");
		SetComplete(true);
	}
}

bool CMOD_Objective_Escape::OtherObjectivesComplete(){
	if ( !ASWGameResource() )
		return false;

	CASW_Game_Resource* pGameResource = ASWGameResource();
	for (int i=0;i<12;i++)
	{
		CASW_Objective* pObjective = pGameResource->GetObjective(i);
		// if another objective isn't optional and isn't complete, then we're not ready to escape
		if (pObjective && pObjective!=this
			&& !pObjective->IsObjectiveOptional() && !pObjective->IsObjectiveComplete())
		{
			Msg("Not all Objectives complete\n");
			return false;
		}
	}
	Msg("All Objectives complete\n");
	return true;
}
bool CMOD_Objective_Escape::AllLiveMarinesInExit()
{
	if ( !ASWGameResource() ||!GetTrigger() )
	{
		Msg("All Live Marines are NOT in Exit\n");
		return false;
	}

	CASW_Game_Resource* pGameResource = ASWGameResource();
	for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
	{
		CASW_Marine_Resource* pMR = pGameResource->GetMarineResource(i);
		if (pMR && pMR->GetHealthPercent() > 0
			&& pMR->GetMarineEntity())
		{
			// we've got a live marine, check if he's in the exit area
			if (!GetTrigger()->IsTouching(pMR->GetMarineEntity()))
			{
				Msg("All Live Marines are NOT in Exit\n");
				return false;	// a live marine isn't in the exit zone
			}
		}
	}
	Msg("All Live Marines are in Exit\n");
	return true;
}

void MOD_Level_Builder::BuildMapForNextMission()
{
	CASW_Campaign_Info *pCampaign = CAlienSwarm::GetCampaignInfo();
	if (!pCampaign)
	{
		Msg("Failed to load Campaign with CAlienSwarm::GetCampaignInfo()\n");
		return;
	}

	CASW_Campaign_Save *pSave = CAlienSwarm::GetCampaignInfoGetCampaignSave();
	if (!pSave)
	{
		Msg("Failed to load Campaign Save with CAlienSwarm::GetCampaignInfoGetCampaignSave()\n");
		return;
	}

	int iNextMission = pSave->m_iNumMissionsComplete;
	CASW_Campaign_Mission_t* pNextMission = pCampaign->GetMission(iNextMission);
	if (!pNextMission)
	{
		Msg("Failed to load next campaign mission with pCampaign->GetMission(iNextMission)\n");
		return;
	}

	int iPlayerPerformance =  CMOD_Player_Performance::PlayerPerformance()->CalculatePerformance();

	missionchooser->modLevel_Builder()->BuildMapForMissionFromLayoutFile(
		pNextMission->m_MapName.ToCStr(), iPlayerPerformance);

}

CBaseTrigger* CMOD_Objective_Escape::GetTrigger()
{
	return dynamic_cast<CBaseTrigger*>(m_hTrigger.Get());
}<commit_msg><commit_after>#include "cbase.h"
//#include "asw_objective_escape.h"
#include "mod_objective_escape.h"
#include "asw_game_resource.h"
#include "asw_marine_resource.h"
#include "asw_marine.h"
#include "triggers.h"
#include "mod_player_performance.h"

#include "missionchooser/iasw_random_missions.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

LINK_ENTITY_TO_CLASS( mod_objective_escape, CMOD_Objective_Escape );

BEGIN_DATADESC( CMOD_Objective_Escape )
	DEFINE_FIELD( m_hTrigger, FIELD_EHANDLE ),
	DEFINE_INPUTFUNC( FIELD_VOID, "MarineInEscapeArea", InputMarineInEscapeArea ),
END_DATADESC()

CUtlVector<CMOD_Objective_Escape*> g_aEscapeObjectives;

//CASW_Objective_Escape * m_aswEscape;

CMOD_Objective_Escape::CMOD_Objective_Escape() : CASW_Objective()
{
	m_hTrigger = NULL;
	g_aEscapeObjectives.AddToTail( this );
	//m_aswEscape = new CASW_Objective_Escape();
}

CMOD_Objective_Escape::~CMOD_Objective_Escape()
{
	g_aEscapeObjectives.FindAndRemove( this );
}

void CMOD_Objective_Escape::Spawn(){
	//m_aswEscape = new CASW_Objective_Escape();
}

void CMOD_Objective_Escape::InputMarineInEscapeArea( inputdata_t &inputdata ){
	Msg("Maine in Escape Area");

	CBaseTrigger* pTrig = dynamic_cast<CBaseTrigger*>(inputdata.pCaller);
	if (!pTrig)
	{
		Msg("Error: Escape objective input called by something that wasn't a trigger\n");
		return;
	}
	if (pTrig != GetTrigger() && GetTrigger()!= NULL)
	{
		Msg("Error: Escape objective input called by two different triggers.  Only 1 escape area is allowed per map.\n");
		return;
	}
	m_hTrigger = pTrig;

	CheckEscapeStatus();
}

void CMOD_Objective_Escape::CheckEscapeStatus()
{
	if (OtherObjectivesComplete() && AllLiveMarinesInExit())
	{
		//Dynamically build the map for the next mission.
		BuildMapForNextMission();

		//Fires ASW_Objective::OnObjectiveComplete
		Msg("Setting Objective to Complete\n");
		SetComplete(true);
	}
}

bool CMOD_Objective_Escape::OtherObjectivesComplete(){
	if ( !ASWGameResource() )
		return false;

	CASW_Game_Resource* pGameResource = ASWGameResource();
	for (int i=0;i<12;i++)
	{
		CASW_Objective* pObjective = pGameResource->GetObjective(i);
		// if another objective isn't optional and isn't complete, then we're not ready to escape
		if (pObjective && pObjective!=this
			&& !pObjective->IsObjectiveOptional() && !pObjective->IsObjectiveComplete())
		{
			Msg("Not all Objectives complete\n");
			return false;
		}
	}
	Msg("All Objectives complete\n");
	return true;
}
bool CMOD_Objective_Escape::AllLiveMarinesInExit()
{
	if ( !ASWGameResource() ||!GetTrigger() )
	{
		Msg("All Live Marines are NOT in Exit\n");
		return false;
	}

	CASW_Game_Resource* pGameResource = ASWGameResource();
	for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
	{
		CASW_Marine_Resource* pMR = pGameResource->GetMarineResource(i);
		if (pMR && pMR->GetHealthPercent() > 0
			&& pMR->GetMarineEntity())
		{
			// we've got a live marine, check if he's in the exit area
			if (!GetTrigger()->IsTouching(pMR->GetMarineEntity()))
			{
				Msg("All Live Marines are NOT in Exit\n");
				return false;	// a live marine isn't in the exit zone
			}
		}
	}
	Msg("All Live Marines are in Exit\n");
	return true;
}

void CMOD_Objective_Escape::BuildMapForNextMission()
{
	CASW_Campaign_Info *pCampaign = CAlienSwarm::GetCampaignInfo();
	if (!pCampaign)
	{
		Msg("Failed to load Campaign with CAlienSwarm::GetCampaignInfo()\n");
		return;
	}

	CASW_Campaign_Save *pSave = CAlienSwarm::GetCampaignInfoGetCampaignSave();
	if (!pSave)
	{
		Msg("Failed to load Campaign Save with CAlienSwarm::GetCampaignInfoGetCampaignSave()\n");
		return;
	}

	int iNextMission = pSave->m_iNumMissionsComplete;
	CASW_Campaign_Mission_t* pNextMission = pCampaign->GetMission(iNextMission);
	if (!pNextMission)
	{
		Msg("Failed to load next campaign mission with pCampaign->GetMission(iNextMission)\n");
		return;
	}

	int iPlayerPerformance =  CMOD_Player_Performance::PlayerPerformance()->CalculatePerformance();

	missionchooser->modLevel_Builder()->BuildMapForMissionFromLayoutFile(
		pNextMission->m_MapName.ToCStr(), iPlayerPerformance);

}

CBaseTrigger* CMOD_Objective_Escape::GetTrigger()
{
	return dynamic_cast<CBaseTrigger*>(m_hTrigger.Get());
}<|endoftext|>


<commit_before>#include "../../../wrdSyntaxTest.hpp"

using namespace wrd;
using namespace std;

namespace {
    struct defAssignExprTest : public wrdSyntaxTest {};
}

TEST_F(defAssignExprTest, simpleGlobalDefAssign) {
    // control group.
    make().parse(R"SRC(
        age int // age is age
        main() int // main is also a main
            age := 5
            return 0
    )SRC").shouldVerified(true);
    scope& owns = (scope&) (((scopes&) getSlot().subs()).getContainer());
    scope& shares = (scope&) (((scopes&) getSlot().subs()).getNext().getContainer());
    ASSERT_FALSE(nul(shares));
    ASSERT_FALSE(nul(owns));
    ASSERT_EQ(owns.len(), 1);
    ASSERT_EQ(shares.len(), 2);

    run();
    ASSERT_EQ(getSubPack().sub<wInt>("age").cast<int>(), 0);
}

TEST_F(defAssignExprTest, simpleLocalDefAssign) {
    // control group.
    make().parse(R"SRC(
        age int // age is age
        main() int // main is also a main
            age = 3
            age := 5
            age = 2
            return 0
    )SRC").shouldVerified(true);
    run();
    ASSERT_EQ(getSubPack().sub("age").cast<int>(), 3);
}

TEST_F(defAssignExprTest, testCircularDependencies) {
    make("holymoly").parse(R"SRC(
        pack holymoly

        a := c
        b := a
        c := b // type can't be defined.

        main() int
            return 0
    )SRC").shouldParsed(true);
    shouldVerified(false);
    // however when runs it, it throws an error.
}

TEST_F(defAssignExprTest, testNearCircularDependencies) {
    make("holymoly").parse(R"SRC(
        pack holymoly

        c := 1 // type can be defined.
        a := c
        b := a

        main() int
            sys.con.print(a as str)
            sys.con.print(b as str)
            return 0
    )SRC").shouldParsed(true);
    shouldVerified(true);
    // however when runs it, it throws an error.
    // because assigning 1 to c will be done after evaluating of assignment of the 'a'.
}

TEST_F(defAssignExprTest, testDefAssign1) {
    make().parse(R"SRC(
        foo() int
            return a = 2

        a := foo() + 5

        main() int
            sys.con.print("a=" + a)
            return 0
    )SRC").shouldVerified(true);
    run();
}
<commit_msg>wrd: test: add TC for defAssignExpr<commit_after>#include "../../../wrdSyntaxTest.hpp"

using namespace wrd;
using namespace std;

namespace {
    struct defAssignExprTest : public wrdSyntaxTest {};
}

TEST_F(defAssignExprTest, simpleGlobalDefAssign) {
    // control group.
    make().parse(R"SRC(
        age int // age is age
        main() int // main is also a main
            age := 5
            return 0
    )SRC").shouldVerified(true);
    scope& owns = (scope&) (((scopes&) getSlot().subs()).getContainer());
    scope& shares = (scope&) (((scopes&) getSlot().subs()).getNext().getContainer());
    ASSERT_FALSE(nul(shares));
    ASSERT_FALSE(nul(owns));
    ASSERT_EQ(owns.len(), 1);
    ASSERT_EQ(shares.len(), 2);

    run();
    ASSERT_EQ(getSubPack().sub<wInt>("age").cast<int>(), 0);
}

TEST_F(defAssignExprTest, simpleLocalDefAssign) {
    // control group.
    make().parse(R"SRC(
        age int // age is age
        main() int // main is also a main
            age = 3
            age := 5
            age = 2
            return 0
    )SRC").shouldVerified(true);
    run();
    ASSERT_EQ(getSubPack().sub("age").cast<int>(), 3);
}

TEST_F(defAssignExprTest, testCircularDependencies) {
    make("holymoly").parse(R"SRC(
        pack holymoly

        a := c
        b := a
        c := b // type can't be defined.

        main() int
            return 0
    )SRC").shouldParsed(true);
    shouldVerified(false);
    // however when runs it, it throws an error.
}

TEST_F(defAssignExprTest, testNearCircularDependencies) {
    make("holymoly").parse(R"SRC(
        pack holymoly

        c := 1 // type can be defined.
        a := c
        b := a

        main() int
            sys.con.print(a as str)
            sys.con.print(b as str)
            return 0
    )SRC").shouldParsed(true);
    shouldVerified(true);
    // however when runs it, it throws an error.
    // because assigning 1 to c will be done after evaluating of assignment of the 'a'.
}

TEST_F(defAssignExprTest, testDefAssign1) {
    make().parse(R"SRC(
        foo() int
            return a = 2

        a := foo() + 5

        main() int
            sys.con.print("a=" + a)
            return 0
    )SRC").shouldVerified(true);
    run();
}

TEST_F(defAssignExprTest, defAssignInObjectRefersInvalidFuncNegative) {
    make().parse(R"SRC(
        aka sys.con c
        nickname := foo()

        foo() str
            c.print("I'm foo!\n")
            return 1 // this is invalid function.

        main() void
            c.print("your nickname is " + nickname)
    )SRC").shouldParsed(true);
    shouldVerified(false);
}

TEST_F(defAssignExprTest, defAssignInObjectRefersInvalidFuncNegative2) {
    make().parse(R"SRC(
        aka sys.con c
        nickname := boo() // refers the func that doesn't exist.

        foo() str
            c.print("I'm foo!\n")
            return 1 // this is invalid function.

        main() void
            c.print("your nickname is " + nickname)
    )SRC").shouldParsed(true);
    shouldVerified(false);
}
<|endoftext|>