]> Dogcows Code - chaz/yoink/commitdiff
foundational changes; tying up some loose ends
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Fri, 4 Dec 2009 04:35:25 +0000 (21:35 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Fri, 4 Dec 2009 04:35:25 +0000 (21:35 -0700)
34 files changed:
README
doc/yoink.6.in
src/Animation.cc
src/ErrorHandler.cc [new file with mode: 0644]
src/ErrorHandler.hh [new file with mode: 0644]
src/GameLayer.cc
src/GameLayer.hh
src/Hud.cc
src/Hud.hh
src/MainLayer.cc
src/MainLayer.hh
src/Makefile.am
src/Moof/Dispatch.cc [moved from src/Moof/Dispatcher.cc with 60% similarity]
src/Moof/Dispatch.hh [moved from src/Moof/Dispatcher.hh with 54% similarity]
src/Moof/Engine.cc
src/Moof/Engine.hh
src/Moof/Exception.hh
src/Moof/Layer.hh
src/Moof/Log.cc
src/Moof/Log.hh
src/Moof/ModalDialog.hh
src/Moof/Script.hh
src/Moof/Settings.cc
src/Moof/Settings.hh
src/Moof/Sound.cc
src/Moof/Texture.cc
src/Moof/Timer.cc
src/Moof/Timer.hh
src/Moof/Transition.hh
src/Moof/Video.cc
src/Moof/Video.hh
src/Tilemap.cc
src/TitleLayer.cc
src/TitleLayer.hh

diff --git a/README b/README
index eaea5adc24db2f235f3469341e9f9820c89eba1f..a583d752b6c65401339a4791394211118bb3296c 100644 (file)
--- a/README
+++ b/README
@@ -30,8 +30,7 @@ this simple, fast-moving action game to a wider audience.
 
 b) Requirements
 
-boost
-headers
+boost headers
 freealut
 libvorbis
 Lua
index ece0fa5b474108bbbde5a81c5682d245c5018b31..ec41deebeb4913b918a558727cdd2e27220f4910 100644 (file)
@@ -70,61 +70,28 @@ around, especially in the sky, if you can't find the last few.
 .br
 .SH OPTIONS
 .PP
-There are a plethora of options available for tweaking various aspects of the
-game.  All options can be set either from a configuration file or by passing
-them as arguments.
-.PP
-A
-.B yoink
-configuration file ("yoinkrc") consists of key-value pairs.  The format is not
-unlike that of other configuration files you are already familiar with.  The
-syntax used is lua.
+Options are set from config files and command-line arguments.  A
 .B yoink
-looks for configuration files and loads them in this order, the options from
-each subsequent configuration files taking precedence over the same options if
-they exist in previous files.
+configfile ("yoinkrc") consists of key-value pairs.  They are loaded in this
+order:
 .TP
 1. @DATADIR@/yoinkrc
-This is the base configuration file which should be considered read-only.  Look
-to this file as an example of the format used for configuration files.
+This is the base config file which should be considered read-only.  Look to this
+file as an example of the format used for config files.
 .TP
 2. /etc/yoinkrc
-This is the system-wide configuration file.  Not available on Windows.
+This is the system-wide config file.  Not available on Windows.
 .TP
 3. $HOME/.yoinkrc
-This is your own personal configuration file.
+This is your own personal config file.
 .TP
 4. $YOINKRC
-This is an optional environment variable you can set to point to a configuration
-file.
-.PP
-Options that are passed as arguments take precedence over options loaded from
-the configuration file(s).  This mechanism can be used to play the game with
-temporary settings which you do not intend to retain.  Here are some examples of
-passing options on the command-line:
-.PP
-.TP
-yoink fullscreen=true
-Run Yoink with the option
-.I fullscreen
-as true.  This will run the game in full-screen mode.
-.TP
-yoink maxfps=60
-Run Yoink with the option
-.I maxfps
-as 60.  This will cap the display rate at 60Hz.
+This is an optional environment variable you can set to the path of a config
+file at a non-standard location.
 .PP
-You can also set options with array values.  Arrays can be passed on the command
-line by surrounding all the parts with curly brackets and separating each part
-by a comma.  You may also have to quote the brackets so your shell doesn't parse
-them.  For example:
-.TP
-yoink videomode=\\{1024,768\\}
-Run Yoink with the top
-.I videomode
-as the numbers 1024 and 768.  The video size will be 1024x768.
-.PP
-Here is a list of some of the options available:
+As usual, options that are passed as arguments take precedence over options
+loaded from the config file(s).  Here is a list of some of the options available
+at your disposal:
 .TP
 .B detail
 The level of detail.  Possible values are 1, 2, or 3 where 1 means the least
@@ -180,11 +147,26 @@ is 80.
 .B videomode
 The resolution or size of the window.  The value is an array with three number
 elements representing the width, height, and bits per pixel that make up the
-video mode.  The third number is optional.  The default value is {800, 600}.
+video mode.  The third number is optional.  The default value is {800,600}.  You
+may need to escape the curly braces so the shell doesn't parse them.
 .PP
 This is only a list of the more useful options.  You'll have to use the source
 to find out about the more esoteric options, but you probably won't need to.
 .br
+.SH EXAMPLES
+.PP
+Here are some examples of typical usage:
+.PP
+.TP
+yoink fullscreen=true
+Run Yoink in full-screen mode.
+.TP
+yoink maxfps=60
+Cap the allowable frame-rate to 60Hz.
+.TP
+yoink videomode=\\{1024,768\\}
+Run yoink with a resultion of 1024x768.  Notice the escapes for the curly
+braces so the shell doesn't parse them.
 .SH ENVIRONMENT
 .PP
 .B yoink
@@ -195,7 +177,7 @@ If set to a path of a valid directory (presumably a user's home directory),
 .B yoink
 will look for a file at
 .I $HOME/.yoinkrc
-and load it as a configuration file.
+and load it as a config file.
 .TP
 USER
 .B yoink
@@ -210,10 +192,10 @@ variable if you move the game's assets to another directory or perhaps want to
 load your own custom assets rather than the defaults.
 .TP
 YOINKRC
-If set to a path of a valid configuration file, 
+If set to a path of a valid config file, 
 .B yoink
 will load the options from that file, and those options will take precedence
-over options loaded from other configuration files.
+over options loaded from other config files.
 .br
 .SH NOTES
 .PP
@@ -239,10 +221,10 @@ Use the
 option.  You can set the timestep to be as low as the your
 .I maxfps
 option, but it is not recommended to set this lower than the target frame rate.
-Remember the trade-off here is decreased simulation accuracy.  Try this to set
-your frame rate to 30Hz and your timestep to 60Hz:
+Remember the trade-off here is decreased simulation accuracy.  Try to set your
+maxfps to 30Hz and your timestep to 60Hz:
 .PP
-yoink maxfps=30 timestep=maxfps\\*2
+yoink maxfps=30 timestep=60
 .TP
 3. Decrease the level of rendering detail.
 Use the
@@ -253,7 +235,9 @@ than choppy animation.
 .SH BUGS
 .PP
 Although the pixelated graphics are intentional, there are some unintended
-artifacts which are more obvious on certain OpenGL implementations.
+artifacts which are more obvious with certain video drivers.
+.PP
+The robots are not very bright.
 .PP
 Send bug reports, patches, and love notes to:
 .br
index c694aecc44b0b3ef8df581c0a85d0efa8ac17f5e..ab178df6f9850a27b0d94e36aad786fc40f3c439 100644 (file)
@@ -166,8 +166,8 @@ class Animation::Impl
                        Mf::Script script;
                        std::string filePath = Animation::getPath(getName());
 
-                       script.importStandardLibraries();
-                       importLogScript(script);
+                       script.importBaseLibrary();
+                       importLogPrintFunction(script);
                        importAnimationBindings(script);
 
                        if (script.doFile(filePath) != Mf::Script::SUCCESS)
diff --git a/src/ErrorHandler.cc b/src/ErrorHandler.cc
new file mode 100644 (file)
index 0000000..66a488e
--- /dev/null
@@ -0,0 +1,87 @@
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+ Redistribution   and   use  in  source  and  binary  forms,  with  or  without
+ modification, are permitted provided that the following conditions are met:
+   * Redistributions  of  source  code  must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+   * Redistributions  in binary form must reproduce the above copyright notice,
+     this  list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+ THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <sstream>
+
+#include "ErrorHandler.hh"
+
+
+std::string getErrorString(const Mf::Exception& e)
+{
+       std::string str;
+
+       switch(e.code())
+       {
+               case Mf::ErrorCode::FASTEVENTS_INIT:
+               case Mf::ErrorCode::SDL_INIT:
+                       str += "An error occurred during SDL initialization: ";
+                       str += e.what();
+                       return str;
+
+               case Mf::ErrorCode::FILE_NOT_FOUND:
+                       str += "A required file (";
+                       str += e.what();
+                       str += ") could not be found.";
+                       return str;
+
+               case Mf::ErrorCode::RESOURCE_NOT_FOUND:
+                       str += "A required resource (";
+                       str += e.what();
+                       str += ") could not be found.";
+                       return str;
+
+               case Mf::ErrorCode::SCRIPT_ERROR:
+                       str += "An error occurred in a script: ";
+                       str == e.what();
+                       return str;
+
+               case Mf::ErrorCode::SDL_VIDEOMODE:
+                       str += "An error occurred while trying to set up the video mode.";
+                       return str;
+
+               case Mf::ErrorCode::UNKNOWN_AUDIO_FORMAT:
+                       str += "An error occurred while trying to load an audio file, ";
+                       str += e.what();
+                       str += ".";
+                       return str;
+
+               case Mf::ErrorCode::UNKNOWN_IMAGE_FORMAT:
+                       str += "An error occurred while trying to load an image file, ";
+                       str += e.what();
+                       str += ".";
+                       return str;
+       }
+
+       std::ostringstream stream;
+       stream << "An unknown error (code " << e.code() << ") occurred.";
+       return stream.str();
+}
+
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/ErrorHandler.hh b/src/ErrorHandler.hh
new file mode 100644 (file)
index 0000000..2b13b1d
--- /dev/null
@@ -0,0 +1,41 @@
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+ Redistribution   and   use  in  source  and  binary  forms,  with  or  without
+ modification, are permitted provided that the following conditions are met:
+   * Redistributions  of  source  code  must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+   * Redistributions  in binary form must reproduce the above copyright notice,
+     this  list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+ THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _ERRORHANDLER_HH_
+#define _ERRORHANDLER_HH_
+
+#include <Moof/Exception.hh>
+
+
+std::string getErrorString(const Mf::Exception& e);
+
+
+#endif // _ERRORHANDLER_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
index a37f175801e8e38e280dfa857f9798724fd2c3b6..f61ec3d43adf07da1b7fe0d9884fa713ae0d83d1 100644 (file)
@@ -34,6 +34,7 @@
 #include <Moof/Video.hh>
 
 #include "GameLayer.hh"
+#include "Hud.hh"
 
 #if HAVE_CONFIG_H
 #include "config.h"
@@ -45,37 +46,40 @@ Mf::Scalar GameLayer::getZCoord(const Mf::Vector2& position) const
 {
        Mf::Scalar z;
 
-       mScript.getGlobalTable().pushField("GetZCoord");
-       mScript.push(position[0]);
-       mScript.push(position[1]);
-       mScript.call(2, 1);
-       mScript.getTop().get(z);
-       mScript.pop();
+       mState.script.getGlobalTable().pushField("GetZCoord");
+       mState.script.push(position[0]);
+       mState.script.push(position[1]);
+       mState.script.call(2, 1);
+       mState.script.getTop().get(z);
+       mState.script.pop();
 
        return z;
 }
 
 void GameLayer::loadSceneLoader()
 {
+       mState.script.importStandardLibraries();
+       importLogPrintFunction(mState.script);
+
        std::string loaderPath = Scene::getPath("loader");
        if (loaderPath == "")
        {
                throw Mf::Exception(Mf::ErrorCode::RESOURCE_NOT_FOUND, "loader");
        }
 
-       Mf::Script::Status status = mScript.doFile(loaderPath);
+       Mf::Script::Status status = mState.script.doFile(loaderPath);
        if (status != Mf::Script::SUCCESS)
        {
                std::string str;
-               mScript[-1].get(str);
+               mState.script[-1].get(str);
 
                Mf::logScript("%s", str.c_str());
-               throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str.c_str());
+               throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str);
        }
 
-       mScript.getGlobalTable().pushField("scenes");
-       mScript.getTop().get(mSceneList);
-       if (mSceneList.size() == 0)
+       mState.script.getGlobalTable().pushField("scenes");
+       mState.script.getTop().get(mState.sceneList);
+       if (mState.sceneList.size() == 0)
        {
                Mf::logScript("no variable `scenes' within loader");
                throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, "no scenes to load");
@@ -84,11 +88,11 @@ void GameLayer::loadSceneLoader()
 
 void GameLayer::advanceScene()
 {
-       if (mSceneList.size() != 0)
+       if (mState.sceneList.size() != 0)
        {
-               mScene = Scene::alloc(mSceneList[0]);
-               mSceneList.erase(mSceneList.begin());
-               mScene->load(mScript);
+               mState.scene = Scene::alloc(mState.sceneList[0]);
+               mState.sceneList.erase(mState.sceneList.begin());
+               mState.scene->load(mState.script);
        }
 }
 
@@ -104,47 +108,41 @@ GameLayer::GameLayer() :
        loadSceneLoader();
        advanceScene();                         // load the first scene
 
-       mHeroine = Heroine::alloc();
-       mHeroine->animation.startSequence("FlyDiagonallyUp");
+       mState.heroine = Heroine::alloc();
+       mState.heroine->animation.startSequence("FlyDiagonallyUp");
 
        Mf::Scalar a[6] = {0.0, 1.5, -0.5, 3.0, -2.0, 1.0};
-       mInterp.init(a, 2.0, Mf::Interpolator::OSCILLATE);
+       mState.interp.init(a, 2.0, Mf::Interpolator::OSCILLATE);
 
        setProjection();
-
-       mHud = Hud::alloc();
 }
 
 
 void GameLayer::pushed(Mf::Engine& engine)
 {
-       engine.push(mHud);
+       engine.push(Hud::alloc(mState));
 }
 
 
-void GameLayer::update(Mf::Scalar t, Mf::Scalar dt)
+void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
 {
-       mCamera.update(t, dt);
-       mHeroine->update(t, dt);
+       mState.camera.update(t, dt);
+       mState.heroine->update(t, dt);
 
-       mScene->checkForCollision(*mHeroine);
+       mState.scene->checkForCollision(*mState.heroine);
 
-       mCamera.setPosition(Mf::Vector3(-mHeroine->getState().position[0],
-                               -mHeroine->getState().position[1], -10));
-       //mCamera.lookAt(Mf::promote(mHeroine->getState().position));
+       mState.camera.setPosition(Mf::Vector3(-mState.heroine->getState().position[0],
+                               -mState.heroine->getState().position[1], -10));
+       //mState.camera.lookAt(Mf::promote(mState.heroine->getState().position));
 
-       //Mf::Vector3 heroinePosition = Mf::promote(mHeroine->getState().position);
+       //Mf::Vector3 heroinePosition = Mf::promote(mState.heroine->getState().position);
        //Mf::Sound::setListenerPosition(heroinePosition);
-       
-       mInterp.update(t, dt);
-       mHud->setBar1Progress(mInterp.getState(dt));
-       mHud->setBar2Progress(1.0 - mInterp.getState(dt));
 }
 
 
-void GameLayer::draw(Mf::Scalar alpha) const
+void GameLayer::draw(Mf::Engine& engine, Mf::Scalar alpha) const
 {
-       mCamera.uploadToGL(alpha);
+       mState.camera.uploadToGL(alpha);
 
        // DRAW THE SCENE
        Mf::Texture::resetBind();
@@ -152,45 +150,51 @@ void GameLayer::draw(Mf::Scalar alpha) const
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-       mScene->drawIfVisible(alpha, mCamera.getFrustum());
+       mState.scene->drawIfVisible(alpha, mState.camera.getFrustum());
 
-       mHeroine->setZCoord(getZCoord(mHeroine->getState().position));
-       mHeroine->draw(alpha);
+       mState.heroine->setZCoord(getZCoord(mState.heroine->getState().position));
+       mState.heroine->draw(alpha);
 }
 
-bool GameLayer::handleEvent(const Mf::Event& event)
+bool GameLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event)
 {
        switch (event.type)
        {
                case SDL_KEYDOWN:
                        if (event.key.keysym.sym == SDLK_SPACE)
                        {
-                               mHeroine->animation.startSequence("Flattened");
+                               mState.heroine->animation.startSequence("Flattened");
                                Mf::logInfo("thump!");
                                mPunchSound.play();
                                return true;
                        }
-                       else if (event.key.keysym.sym == SDLK_p)
+                       else if (event.key.keysym.sym == SDLK_m)
                        {
                                mMusic.toggle();
                                return true;
                        }
-                       else if (event.key.keysym.sym == SDLK_y)
+                       return mState.heroine->handleEvent(event);
+
+               case SDL_KEYUP:
+                       if (event.key.keysym.sym == SDLK_ESCAPE)
                        {
-                               Mf::Engine::getInstance().pop();
+                               engine.pop(this);
                                return true;
                        }
-
-               case SDL_KEYUP:
-                       return mHeroine->handleEvent(event);
+                       else if (event.key.keysym.sym == SDLK_h)
+                       {
+                               engine.push(Hud::alloc(mState));
+                               return true;
+                       }
+                       return mState.heroine->handleEvent(event);
 
                case SDL_MOUSEMOTION:
                case SDL_MOUSEBUTTONDOWN:
-                       mCamera.handleEvent(event);
+                       mState.camera.handleEvent(event);
                        return true;
 
                case SDL_VIDEORESIZE:
-                       setProjection(Mf::Scalar(event.resize.w), Mf::Scalar(event.resize.h));
+                       setProjection(event.resize.w, event.resize.h);
                        break;
        }
 
@@ -200,13 +204,13 @@ bool GameLayer::handleEvent(const Mf::Event& event)
 
 void GameLayer::setProjection()
 {
-       Mf::Video& video = Mf::Engine::getInstance().getVideo();
-       setProjection(video.getWidth(), video.getHeight());
+       Mf::VideoP video = Mf::Engine::getInstance().getVideo();
+       setProjection(video->getWidth(), video->getHeight());
 }
 
 void GameLayer::setProjection(Mf::Scalar width, Mf::Scalar height)
 {
-       mCamera.setProjection(cml::rad(60.0), width / height, 1.0, 200.0);
+       mState.camera.setProjection(cml::rad(60.0), width / height, 1.0, 200.0);
 }
 
 
index 4e26e689b495a12a39289041ac7fe992b5e085a7..d75d9dc467e07ca998c57374e4482ac816b48112 100644 (file)
@@ -41,7 +41,6 @@
 #include <boost/shared_ptr.hpp>
 
 #include <Moof/Camera.hh>
-#include <Moof/Dispatcher.hh>
 #include <Moof/Interpolator.hh>
 #include <Moof/Layer.hh>
 #include <Moof/Math.hh>
@@ -50,7 +49,6 @@
 
 #include "Character.hh"
 #include "Heroine.hh"
-#include "Hud.hh"
 #include "Scene.hh"
 
 
@@ -69,9 +67,24 @@ public:
 
        void pushed(Mf::Engine& engine);
 
-       void update(Mf::Scalar t, Mf::Scalar dt);
-       void draw(Mf::Scalar alpha) const;
-       bool handleEvent(const Mf::Event& event);
+       void update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt);
+       void draw(Mf::Engine& engine, Mf::Scalar alpha) const;
+       bool handleEvent(Mf::Engine& engine, const Mf::Event& event);
+
+       struct State
+       {
+               // the script object must be mutable because some script functions must be
+               // called during draw
+               mutable Mf::Script                      script;
+               std::vector<std::string>        sceneList;
+
+               HeroineP                heroine;
+               SceneP                  scene;
+
+               Mf::PolynomialInterpolator<5> interp;
+
+               Mf::Camera              camera;
+       };
 
 private:
 
@@ -83,23 +96,9 @@ private:
        void setProjection();
        void setProjection(Mf::Scalar width, Mf::Scalar height);
 
-
-       // the script object must be mutable because some script functions must be
-       // called during draw
-       mutable Mf::Script                      mScript;
-       std::vector<std::string>        mSceneList;
-
-       Mf::Sound               mMusic;
-       Mf::Sound               mPunchSound;
-
-       HeroineP                mHeroine;
-       SceneP                  mScene;
-
-       Mf::PolynomialInterpolator<5> mInterp;
-
-       Mf::Camera              mCamera;
-
-       HudP                    mHud;
+       State           mState;
+       Mf::Sound       mMusic;
+       Mf::Sound       mPunchSound;
 };
 
 
index a7e141e1ef8a7d57138ffb1fc9a2dff80421e2e7..90f5dd9418dd90f85bb25bc72ef631d0af5ebf90 100644 (file)
 
 *******************************************************************************/
 
+#include <Moof/Engine.hh>
 #include <Moof/OpenGL.hh>
+#include <Moof/Video.hh>
 
 #include "Hud.hh"
 
-#include <iostream>
-
 
 ProgressBar::ProgressBar(const Tilemap& tilemap, Tilemap::Index index) :
        mProgress(0.0),
@@ -118,12 +118,14 @@ void ProgressBar::draw(Mf::Scalar alpha) const
 }
 
 
-Hud::Hud() :
+Hud::Hud(GameLayer::State& state) :
+       mState(state),
        mBar1(Tilemap("StatusBars"), 0),
        mBar2(Tilemap("StatusBars"), 2),
        mFont("Font")
 {
-       resize(800, 600);
+       Mf::VideoP video = Mf::Engine::getInstance().getVideo();
+       resize(video->getWidth(), video->getHeight());
 }
 
 
@@ -145,7 +147,14 @@ void Hud::resize(int width, int height)
 }
 
 
-void Hud::draw(Mf::Scalar alpha) const
+void Hud::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
+{
+       mState.interp.update(t, dt);
+       setBar1Progress(mState.interp.getState(dt));
+       setBar2Progress(1.0 - mState.interp.getState(dt));
+}
+
+void Hud::draw(Mf::Engine& engine, Mf::Scalar alpha) const
 {
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
@@ -171,10 +180,19 @@ void Hud::draw(Mf::Scalar alpha) const
        glPopMatrix();
 }
 
-bool Hud::handleEvent(Mf::Event& event)
+bool Hud::handleEvent(Mf::Engine& engine, const Mf::Event& event)
 {
        switch (event.type)
        {
+               case SDL_KEYUP:
+                       if (event.key.keysym.sym == SDLK_h)
+                       {
+                               // don't want the hud anymore
+                               engine.pop(this);
+                               return true;
+                       }
+                       break;
+
                case SDL_VIDEORESIZE:
                        resize(event.resize.w, event.resize.h);
                        break;
index 59f0631a964dcf391de2aff2bdfbf45ffaf976a2..d3675a476c85b62dcb5782256dd2856bfce9f506 100644 (file)
@@ -39,6 +39,7 @@
 #include <Moof/Math.hh>
 #include <Moof/Rectangle.hh>
 
+#include "GameLayer.hh"
 #include "Tilemap.hh"
 
 
@@ -76,11 +77,11 @@ class Hud : public Mf::Layer
 {
 public:
 
-       Hud();
+       Hud(GameLayer::State& state);
 
-       static HudP alloc()
+       static HudP alloc(GameLayer::State& state)
        {
-               return HudP(new Hud);
+               return HudP(new Hud(state));
        }
 
        void setBar1Progress(Mf::Scalar progress)
@@ -99,11 +100,14 @@ public:
 
        void resize(int width, int height);
 
-       void draw(Mf::Scalar alpha = 0.0) const;
-       bool handleEvent(Mf::Event& event);
+       void update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt);
+       void draw(Mf::Engine& engine, Mf::Scalar alpha = 0.0) const;
+       bool handleEvent(Mf::Engine& engine, const Mf::Event& event);
 
 private:
 
+       GameLayer::State&               mState;
+
        ProgressBar     mBar1;
        ProgressBar     mBar2;
 
index 6a426fb8f41c89cfba117571a945a554854fffb9..38c849ebd08129cf2c2f83dcc447329f5546db3a 100644 (file)
 #include <string>
 #include <unistd.h>            // access
 
-#include <Moof/Dispatcher.hh>
-#include <Moof/Exception.hh>
 #include <Moof/Log.hh>
 #include <Moof/ModalDialog.hh>
 #include <Moof/OpenGL.hh>
 #include <Moof/Resource.hh>
+#include <Moof/Settings.hh>
 #include <Moof/Transition.hh>
 #include <Moof/Video.hh>
 
+#include "ErrorHandler.hh"
 #include "GameLayer.hh"
 #include "MainLayer.hh"
 #include "TitleLayer.hh"
 
 MainLayer::MainLayer()
 {
-       Mf::dispatcher::addHandler("video.context_recreated",
-                       boost::bind(&MainLayer::contextRecreated, this, _1), this);
+       mDispatchHandler = Mf::Engine::getInstance().addHandler("video.newcontext",
+                       boost::bind(&MainLayer::contextRecreated, this));
        setupGL();
 }
 
-MainLayer::~MainLayer()
-{
-       Mf::dispatcher::removeHandler(this);
-}
-
-
 void MainLayer::pushed(Mf::Engine& engine)
 {
-       mEngine = &engine;
-
        //Mf::Scalar coeff[] = {0.0, 1.0};
        //Mf::Lerp interp(coeff, 0.25);
 
@@ -75,11 +67,20 @@ void MainLayer::pushed(Mf::Engine& engine)
                //Mf::Transition<Mf::Lerp>::alloc(gameLayer, Mf::LayerP(), interp);
        //engine->push(transition);
        //engine->push(GameLayer::alloc());
-       mEngine->push(TitleLayer::alloc());
+       engine.push(TitleLayer::alloc());
 }
 
 
-void MainLayer::draw(Mf::Scalar alpha) const
+void MainLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
+{
+       if (engine.getSize() == 1)
+       {
+               // this is the only layer left on the stack
+               engine.push(TitleLayer::alloc());
+       }
+}
+
+void MainLayer::draw(Mf::Engine& engine, Mf::Scalar alpha) const
 {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -90,28 +91,24 @@ void MainLayer::draw(Mf::Scalar alpha) const
        glLoadIdentity();
 }
 
-bool MainLayer::handleEvent(const Mf::Event& event)
+bool MainLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event)
 {
        switch (event.type)
        {
-               case SDL_KEYDOWN:
+               case SDL_KEYUP:
                        if (event.key.keysym.sym == SDLK_ESCAPE)
                        {
-                               quit();
+                               engine.clear();
                        }
                        else if (event.key.keysym.sym == SDLK_f)
                        {
-                               mEngine->getVideo().toggleFull();
+                               engine.getVideo()->toggleFull();
                        }
                        else if (event.key.keysym.sym == SDLK_l)
                        {
-                               Mf::Video& video = mEngine->getVideo();
-                               video.toggleCursorGrab();
-                               video.toggleCursorVisible();
-                       }
-                       else if (event.key.keysym.sym == SDLK_y)
-                       {
-                               mEngine->push(GameLayer::alloc());
+                               Mf::VideoP video = engine.getVideo();
+                               video->toggleCursorGrab();
+                               video->toggleCursorVisible();
                        }
                        break;
 
@@ -120,19 +117,13 @@ bool MainLayer::handleEvent(const Mf::Event& event)
                        break;
 
                case SDL_QUIT:
-                       quit();
+                       engine.clear();
                        break;
        }
 
        return false;
 }
 
-void MainLayer::quit()
-{
-       // remove all the layers
-       mEngine->clear();
-}
-
 
 void MainLayer::setupGL()
 {
@@ -157,7 +148,7 @@ void MainLayer::setupGL()
        glMatrixMode(GL_MODELVIEW);
 }
 
-void MainLayer::contextRecreated(const Mf::Notification* note)
+void MainLayer::contextRecreated()
 {
        // whenever the context is destroyed and a new one created, it probably
        // won't contain our state so we need to set that up again
@@ -272,6 +263,7 @@ int main(int argc, char* argv[])
                }
        }
 
+
        std::cout << std::endl << PACKAGE_STRING << std::endl
                          << "Compiled " << __TIME__ " " __DATE__ << std::endl
                          << "Send patches and bug reports to <"
@@ -305,19 +297,20 @@ int main(int argc, char* argv[])
 
        Mf::Resource::addSearchPath(YOINK_DATADIR);
 
-       std::string iconFile = Mf::Resource::getPath(PACKAGE".png");
-
 
        // Build the list of config files to search for, in this order:
        // 1. YOINK_DATADIR/yoinkrc
-       // 2. /etc/yoinkrc
+       // 2. /etc/yoinkrc (not for Windows)
        // 3. $HOME/.yoinkrc
        // 4. YOINKRC (environment)
 
        std::string configFiles;
 
        configFiles += Mf::Resource::getPath("yoinkrc");
-       configFiles += ":/etc/yoinkrc:$HOME/.yoinkrc";
+#if !defined(_WIN32) && !defined(__WIN32__)
+       configFiles += ":/etc/yoinkrc";
+#endif
+       configFiles += ":$HOME/.yoinkrc";
 
        char* configFile = getenv("YOINKRC");
        if (configFile)
@@ -326,22 +319,27 @@ int main(int argc, char* argv[])
                configFiles += configFile;
        }
 
+       Mf::Settings& settings = Mf::Settings::getInstance();
+       settings.loadFromFile(configFiles);
+       settings.parseArgs(argc, argv);
+
+       std::string iconFile = Mf::Resource::getPath(PACKAGE".png");
+
+
        try
        {
-               Mf::Engine app(argc, argv, PACKAGE_STRING, iconFile, configFiles);
+               Mf::Engine& app = Mf::Engine::getInstance();
+               app.setVideo(Mf::Video::alloc(PACKAGE_STRING, iconFile));
                app.push(MainLayer::alloc());
 
                app.run();
        }
        catch (const Mf::Exception& e)
        {
-               Mf::logError("unhandled exception (code %d): \"%s\"",
-                               e.code(), e.what());
-
                Mf::ModalDialog dialog;
                dialog.title = PACKAGE_STRING;
                dialog.text1 = "Unhandled Exception";
-               dialog.text2 = e.what();
+               dialog.text2 = getErrorString(e);
                dialog.type = Mf::ModalDialog::CRITICAL;
                dialog.run();
 
index 97385830a326259ea64e5b6534530ff2579dd0ed..731adef4e2239018d91708afa184f334aed47831 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <boost/shared_ptr.hpp>
 
+#include <Moof/Dispatch.hh>
 #include <Moof/Engine.hh>
 #include <Moof/Layer.hh>
 #include <Moof/Math.hh>
@@ -52,7 +53,6 @@ class MainLayer : public Mf::Layer
 public:
 
        MainLayer();
-       ~MainLayer();
 
        static MainLayerP alloc()
        {
@@ -61,10 +61,9 @@ public:
 
        void pushed(Mf::Engine& engine);
 
-       void draw(Mf::Scalar alpha) const;
-       bool handleEvent(const Mf::Event& event);
-
-       void quit();
+       void update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt);
+       void draw(Mf::Engine& engine, Mf::Scalar alpha) const;
+       bool handleEvent(Mf::Engine& engine, const Mf::Event& event);
 
 private:
 
@@ -72,9 +71,9 @@ private:
         * Set OpenGL to a state we can know and depend on.
         */
        void setupGL();
-       void contextRecreated(const Mf::Notification* note);
+       void contextRecreated();
 
-       Mf::Engine* mEngine;
+       Mf::Dispatch::Handler   mDispatchHandler;
 };
 
 
index c5cddeb40915e811039c1ffccbec03fde81644c8..c0600cd56f732c03292fc32a1ca662e554c11f9e 100644 (file)
@@ -19,8 +19,8 @@ libmoof_a_SOURCES = \
                                        Moof/ConvertUTF.c \
                                        Moof/ConvertUTF.h \
                                        Moof/Cullable.hh \
-                                       Moof/Dispatcher.cc \
-                                       Moof/Dispatcher.hh \
+                                       Moof/Dispatch.cc \
+                                       Moof/Dispatch.hh \
                                        Moof/Drawable.hh \
                                        Moof/Engine.cc \
                                        Moof/Engine.hh \
@@ -86,6 +86,8 @@ yoink_SOURCES = \
                                Animation.hh \
                                Character.cc \
                                Character.hh \
+                               ErrorHandler.cc \
+                               ErrorHandler.hh \
                                GameLayer.cc \
                                GameLayer.hh \
                                Heroine.cc \
similarity index 60%
rename from src/Moof/Dispatcher.cc
rename to src/Moof/Dispatch.cc
index 320746485199d227a77dbb4624015969e8bc09b2..17f8f172803901513733b4fc8905b9717848ab1e 100644 (file)
 
 #include <map>
 
-#include "Dispatcher.hh"
+#include "Dispatch.hh"
 
 
 namespace Mf {
 
 
-class Dispatcher::Impl
+class Dispatch::Impl
 {
-       friend class Dispatcher;
+public:
 
        Impl() :
-               mId(1) {}
+               mId(0) {}
 
-       Dispatcher::Handler getNewHandler()
+       Dispatch::Handler getNewHandler()
        {
-               mId += 2;
-               return (Dispatcher::Handler)mId;
+               ++mId;
+               //return Dispatch::Handler(this, mId);
+               Dispatch::Handler handler(this, mId);
+               return handler;
        }
 
-       typedef std::pair<Dispatcher::Handler,Dispatcher::Function>     Callback;
-       typedef std::multimap<std::string,Callback>                                     CallbackLookup;
-       typedef CallbackLookup::iterator                                                        CallbackIter;
+       typedef std::pair<unsigned,Dispatch::Function>  Callback;
+       typedef std::multimap<std::string,Callback>             CallbackLookup;
+       typedef CallbackLookup::iterator                                CallbackIter;
 
-       typedef std::multimap<Dispatcher::Handler,std::string>          HandlerLookup;
-       typedef HandlerLookup::iterator                                                         HandlerIter;
+       typedef std::multimap<unsigned,std::string>             HandlerLookup;
+       typedef HandlerLookup::iterator                                 HandlerIter;
 
 
-       inline Handler addHandler(const std::string& message,
-                       const Function& callback, Handler id)
+       inline Handler addHandler(const std::string& event,
+                       const Function& callback, Handler handler)
        {
-               mCallbacks.insert(std::make_pair(message, std::make_pair(id, callback)));
-               mHandlers.insert(std::make_pair(id, message));
+               mCallbacks.insert(std::make_pair(event,
+                                       std::make_pair(handler.getId(), callback)));
+               mHandlers.insert(std::make_pair(handler.getId(), event));
 
-               return id;
+               return handler;
        }
 
-       inline void removeHandler(Handler id)
+       inline void removeHandler(unsigned id)
        {
                std::pair<HandlerIter,HandlerIter> matching(mHandlers.equal_range(id));
 
@@ -86,64 +89,73 @@ class Dispatcher::Impl
                mHandlers.erase(id);
        }
 
-       void dispatch(const std::string& message, const Notification* param)
+       void dispatch(const std::string& event, const Message* message)
        {
                std::pair<CallbackIter,CallbackIter>
-                       callbacks(mCallbacks.equal_range(message));
+                       callbacks(mCallbacks.equal_range(event));
 
                for (CallbackIter it = callbacks.first; it != callbacks.second; ++it)
                {
                        Function callback = (*it).second.second;
-                       callback(param);
+                       callback(message);
                }
        }
 
 
-       unsigned long   mId;
+       unsigned                mId;
 
        CallbackLookup  mCallbacks;
        HandlerLookup   mHandlers;
 };
 
 
-Dispatcher::Dispatcher() :
-       mImpl(new Dispatcher::Impl) {}
+Dispatch::Handler::~Handler()
+{
+       if (mId)
+       {
+               mDispatch->removeHandler(mId);
+       }
+}
+
+
+Dispatch::Dispatch() :
+       mImpl(new Dispatch::Impl) {}
 
-Dispatcher::~Dispatcher() {}
+Dispatch::~Dispatch() {}
 
 
-Dispatcher& Dispatcher::getInstance()
+Dispatch& Dispatch::getInstance()
 {
-       static Dispatcher dispatcher;
-       return dispatcher;
+       static Dispatch dispatch;
+       return dispatch;
 }
 
 
-Dispatcher::Handler Dispatcher::addHandler(const std::string& message,
+Dispatch::Handler Dispatch::addHandler(const std::string& event,
                const Function& callback)
 {
-       return addHandler(message, callback, mImpl->getNewHandler());
+       return addHandler(event, callback, mImpl->getNewHandler());
 }
 
-Dispatcher::Handler Dispatcher::addHandler(const std::string& message,
-               const Function& callback, Handler id)
+Dispatch::Handler Dispatch::addHandler(const std::string& event,
+               const Function& callback, Handler handler)
 {
        // pass through
-       return mImpl->addHandler(message, callback, id);
+       return mImpl->addHandler(event, callback, handler);
 }
 
 
-void Dispatcher::removeHandler(Handler id)
+void Dispatch::removeHandler(unsigned id)
 {
        // pass through
        return mImpl->removeHandler(id);
 }
 
 
-void Dispatcher::dispatch(const std::string& message, const Notification* param)
+void Dispatch::dispatch(const std::string& event, const Message* message)
 {
        // pass through
-       mImpl->dispatch(message, param);
+       mImpl->dispatch(event, message);
 }
 
 
similarity index 54%
rename from src/Moof/Dispatcher.hh
rename to src/Moof/Dispatch.hh
index 7945752df0b21ff3b97aa2104ee1b6bc1c3e4c0b..bbf37f3c3cf31baad892a6a0c2eb26a520d243c1 100644 (file)
@@ -26,8 +26,8 @@
 
 *******************************************************************************/
 
-#ifndef _MOOF_DISPATCHER_HH_
-#define _MOOF_DISPATCHER_HH_
+#ifndef _MOOF_DISPATCH_HH_
+#define _MOOF_DISPATCH_HH_
 
 #include <string>
 
@@ -40,79 +40,90 @@ namespace Mf {
 
 
 /**
- * Interface for a notification class.
+ * Dispatcher of messages to interested parties.
  */
 
-class Notification
+class Dispatch
 {
+       class Impl;
+       boost::shared_ptr<Impl> mImpl;
+
+       void removeHandler(unsigned id);
+
 public:
-       virtual ~Notification() {};
-};
 
+       /**
+        * Interface for a notification class.
+        */
 
-/**
- * Dispatcher of notifications to interested parties.
- */
+       class Message
+       {
+       public:
+               virtual ~Message() {};
+       };
 
-class Dispatcher
-{
-       class Impl;
-       boost::shared_ptr<Impl> mImpl;
 
-public:
+       class Handler
+       {
+       public:
 
-       // TODO - the Handler would be even better as an object which automagically
-       // removes itself from the dispatcher on destruction, so users don't have to
-       // worry about forgetting
-       typedef void* Handler;
-       typedef boost::function<void(const Notification*)> Function;
+               Handler() :
+                       mDispatch(0),
+                       mId(0) {}
 
-       Dispatcher();
-       ~Dispatcher();
+               Handler(Impl* dispatch, unsigned id) :
+                       mDispatch(dispatch),
+                       mId(id) {}
 
-       // get global instance
-       static Dispatcher& getInstance();
+               Handler(const Handler& handler) :
+                       mDispatch(handler.mDispatch),
+                       mId(handler.mId)
+               {
+                       handler.mId = 0;
+               }
 
-       Handler addHandler(const std::string& message, const Function& callback);
-       Handler addHandler(const std::string& message, const Function& callback,
-                       Handler id);
+               ~Handler();
 
-       void removeHandler(Handler id);
+               Handler& operator = (const Handler& handler)
+               {
+                       mDispatch = handler.mDispatch;
+                       mId = handler.mId;
+                       handler.mId = 0;
+                       return *this;
+               }
 
-       void dispatch(const std::string& message, const Notification* param = 0);
-};
+               unsigned getId() const
+               {
+                       return mId;
+               }
+       
+       private:
 
+               Impl*                           mDispatch;
+               mutable unsigned        mId;
 
-namespace dispatcher {
+       };
 
-inline Dispatcher::Handler addHandler(const std::string& message,
-               const Dispatcher::Function& callback)
-{
-       return Dispatcher::getInstance().addHandler(message, callback);
-}
+       typedef boost::function<void(const Message*)> Function;
 
-inline Dispatcher::Handler addHandler(const std::string& message,
-               const Dispatcher::Function& callback, Dispatcher::Handler id)
-{
-       return Dispatcher::getInstance().addHandler(message, callback, id);
-}
 
-inline void removeHandler(Dispatcher::Handler id)
-{
-       Dispatcher::getInstance().removeHandler(id);
-}
+       Dispatch();
+       ~Dispatch();
 
-inline void dispatch(const std::string& message, const Notification* param = 0)
-{
-       Dispatcher::getInstance().dispatch(message, param);
-}
+       // create and/or get a global instance
+       static Dispatch& getInstance();
 
-} // namespace dispatcher
+       Handler addHandler(const std::string& event, const Function& callback);
+       Handler addHandler(const std::string& event, const Function& callback,
+                       Handler handler);
+
+       void dispatch(const std::string& event, const Message* message = 0);
+};
 
 
 } // namespace Mf
 
-#endif // _MOOF_DISPATCHER_HH_
+#endif // _MOOF_DISPATCH_HH_
 
 /** vim: set ts=4 sw=4 tw=80: *************************************************/
 
index 9ff5e1a8f1158188a4e58832a8a36a02c78ebcfb..f4bc712b27887d0b5397c579fc861d196ffc3bc6 100644 (file)
 #include "fastevents.h"
 #include <AL/alut.h>
 
-#include "Dispatcher.hh"
 #include "Engine.hh"
 #include "Event.hh"
 #include "Exception.hh"
 #include "Log.hh"
+#include "Math.hh"
 #include "Random.hh"
 #include "Settings.hh"
 #include "Timer.hh"
-#include "Video.hh"
 
 
 namespace Mf {
@@ -53,36 +52,36 @@ class Engine::Impl
 {
 public:
 
-       Impl(int argc, char* argv[], const std::string& name,
-                       const std::string& iconFile, const std::string& configFile,
-                       Engine& engine) :
+       Impl(Engine& engine) :
                mInterface(engine),
                mTimestep(0.01),
                mPrintFps(false)
        {
-#if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
+               // first, initialize the libraries
+
+#if defined(_WIN32) || defined(__WIN32__)
                if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
 #else
                if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) != 0)
 #endif
                {
                        const char* error = SDL_GetError();
-                       logError("sdl is complaining: %s", error);
                        throw Exception(ErrorCode::SDL_INIT, error);
                }
                if (FE_Init() != 0)
                {
                        const char* error = FE_GetError();
-                       logError("fast events error: %s", error);
                        throw Exception(ErrorCode::FASTEVENTS_INIT, error);
                }
-               alutInit(&argc, argv);
+               int argc = 1;
+               char name[] = "hello";
+               alutInit(&argc, (char**)&name);
+               
+               // now load the settings the engine needs
 
                Settings& settings = Settings::getInstance();
-               settings.loadFromFile(configFile);
-               settings.parseArgs(argc, argv);
 
-               long randomSeed;
+               unsigned randomSeed;
                if (settings.get("rngseed", randomSeed)) setSeed(randomSeed);
                else setSeed();
 
@@ -92,12 +91,10 @@ public:
 
                Scalar maxFps = 40.0;
                settings.get("maxfps", maxFps);
-               mDrawRate = 1.0 / maxFps;
+               mMaxFps = 1.0 / maxFps;
+               capFps();
 
                settings.get("printfps", mPrintFps);
-
-               mVideo = Video::alloc(name, iconFile);
-               mVideo->makeActive();
        }
 
        ~Impl()
@@ -139,14 +136,15 @@ public:
                        deltaTime = newTicks - ticksNow;
                        ticksNow = newTicks;
 
+                       // don't slow the animation until 4Hz, which is unplayable anyway
                        if (deltaTime >= 0.25) deltaTime = 0.25;
                        accumulator += deltaTime;
 
                        Timer::fireIfExpired(ticksNow);
+                       dispatchEvents();
 
                        while (accumulator >= mTimestep)
                        {
-                               dispatchEvents();
                                update(totalTime, mTimestep);
 
                                totalTime += mTimestep;
@@ -183,17 +181,17 @@ public:
                                draw(accumulator / mTimestep);
                                mVideo->swap();
 
-                               nextDraw += mDrawRate;
+                               nextDraw += mMaxFps;
                                if (ticksNow >= nextDraw)
                                {
                                        // we missed some scheduled draws, so reset the schedule
-                                       nextDraw = ticksNow + mDrawRate;
+                                       nextDraw = ticksNow + mMaxFps;
                                }
                        }
 
                        // be a good citizen and give back what you don't need
                        Timer::sleep(std::min(std::min(nextStep, nextDraw),
-                                               Timer::getNextFire()), true);
+                                               Timer::getNextFire()), Timer::ACTUAL);
                }
                while (!mStack.empty());
        }
@@ -211,7 +209,8 @@ public:
                                                        (SDL_GetModState() & KMOD_CTRL) )
                                        {
                                                // emergency escape
-                                               exit(0);
+                                               logWarning("escape forced");
+                                               exit(1);
                                        }
                                        break;
 
@@ -229,7 +228,7 @@ public:
        {
                for (mStackIt = mStack.begin(); mStackIt != mStack.end(); ++mStackIt)
                {
-                       (*mStackIt)->update(t, dt);
+                       (*mStackIt)->update(mInterface, t, dt);
                }
        }
 
@@ -239,7 +238,7 @@ public:
                std::list<LayerP>::reverse_iterator it;
                for (it = mStack.rbegin(); it != mStack.rend(); ++it)
                {
-                       (*it)->draw(alpha);
+                       (*it)->draw(mInterface, alpha);
                }
        }
 
@@ -247,7 +246,7 @@ public:
        {
                for (mStackIt = mStack.begin(); mStackIt != mStack.end(); ++mStackIt)
                {
-                       if ((*mStackIt)->handleEvent(event)) break;
+                       if ((*mStackIt)->handleEvent(mInterface, event)) break;
                }
        }
 
@@ -256,7 +255,7 @@ public:
        {
                ASSERT(layer && "cannot push null layer");
                mStack.push_front(layer);
-               logInfo(" push: %d", mStack.size());
+               logDebug("stack: %d [pushed %X]", mStack.size(), layer.get());
                layer->pushed(mInterface);
        }
 
@@ -265,26 +264,26 @@ public:
                bool fixIt = false;
                if (mStack.begin() == mStackIt) fixIt = true;
 
-               LayerP popped = mStack.front();
+               LayerP layer = mStack.front();
                mStack.pop_front();
-               logInfo("  pop: %d", mStack.size());
-               popped->popped(mInterface);
+               logDebug("stack: %d [popped %X]", mStack.size(), layer.get());
+               layer->popped(mInterface);
 
                if (fixIt) mStackIt = --mStack.begin();
 
-               return popped;
+               return layer;
        }
 
        LayerP pop(Layer* layer)
        {
                bool fixIt = false;
 
-               std::list<LayerP> popped;
+               std::list<LayerP> layers;
 
                std::list<LayerP>::iterator it;
                for (it = mStack.begin(); it != mStack.end(); ++it)
                {
-                       popped.push_back(*it);
+                       layers.push_back(*it);
 
                        if (it == mStackIt) fixIt = true;
 
@@ -293,14 +292,15 @@ public:
                                ++it;
                                mStack.erase(mStack.begin(), it);
 
-                               for (it = popped.begin(); it != popped.end(); ++it)
+                               for (it = layers.begin(); it != layers.end(); ++it)
                                {
                                        (*it)->popped(mInterface);
+                                       logDebug("stack: %d [popped %X]", mStack.size(), (*it).get());
                                }
 
                                if (fixIt) mStackIt = --mStack.begin();
 
-                               return popped.back();
+                               return layers.back();
                        }
                }
 
@@ -311,77 +311,83 @@ public:
        {
                mStack.clear();
                mStackIt = mStack.begin();
-               logInfo("clear: %d", mStack.size());
+               logDebug("stack: 0 [cleared]");
        }
 
 
-       Engine&                         mInterface;
+       void capFps()
+       {
+               if (mMaxFps < mTimestep)
+               {
+                       logWarning("capping maximum fps to timestep (%f)", mTimestep);
+                       mMaxFps = mTimestep;
+               }
+       }
+
 
-       VideoP                          mVideo;
+       Engine&                                         mInterface;
+       VideoP                                          mVideo;
+       Dispatch                                        mDispatch;
 
        std::list<LayerP>                       mStack;
        std::list<LayerP>::iterator     mStackIt;
 
-       Scalar                          mTimestep;
-       Scalar                          mDrawRate;
+       Scalar                                          mTimestep;
+       Scalar                                          mMaxFps;
 
-       long                            mFps;
-       bool                            mPrintFps;
+       int                                                     mFps;
+       bool                                            mPrintFps;
 };
 
 
-static Engine* instance = 0;
-
-Engine::Engine(int argc, char* argv[], const std::string& name,
-               const std::string& iconFile, const std::string& configFile) :
-       mImpl(new Engine::Impl(argc, argv, name, iconFile, configFile, *this))
-{
-       instance = this;
-}
-
+Engine::Engine() :
+       // pass through
+       mImpl(new Engine::Impl(*this)) {}
 
 Engine& Engine::getInstance()
 {
-       ASSERT(instance && "dereferencing null pointer");
-       return *instance;
-       // TODO this has not been completely thought out
-       //static Engine engine;
-       //return engine;
+       static Engine engine;
+       return engine;
 }
 
 
-void Engine::run()
+void Engine::setVideo(VideoP video)
 {
-       return mImpl->run();
+       // pass through
+       mImpl->mVideo = video;
 }
 
-void Engine::setTimestep(Scalar ts)
+VideoP Engine::getVideo() const
 {
-       mImpl->mTimestep = ts;
+       return mImpl->mVideo;
 }
 
-Scalar Engine::getTimestep() const
+
+void Engine::setTimestep(int ts)
 {
-       return mImpl->mTimestep;
+       mImpl->mTimestep = 1.0 / Scalar(ts);
+       mImpl->capFps();
 }
 
-void Engine::setMaxFrameRate(long maxFps)
+int Engine::getTimestep() const
 {
-       mImpl->mDrawRate = 1.0 / Scalar(maxFps);
+       return int(1.0 / mImpl->mTimestep);
 }
 
-long Engine::getMaxFrameRate() const
+
+void Engine::setMaxFps(int maxFps)
 {
-       return long(1.0 / mImpl->mDrawRate);
+       mImpl->mMaxFps = 1.0 / Scalar(maxFps);
+       mImpl->capFps();
 }
 
-
-Video& Engine::getVideo() const
+int Engine::getMaxFps() const
 {
-       return *mImpl->mVideo;
+       return int(1.0 / mImpl->mMaxFps);
 }
 
-long Engine::getFrameRate() const
+
+int Engine::getFps() const
 {
        return mImpl->mFps;
 }
@@ -411,6 +417,37 @@ void Engine::clear()
        mImpl->clear();
 }
 
+int Engine::getSize() const
+{
+       return mImpl->mStack.size();
+}
+
+
+void Engine::run()
+{
+       // pass through
+       return mImpl->run();
+}
+
+
+Dispatch::Handler Engine::addHandler(const std::string& event,
+               const Dispatch::Function& callback)
+{
+       return mImpl->mDispatch.addHandler(event, callback);
+}
+
+Dispatch::Handler Engine::addHandler(const std::string& event,
+               const Dispatch::Function& callback, Dispatch::Handler handler)
+{
+       return mImpl->mDispatch.addHandler(event, callback, handler);
+}
+
+void Engine::dispatch(const std::string& event,
+               const Dispatch::Message* message)
+{
+       mImpl->mDispatch.dispatch(event, message);
+}
+
 
 } // namespace Mf
 
index 84b1f588f57e41c55d5a185bec8e0d40abcca198..c5e99864f103e49dedffee2721609f48e136fe84 100644 (file)
 
 #include <boost/shared_ptr.hpp>
 
+#include <Moof/Dispatch.hh>
+#include <Moof/Video.hh>
 #include <Moof/Layer.hh>
-#include <Moof/Math.hh>
 
 
 namespace Mf {
 
 
-// forward declarations
-class Video;
+/**
+ * The engine is essentially a stack of layers.  While running, it updates each
+ * layer from the bottom up every timestep.  It also draws each layer from the
+ * bottom up, adhering to the maximum frame-rate.  Events are send to each layer
+ * from the top down until a layer signals the event was handled.  The engine is
+ * also responsible for firing timers on time.  The engine will continue running
+ * as long as there are layers on the stack.
+ */
 
 class Engine
 {
 public:
 
-       Engine(int argc, char* argv[], const std::string& name, 
-                       const std::string& iconFile, const std::string& configFile);
        ~Engine() {}
 
        // get global instance
        static Engine& getInstance();
 
-       void run();
+       // setting the video is required before you can run the engine and should
+       // probably be done before adding any layers
+       void setVideo(VideoP video);
+       VideoP getVideo() const;
+
+       void setTimestep(int ts);
+       int getTimestep() const;
+
+       void setMaxFps(int maxFps);     // draw rate is always capped at the timestep
+       int getMaxFps() const;
+
+       int getFps() const;
 
-       void setTimestep(Scalar ts);
-       Scalar getTimestep() const;
-       void setMaxFrameRate(long maxFps);
-       long getMaxFrameRate() const;
+       void push(LayerP layer);        // push a layer onto the top
+       LayerP pop();                           // pop the top layer
+       LayerP pop(Layer* layer);       // pops a specific layer and all layers above it
+       void clear();                           // remove all layers (the engine will stop)
 
-       Video& getVideo() const;
-       long getFrameRate() const;
+       int getSize() const;            // get the size of the stack
 
-       void push(LayerP layer);
-       LayerP pop();
-       // pops a specific layer and all layers above it
-       LayerP pop(Layer* layer);
-       void clear();
+       // set this machine in motion
+       void run();
+
+       Dispatch::Handler addHandler(const std::string& event,
+                       const Dispatch::Function& callback);
+       Dispatch::Handler addHandler(const std::string& event,
+                       const Dispatch::Function& callback, Dispatch::Handler handler);
+
+       void dispatch(const std::string& event,
+                       const Dispatch::Message* message = 0);
 
 private:
 
+       Engine();               // use getInstance() to access the engine
+
        class Impl;
        boost::shared_ptr<Impl> mImpl;
 };
index a63f761ad8b857e8c63e81ca11e68df799f73828..f8921bd5943cf161ee60036bd3d1f2ec3b564576 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <cstring>
 #include <exception>
+#include <string>
 
 #include <Moof/Math.hh>
 
@@ -42,10 +43,10 @@ class Exception : public std::exception
 {
 public:
 
-       explicit Exception(unsigned code, const char* what = "")
+       explicit Exception(unsigned code, const std::string& what = "")
        {
                mWhat[sizeof(mWhat)-1] = '\0';
-               strncpy(mWhat, what, sizeof(mWhat)-1);
+               strncpy(mWhat, what.c_str(), sizeof(mWhat)-1);
                mCode = code;
        }
        virtual ~Exception() throw() {}
@@ -81,8 +82,8 @@ enum Code
        SCRIPT_ERROR,                           // description
        SDL_INIT,                                       // description
        SDL_VIDEOMODE,                          // -
-       UNKNOWN_AUDIO_FORMAT,           // -
-       UNKNOWN_IMAGE_FORMAT,           // -
+       UNKNOWN_AUDIO_FORMAT,           // name of resource
+       UNKNOWN_IMAGE_FORMAT,           // name of resource
 };
 } // namespace ErrorCode
 
index 55e233ed02b39067b267507018273419889481b8..9ba428899c6461060dacfbd97c0b0b2806c1ca30 100644 (file)
@@ -31,7 +31,6 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include <Moof/Drawable.hh>
 #include <Moof/Event.hh>
 #include <Moof/Math.hh>
 
@@ -43,7 +42,7 @@ namespace Mf {
 class Engine;
 
 
-class Layer : public Drawable
+class Layer
 {
 public:
 
@@ -52,9 +51,12 @@ public:
        virtual void pushed(Engine& engine) {}
        virtual void popped(Engine& engine) {}
 
-       virtual void update(Scalar t, Scalar dt) {}
-       virtual void draw(Scalar alpha) const {}
-       virtual bool handleEvent(const Event& event) { return false; }
+       virtual void update(Engine& engine, Scalar t, Scalar dt) {}
+       virtual void draw(Engine& engine, Scalar alpha) const {}
+       virtual bool handleEvent(Engine& engine, const Event& event)
+       {
+               return false;
+       }
 };
 
 typedef boost::shared_ptr<Layer> LayerP;
index 96827e1a8be84a9219bbb47e1569f195af82f6eb..a7cdae4a49e57604a6cdea4f678dba2d888aa2a7 100644 (file)
@@ -161,7 +161,7 @@ int logScript(Script& script)
 }
 
 
-void importLogScript(Script& script)
+void importLogPrintFunction(Script& script)
 {
        script.importFunction("print", (int (*)(Script&))logScript);
 }
index 221827f4eb86fcbcb03e4b6b628124b48e6dc8d4..d3aa555aac4c5fa4b81076de90a595612ca28883 100644 (file)
@@ -119,7 +119,7 @@ void logDebug(const char* fmt, ...);
 void logScript(const char* fmt, ...);
 class Script;
 int logScript(Script& script);
-void importLogScript(Script& script);
+void importLogPrintFunction(Script& script);
 
 
 } // namespace Mf
index 11d9d7997916926b4fff50c25e44211af078f36d..68a6d285f99f414297d98e49a61093932fbb573c 100644 (file)
 
 #include <string>
 
+#if HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
 #if defined(_WIN32) || defined(__WIN32__)
 #include <windows.h>
 #elif defined(__APPLE__) && defined(__MACH__)
 #include <QMessageBox>
 #endif
 
+#include <Moof/Log.hh>
 #include <Moof/Resource.hh>
 
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 
 namespace Mf {
 
@@ -66,13 +67,31 @@ struct ModalDialog
                CRITICAL        = 3
        };
 
+
        std::string title;
        Type            type;
        std::string text1;
        std::string text2;
 
+
        void run() const
        {
+               switch (type)
+               {
+                       case WARNING:
+                               logWarning("%s", text1.c_str());
+                               logWarning("%s", text2.c_str());
+                               break;
+                       case CRITICAL:
+                               logError("%s", text1.c_str());
+                               logError("%s", text2.c_str());
+                               break;
+                       default:
+                               logInfo("%s", text1.c_str());
+                               logInfo("%s", text2.c_str());
+                               break;
+               }
+
 #if USE_GTK
 
                int argc = 0;
index df00619d69e59b4dafcf644d5782e2ab53ac1eac..2f285cecc2bcdd740529783fcc8d4f7ea0fa581b 100644 (file)
@@ -471,15 +471,14 @@ public:
 
 
        Script() :
-               mState(luaL_newstate())
+               mState(0)
        {
-               lua_pushlightuserdata(mState, this);
-               lua_setfield(mState, LUA_REGISTRYINDEX, "_script_obj");
+               reset();
        }
 
        ~Script()
        {
-               if (mIsMainThread) lua_close(mState);
+               destroy();
        }
 
 
@@ -488,12 +487,77 @@ public:
                return ScriptP(new Script);
        }
 
+       void reset()
+       {
+               if (mState) destroy();
+               mState = luaL_newstate();
+               lua_pushlightuserdata(mState, this);
+               lua_setfield(mState, LUA_REGISTRYINDEX, "_script_obj");
+       }
+
 
        void importStandardLibraries()
        {
                luaL_openlibs(mState);
        }
 
+       void importBaseLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_base);
+               push(LUA_COLIBNAME);
+               call(1, 0);
+       }
+
+       void importPackageLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_package);
+               push(LUA_LOADLIBNAME);
+               call(1, 0);
+       }
+
+       void importStringLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_string);
+               push(LUA_STRLIBNAME);
+               call(1, 0);
+       }
+
+       void importTableLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_table);
+               push(LUA_TABLIBNAME);
+               call(1, 0);
+       }
+
+       void importMathLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_math);
+               push(LUA_MATHLIBNAME);
+               call(1, 0);
+       }
+
+       void importIoLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_io);
+               push(LUA_IOLIBNAME);
+               call(1, 0);
+       }
+
+       void importOsLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_os);
+               push(LUA_OSLIBNAME);
+               call(1, 0);
+       }
+
+       void importDebugLibrary()
+       {
+               lua_pushcfunction(mState, luaopen_debug);
+               push(LUA_DBLIBNAME);
+               call(1, 0);
+       }
+
+
        void importFunction(const std::string& name, const Function& function)
        {
                push(function);
@@ -815,6 +879,11 @@ private:
                return (*function)(*script);
        }
 
+       void destroy()
+       {
+               if (mIsMainThread) lua_close(mState);
+       }
+
        lua_State*                      mState;
        bool                            mIsMainThread;
        std::list<Function>     mFunctions;
index 5a4f99127f099ef847f1822f8b875614f0d3674b..81b5c50fd62d7b6d34ec740b15b7eb23f09a6800 100644 (file)
@@ -85,6 +85,12 @@ void Settings::loadFromFiles(const std::vector<std::string>& filePaths)
 }
 
 
+void Settings::clear()
+{
+       mScript.reset();
+}
+
+
 } // namepsace Mf
 
 /** vim: set ts=4 sw=4 tw=80: *************************************************/
index 42e7d3a7a5f26e159237a3b37682efb2a4a9f015..9b3e0cb27146bbc3a1a99c91a8c76f56dad3d8d0 100644 (file)
@@ -54,7 +54,8 @@ public:
                mGlobals(mScript.getGlobalTable()),
                mTop(mScript[-1])
        {
-               importLogScript(mScript);
+               mScript.importBaseLibrary();
+               importLogPrintFunction(mScript);
        }
 
        // get global instance
@@ -65,6 +66,8 @@ public:
        void loadFromFile(const std::string& filePath);
        void loadFromFiles(const std::vector<std::string>& filePaths);
 
+       void clear();           // remove all settings
+
        template <typename T>
        bool get(const std::string& key, T& value);
 
index 4c60e328085f60d7d282c2e70144079c49c5dbc2..4275ea4485900c67e147aeb04165b5f6c2496b30 100644 (file)
@@ -35,6 +35,7 @@
 #include <vorbis/codec.h>
 #include <vorbis/vorbisfile.h>
 
+#include "Engine.hh"
 #include "Exception.hh"
 #include "Library.hh"
 #include "Log.hh"
@@ -98,15 +99,12 @@ public:
                        {
                                logWarning("error while loading sound %s",
                                                getName().c_str());
-                               throw Exception(ErrorCode::UNKNOWN_AUDIO_FORMAT);
+                               throw Exception(ErrorCode::UNKNOWN_AUDIO_FORMAT, getName());
                        }
 
                        vorbis_info* vorbisInfo = ov_info(&mOggStream, -1);
                        mFormat = getAudioFormat(vorbisInfo);
                        mFreq = vorbisInfo->rate;
-
-                       logDebug("   channels: %d", vorbisInfo->channels);
-                       logDebug("  frequency: %d", vorbisInfo->rate);
                }
 
 
@@ -137,7 +135,6 @@ public:
                        if (size == 0)
                        {
                                logWarning("decoded no bytes from %s", getName().c_str());
-                               //throw Exception("file_not_found");
                                return;
                        }
 
@@ -209,6 +206,9 @@ public:
 
        void init()
        {
+               // make sure the engine is initialized
+               Engine::getInstance();
+
                ALfloat zero[] = {0.0f, 0.0f, 0.0f};
                
                alGenSources(1, &mSource);
index 341b5598f13f9b8c7d42f93643f26ca3f4727568..a701424d5dd7588537dce06511cfb9e1f0fa6c1e 100644 (file)
@@ -33,7 +33,8 @@
 #include <SDL/SDL.h>
 #include <SDL/SDL_image.h>
 
-#include "Dispatcher.hh"
+#include "Dispatch.hh"
+#include "Engine.hh"
 #include "Exception.hh"
 #include "Library.hh"
 #include "Log.hh"
@@ -64,9 +65,9 @@ class Texture::Impl : public Library<Impl>
        {
                if (mObject)
                {
-                       if (mObject == globalObject_)
+                       if (mObject == gObject)
                        {
-                               globalObject_ = 0;
+                               gObject = 0;
                        }
 
                        glDeleteTextures(1, &mObject);
@@ -80,9 +81,9 @@ class Texture::Impl : public Library<Impl>
         * to cache it if the client has plenty of RAM.
         */
 
-       void contextRecreated(const Notification* note)
+       void contextRecreated()
        {
-               mObject = globalObject_ = 0;
+               mObject = gObject = 0;
                uploadToGL();
        }
 
@@ -143,11 +144,16 @@ public:
                mWrapT(GL_CLAMP),
                mObject(0)
        {
-               loadFromFile();
+               // make sure the engine is initialized
+               Engine& engine = Engine::getInstance();
+               VideoP video = engine.getVideo();
+               ASSERT(video && "cannot load textures without a current video context");
 
                // we want to know when the GL context is recreated
-               Dispatcher::getInstance().addHandler("video.context_recreated",
-                               boost::bind(&Impl::contextRecreated, this, _1), this);
+               mDispatchHandler = engine.addHandler("video.newcontext",
+                               boost::bind(&Impl::contextRecreated, this));
+
+               loadFromFile();
        }
 
        ~Impl()
@@ -158,8 +164,6 @@ public:
                }
 
                unloadFromGL();
-
-               Dispatcher::getInstance().removeHandler(this);
        }
 
 
@@ -246,7 +250,7 @@ public:
                if (!surface)
                {
                        logWarning("texture not found: %s", getName().c_str());
-                       throw Exception(ErrorCode::FILE_NOT_FOUND, getName().c_str());
+                       throw Exception(ErrorCode::FILE_NOT_FOUND, getName());
                }
 
                SDL_Surface* temp = prepareImageForGL(surface);
@@ -254,7 +258,7 @@ public:
 
                if (!temp)
                {
-                       throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT);
+                       throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT, getName());
                }
 
                if (temp->format->BytesPerPixel == 3)
@@ -268,7 +272,7 @@ public:
                else
                {
                        SDL_FreeSurface(temp);
-                       throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT);
+                       throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT, getName());
                }
 
                mWidth = temp->w;
@@ -366,29 +370,31 @@ public:
                {
                        uploadToGL();
                }
-               if (mObject != globalObject_)
+               if (mObject != gObject)
                {
                        glBindTexture(GL_TEXTURE_2D, mObject);
-                       globalObject_ = mObject;
+                       gObject = mObject;
                }
        }
 
 
-       SDL_Surface*    mContext;
-       unsigned                mWidth;                 ///< Horizontal dimension of the image.
-       unsigned                mHeight;                ///< Vertical dimension.
+       SDL_Surface*            mContext;
+       unsigned                        mWidth;                 ///< Horizontal dimension of the image.
+       unsigned                        mHeight;                ///< Vertical dimension.
+
+       GLuint                          mMode;                  ///< GL_RGB or GL_RGBA.
+       GLuint                          mMinFilter;             ///< Minifcation filter.
+       GLuint                          mMagFilter;             ///< Magnification filter.
+       GLuint                          mWrapS;                 ///< Wrapping behavior horizontally.
+       GLuint                          mWrapT;                 ///< Wrapping behavior vertically.
 
-       GLuint                  mMode;                  ///< Depth of the image, GL_RGB or GL_RGBA.
-       GLuint                  mMinFilter;             ///< Minifcation filter.
-       GLuint                  mMagFilter;             ///< Magnification filter.
-       GLuint                  mWrapS;                 ///< Wrapping behavior horizontally.
-       GLuint                  mWrapT;                 ///< Wrapping behavior vertically.
+       GLuint                          mObject;                ///< GL texture handle.
+       static GLuint           gObject;                ///< Global GL texture handle.
 
-       GLuint                  mObject;                ///< GL texture handle.
-       static GLuint   globalObject_;  ///< Global GL texture handle.
+       Dispatch::Handler       mDispatchHandler;
 };
 
-GLuint Texture::Impl::globalObject_ = 0;
+GLuint Texture::Impl::gObject = 0;
 
 
 Texture::Texture(const std::string& name) :
@@ -421,7 +427,7 @@ GLuint Texture::getObject() const
 void Texture::resetBind()
 {
        glBindTexture(GL_TEXTURE_2D, 0);
-       Impl::globalObject_ = 0;
+       Impl::gObject = 0;
 }
 
 
index 7f51510ce60189320383f25272e87da9914dc353..b428f0aade848d1813b9d125b2acd9c238dbd5c1 100644 (file)
@@ -64,7 +64,7 @@ void Timer::init(const Function& function, Scalar seconds, Mode mode)
        {
                mFunction = function;
 
-               if (mode == ABSOLUTEE)
+               if (mode == ACTUAL)
                {
                        mAbsolute = seconds;
                }
@@ -200,12 +200,12 @@ Scalar Timer::getTicks()
        return Scalar(ts.tv_sec - reference) + Scalar(ts.tv_nsec) / 1000000000.0;
 }
 
-void Timer::sleep(Scalar seconds, bool absolute)
+void Timer::sleep(Scalar seconds, Mode mode)
 {
        struct timespec ts;
        int ret;
 
-       if (absolute) seconds -= getTicks();
+       if (mode == ACTUAL) seconds -= getTicks();
        ts.tv_sec = time_t(seconds);
        ts.tv_nsec = long((seconds - Scalar(ts.tv_sec)) * 1000000000.0);
 
@@ -230,9 +230,9 @@ Scalar Timer::getTicks()
        return Scalar(ms / 1000) + Scalar(ms % 1000) / 1000.0;
 }
 
-void Timer::sleep(Scalar seconds, bool absolute)
+void Timer::sleep(Scalar seconds, Mode mode)
 {
-       if (absolute) seconds -= getTicks();
+       if (mode == ACTUAL) seconds -= getTicks();
        SDL_Delay(Uint32(cml::clamp(int(seconds * 1000.0), 0, 1000)));
 }
 
index a0bc676b7f130f042d550ac0c1fb25d44faa3386..b657a5f9632aee158d8b8d5ef4e72d9178979369 100644 (file)
@@ -53,7 +53,7 @@ public:
        {
                INVALID         = -1,
                NORMAL          =  0,
-               ABSOLUTEE       =  1,   // the ABSOLUTE keyword isn't available on win32...
+               ACTUAL          =  1,
                REPEAT          =  2
        };
 
@@ -102,7 +102,7 @@ public:
         * sleep for the requested amount of time (and maybe longer).
         */
 
-       static void sleep(Scalar seconds, bool absolute = false);
+       static void sleep(Scalar seconds, Mode mode = NORMAL);
 
 
        static Scalar getNextFire()
index f1e1bcb4c6efb0a4523e7e3d2320fe7e70f09d2c..ab09c02a582ddd7f5320a18dbaa284c3d8b559bb 100644 (file)
@@ -51,15 +51,12 @@ class Transition : public Layer
 
        T               mInterp;
 
-       Engine* mEngine;
-
 public:
 
        Transition(LayerP t, LayerP f, const T& interp) :
                mTo(t),
                mFrom(f),
-               mInterp(interp),
-               mEngine(0) {}
+               mInterp(interp) {}
 
        typedef boost::shared_ptr<Transition> Ptr;
 
@@ -69,27 +66,22 @@ public:
        }
 
 
-       void pushed(Engine& engine)
-       {
-               mEngine = &engine;
-       }
-
        void popped(Engine& engine)
        {
                if (mTo) engine.push(mTo);
        }
 
-       void update(Scalar t, Scalar dt)
+       void update(Engine& engine, Scalar t, Scalar dt)
        {
                mInterp.update(t, dt);
 
-               if (mFrom) mFrom->update(t, dt);
-               if (mTo) mTo->update(t, dt);
+               if (mFrom) mFrom->update(engine, t, dt);
+               if (mTo) mTo->update(engine, t, dt);
 
                if (mInterp.isDone())
                {
                        // to should /replace/ this
-                       mEngine->pop(this);
+                       engine.pop(this);
                }
        }
 
@@ -126,10 +118,10 @@ public:
                glPopMatrix();
        }
 
-       void draw(Scalar alpha) const
+       void draw(Engine& engine, Scalar alpha) const
        {
                Scalar a = mInterp.getState(alpha);
-               logInfo("draw state: %f", a);
+               logDebug("transition state: %f", a);
 
                //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
@@ -138,7 +130,7 @@ public:
                        glPushMatrix();
                        glLoadIdentity();
                        glRotate(180.0 * a, 0.0, 1.0, 0.0);
-                       mFrom->draw(alpha);
+                       mFrom->draw(engine, alpha);
                        glPopMatrix();
                }
                        //drawFade(a);
@@ -148,21 +140,21 @@ public:
                        glPushMatrix();
                        glLoadIdentity();
                        glRotate(180.0 * (1.0 - a), 0.0, 1.0, 0.0);
-                       mTo->draw(alpha);
+                       mTo->draw(engine, alpha);
                        glPopMatrix();
                }
                        //drawFade(1.0 - a);
        }
 
-       bool handleEvent(const Event& event)
+       bool handleEvent(Engine& engine, const Event& event)
        {
                if (mTo)
                {
-                       return mTo->handleEvent(event);
+                       return mTo->handleEvent(engine, event);
                }
                else if (mFrom)
                {
-                       return mFrom->handleEvent(event);
+                       return mFrom->handleEvent(engine, event);
                }
                return false;
        }
index 9fdd47893652109704f589acc8aa0a5c6b6ad337..eeec47e7eb7d4dcc00b4a6b17fd732f8e61fc93a 100644 (file)
@@ -28,7 +28,8 @@
 
 #include <SDL/SDL_image.h>
 
-#include "Dispatcher.hh"
+#include "Dispatch.hh"
+#include "Engine.hh"
 #include "Exception.hh"
 #include "Log.hh"
 #include "Settings.hh"
@@ -64,6 +65,9 @@ Video::Video(const std::string& caption, const std::string& icon)
 
 void Video::init(const Attributes& attribs)
 {
+       // make sure the engine is initialized before setting up the video
+       Engine::getInstance();
+
        mContext = 0;
        mFlags = 0;
        mAttribs = attribs;
@@ -132,7 +136,8 @@ void Video::setVideoMode(const long mode[3])
                        // on win32, creating a new context via SDL_SetVideoMode will wipe
                        // out the GL state, so we gotta notify everyone to reload their
                        // state after the change
-                       Mf::dispatcher::dispatch("video.context_recreated");
+                       Engine::getInstance().dispatch("video.newcontext");
+
                        logInfo("video context recreated");
 #endif
                }
@@ -182,6 +187,11 @@ std::string Video::getCaption() const
        return mAttribs.caption;
 }
 
+const std::string& Video::getIcon() const
+{
+       return mAttribs.icon;
+}
+
 
 void Video::setFull(bool full)
 {
@@ -275,12 +285,6 @@ void Video::setCursorGrab(bool cursorGrab)
 }
 
 
-void Video::makeActive()
-{
-       // NOP until the day SDL supports more than only one window.
-       // Still waiting...
-}
-
 void Video::swap()
 {
        SDL_GL_SwapBuffers();
index 193274f5fb5b7a82cee5611eb62d1e3bacc4c338..91eecb71d092537be39e12015e9fedfa0d13be97 100644 (file)
@@ -94,6 +94,8 @@ public:
        void setCaption(const std::string& caption);
        std::string getCaption() const;
 
+       const std::string& getIcon() const;
+
        void setFull(bool full);
        void toggleFull();
        bool isFull() const;
@@ -110,7 +112,6 @@ public:
        void toggleCursorGrab();
        bool isCursorGrab() const;
 
-       void makeActive();
        void swap();
 
        int getWidth() const;
index b15d07f29a3900cb3e41e266491cf97482fdbb97..02184bc99dec6049aa72a7c991d19653d5eb9b3e 100644 (file)
@@ -66,7 +66,7 @@ struct Tilemap::Impl : public Mf::Library<Impl>
                std::string filePath = Tilemap::getPath(getName());
 
                script.importStandardLibraries();
-               importLogScript(script);
+               importLogPrintFunction(script);
                bindScriptConstants(script);
 
                if (script.doFile(filePath) != Mf::Script::SUCCESS)
index 11c624d07e94e59375141a98681df5a658a7370f..f5e4ef02a423300c928e5cc77c52dd153dfc96af 100644 (file)
 
 void TitleLayer::pushed(Mf::Engine& engine)
 {
-       mEngine = &engine;
-
        Mf::Scalar coeff[] = {0.0, 1.0};
        mFadeIn.init(coeff, 0.1);
 
        mGameLayer = GameLayer::alloc();
 }
 
-void TitleLayer::update(Mf::Scalar t, Mf::Scalar dt)
+void TitleLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
 {
        if (!mFadeIn.isDone()) mFadeIn.update(t, dt);
 }
 
-void TitleLayer::draw(Mf::Scalar alpha) const
+void TitleLayer::draw(Mf::Engine& engine, Mf::Scalar alpha) const
 {
        glClearColor(0.0, 0.0, mFadeIn.getState(alpha), 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
 }
 
-bool TitleLayer::handleEvent(const Mf::Event& event)
+bool TitleLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event)
 {
        switch (event.type)
        {
                case SDL_KEYUP:
-                       Mf::LayerP titleLayer = mEngine->pop(this);
-                       //mEngine->pushLayer(GameLayer::alloc());
+                       //if (event.key.keysym.sym == SDLK_ESCAPE)
+                       //{
+                               //break;
+                       //}
+
+                       Mf::LayerP titleLayer = engine.pop(this);
+                       //engine.pushLayer(GameLayer::alloc());
 
-                       Mf::Scalar coeff[] = {0.0, 1.0};
-                       Mf::Lerp interp(coeff, 0.2);
+                       Mf::Scalar coeff[] = {0.0, 0.75, 0.99, 1.0};
+                       Mf::PolynomialInterpolator<3> interp(coeff, 0.1);
 
                        //Mf::LayerP mGameLayer = GameLayer::alloc();
-                       Mf::Transition<Mf::Lerp>::Ptr transition =
-                               Mf::Transition<Mf::Lerp>::alloc(mGameLayer, titleLayer, interp);
-                       mEngine->push(transition);
+                       Mf::Transition<Mf::PolynomialInterpolator<3> >::Ptr transition =
+                               Mf::Transition<Mf::PolynomialInterpolator<3> >::alloc(mGameLayer, titleLayer, interp);
+                       engine.push(transition);
                        return true;
        }
 
index 887398816f5f6fc5e5a9f5946b6809066fa1a93e..a781c936508959e881013a24b8dfad4cf2e9261a 100644 (file)
@@ -50,15 +50,13 @@ public:
 
        void pushed(Mf::Engine& engine);
 
-       void update(Mf::Scalar t, Mf::Scalar dt);
-       void draw(Mf::Scalar alpha) const;
-       bool handleEvent(const Mf::Event& event);
+       void update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt);
+       void draw(Mf::Engine& engine, Mf::Scalar alpha) const;
+       bool handleEvent(Mf::Engine& engine, const Mf::Event& event);
 
 private:
 
        Mf::Lerp                mFadeIn;
-       Mf::Engine*             mEngine;
-
        Mf::LayerP              mGameLayer;
 };
 
This page took 0.101075 seconds and 4 git commands to generate.