further implementing runloop support
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sat, 21 Aug 2010 04:28:47 +0000 (22:28 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sat, 21 Aug 2010 04:28:47 +0000 (22:28 -0600)
23 files changed:
data/scenes/Classic.lua
data/yoinkrc
src/Hud.cc
src/Hud.hh
src/Main.cc
src/Main.hh
src/TitleLayer.cc [deleted file]
src/TitleLayer.hh [deleted file]
src/moof/application.cc
src/moof/application.hh
src/moof/image.cc
src/moof/runloop.cc
src/moof/runloop.hh
src/moof/sound.cc
src/moof/thread.hh
src/moof/timer.cc
src/moof/timer.hh
src/moof/video.cc
src/moof/video.hh
src/moof/view.cc [deleted file]
src/moof/view.hh [deleted file]
src/yoink.cc [moved from src/GameLayer.cc with 69% similarity]
src/yoink.hh [moved from src/GameLayer.hh with 75% similarity]

index c2ca18387f1ecf01ae9d73b921faf6d522896da9..b1364b02a64cadca5823868697c2dac5cc111605 100644 (file)
@@ -21,7 +21,7 @@ LogInfo("-----",
 -- detail - level of detail of the scene (HIGH, MEDIUM, or LOW)
 
 
-SetBounds({-5, 0, -6}, {45, 15, 4})
+--SetBounds({-5, 0, -6}, {45, 15, 4})
 
 
 --geometry = yoink.mesh("classic.ac")
index af051b38bd1f83ec366469ee71bdb898e0d107dc..1d58bef8df8a83cab188e51435777995635428cc 100644 (file)
@@ -16,23 +16,22 @@ detail                      = 3
 -- value, but the processor will be taxed more.  Errors could be introduced
 -- in the game with extremely low values.
 
-timestep               = 80
+timestep               = 100
 
 -- Set the target number of frames that should be drawn per second.  The
 -- smoothness of the animation increases as you increase this value.  You
--- probably want to set this somewhere in the 25-85 range, depending on how
--- much work you want your computer to do.  For example, if you're on
+-- probably want to set this somewhere in the 25-200 range, depending on
+-- how much work you want your computer to do.  For example, if you're on
 -- battery power, you might prefer 25 which is still reasonably smooth and
--- will decrease battery drain significantly.  You can also set this to a
--- very high number to effectively draw as many frames as possible, but
--- your actual framerate might be limited by the refresh rate of your
--- display--use the swapcontrol setting to enable or disable this behavior.
+-- will decrease battery drain significantly.  You can also set this to an
+-- arbitrarily high number to effectively draw as many frames as possible,
+-- but your actual framerate might be limited by the refresh rate of your
+-- displayuse the swapcontrol setting to enable or disable this behavior.
 -- You can determine your actual framerate with the showfps option.
 
-framerate              = 50
+framerate              = timestep
 
--- Set this to print the current actual framerate to the console each
--- second.
+-- Set this to show the current frames per second in the window caption.
 
 showfps                        = false
 
@@ -42,19 +41,16 @@ showfps                     = false
 fullscreen             = false
 
 -- If the game is running in a window, set this to also make the window
--- resizable.  This has no effective if the fullscreen option is true.
+-- resizable.  This has no effective if the fullscreen option is set.
 
 resizable              = true
 
--- Set the screen resolution or size of the window.  The value is an array
--- with three number elements representing the width, height, and
--- (optionally) bits per pixel that make up the video mode.
+-- Set the display resolution or size of the viewing window.  If left at
+-- the default value (a function), the video mode will only be set if we're
+-- not in fullscreen.  That way, a native resolution will be used.
 
-if fullscreen then
-       -- In fullscreen mode, a native resolution will be picked.  You could
-       -- still set videomode if you want to use a different resolution.
-else
-       videomode       = {800, 600}
+videomode              = function()
+       if not fullscreen then return {800, 600} end
 end
 
 -- Set this to use double-buffering to improve animation quality.  You
index 58bc7210422e54b0b0a98fb03b1835277db8e90e..cc25dd582171a80551192c1148f65bba4a378a12 100644 (file)
@@ -171,7 +171,7 @@ bool Hud::handle_event(const moof::event& event)
                        if (event.key.keysym.sym == SDLK_h)
                        {
                                // don't want the hud anymore
-                               parent().remove_child(this);
+                               //parent().remove_child(this);
 
                                moof::log_warning("okay bye bye hud");
                                return true;
index 1bb557633c6d73581d3d91b2336d7e5c2120cc8e..30c01363435a73becfe351528b1d07f0514fa0bb 100644 (file)
@@ -21,7 +21,6 @@
 #include <moof/math.hh>
 //#include <moof/rectangle.hh>
 #include <moof/sprite.hh>
-#include <moof/view.hh>
 
 #include "GameState.hh"
 
@@ -58,7 +57,7 @@ private:
 class Hud;
 typedef boost::shared_ptr<Hud> HudP;
 
-class Hud : public moof::view
+class Hud
 {
 public:
 
index e16803739ae6e809d5bf049040debbb3b75e93fd..070912e7ce1a0c7acb8fb7c3e1f75adf6cb151eb 100644 (file)
@@ -26,6 +26,7 @@ inline int isatty(int dummy) { return 0; }
 #include <stlplus/portability/file_system.hpp>
 #include <stlplus/portability/subprocesses.hpp>
 
+#include <moof/image.hh>
 #include <moof/log.hh>
 #include <moof/modal_dialog.hh>
 #include <moof/opengl.hh>
@@ -34,9 +35,7 @@ inline int isatty(int dummy) { return 0; }
 #include <moof/string.hh>
 #include <moof/video.hh>
 
-#include "GameLayer.hh"
 #include "Main.hh"
-#include "TitleLayer.hh"
 #include "version.h"
 
 
@@ -58,6 +57,7 @@ Main::Main(moof::settings& settings) :
 
 void Main::update(moof::scalar t, moof::scalar dt)
 {
+       yoink.update(t, dt);
 }
 
 void Main::draw(moof::scalar alpha) const
@@ -69,10 +69,14 @@ void Main::draw(moof::scalar alpha) const
 
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
+
+       yoink.draw(alpha);
 }
 
 void Main::handle_event(const moof::event& event)
 {
+       if (yoink.handle_event(event)) return;
+
        switch (event.type)
        {
                case SDL_KEYUP:
@@ -150,7 +154,7 @@ std::string Main::config_paths()
 
 void Main::setup_opengl()
 {
-       //glEnable(GL_TEXTURE_2D);
+       glEnable(GL_TEXTURE_2D);
        glEnable(GL_DEPTH_TEST);
        //glEnable(GL_CULL_FACE);
 
@@ -260,6 +264,11 @@ void Main::print_info(int argc, char* argv[])
 #else
        print_option("debug", false);
 #endif
+#if ENABLE_DOUBLE_PRECISION
+       print_option("double", true);
+#else
+       print_option("double", false);
+#endif
 #if WITH_GTK
        print_option("gtk", true);
 #else
@@ -359,6 +368,7 @@ int main(int argc, char* argv[])
 
                class moof::video::attributes attributes(settings);
                moof::video video(PACKAGE_STRING, attributes);
+               video.show_fps(true);
 
                Main app(settings);
                return app.run();
index 47163d11c5bd14232e2c3340e00a7d7c77bc4118..088bd3c1b67e393303165f1a774e6370e84d57be 100644 (file)
@@ -27,6 +27,8 @@
 #include <moof/math.hh>
 #include <moof/timer.hh>
 
+#include "yoink.hh"
+
 
 class Main : public moof::application
 {
@@ -55,6 +57,8 @@ private:
 
        moof::dispatcher::handle        video_reloaded_;
        moof::timer                                     hotload_timer_;
+
+       ::yoink yoink;
 };
 
 
diff --git a/src/TitleLayer.cc b/src/TitleLayer.cc
deleted file mode 100644 (file)
index 92484d0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-
-/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
-**]  All rights reserved.
-*
-* vi:ts=4 sw=4 tw=75
-*
-* Distributable under the terms and conditions of the 2-clause BSD license;
-* see the file COPYING for a complete text of the license.
-*
-**************************************************************************/
-
-#include <moof/opengl.hh>
-
-#include "GameLayer.hh"
-#include "TitleLayer.hh"
-
-
-void TitleLayer::did_add_to_view()
-{
-       mFadeIn.init(0.0, 1.0, 0.15);
-
-       //mGameLayer = GameLayer::alloc();
-}
-
-void TitleLayer::update(moof::scalar t, moof::scalar dt)
-{
-       mFadeIn.update(t, dt);
-       moof::view::update(t, dt);
-}
-
-void TitleLayer::draw(moof::scalar alpha) const
-{
-       glClearColor(mFadeIn.state(alpha), 0.0, mFadeIn.state(alpha), 1.0);
-       glClear(GL_COLOR_BUFFER_BIT);
-       moof::view::draw(alpha);
-}
-
-bool TitleLayer::handle_event(const moof::event& event)
-{
-       if (moof::view::handle_event(event)) return true;
-
-       switch (event.type)
-       {
-               case SDL_KEYUP:
-                       if (event.key.keysym.sym == SDLK_ESCAPE)
-                       {
-                               parent().stop();
-                               return true;
-                       }
-
-                       mGameLayer = GameLayer::alloc();
-                       parent().add_child(mGameLayer);
-
-                       parent().remove_child(this);
-
-                       //moof::lerp_scalar interp(0.1);
-                       //interp.init(0.0, 1.0);
-
-                       //moof::Transition<moof::lerp_scalar>::Ptr transition =
-                               //moof::Transition<moof::lerp_scalar>::alloc(mGameLayer, titleLayer,
-                                                                                               //interp);
-
-                       return true;
-       }
-
-       return false;
-}
-
diff --git a/src/TitleLayer.hh b/src/TitleLayer.hh
deleted file mode 100644 (file)
index be8aba1..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-
-/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
-**]  All rights reserved.
-*
-* vi:ts=4 sw=4 tw=75
-*
-* Distributable under the terms and conditions of the 2-clause BSD license;
-* see the file COPYING for a complete text of the license.
-*
-**************************************************************************/
-
-#ifndef _TITLELAYER_HH_
-#define _TITLELAYER_HH_
-
-#include <boost/shared_ptr.hpp>
-
-#include <moof/interpolator.hh>
-#include <moof/math.hh>
-#include <moof/view.hh>
-
-
-class TitleLayer;
-typedef boost::shared_ptr<TitleLayer> TitleLayerP;
-
-class TitleLayer : public moof::view
-{
-public:
-
-       static TitleLayerP alloc()
-       {
-               return TitleLayerP(new TitleLayer);
-       }
-
-       void did_add_to_view();
-
-       void update(moof::scalar t, moof::scalar dt);
-       void draw(moof::scalar alpha) const;
-       bool handle_event(const moof::event& event);
-
-private:
-
-       moof::lerp_scalar               mFadeIn;
-       moof::view_ptr          mGameLayer;
-};
-
-
-#endif // _TITLELAYER_HH_
-
index fd9ea451fba72ec20e50212be89719646408acfa..b462a0eb2efcd947317a61ffcf619f4553f83579 100644 (file)
@@ -26,8 +26,9 @@ namespace moof {
 
 
 application::application(settings& settings) :
-       next_update_(timer::ticks()),
-       total_time_(SCALAR(0.0))
+       last_update_(timer::ticks()),
+       total_time_(SCALAR(0.0)),
+       accum_(SCALAR(0.0))
 {
        unsigned random_seed;
        if (settings.get("rngseed", random_seed)) srand(random_seed);
@@ -42,10 +43,15 @@ application::application(settings& settings) :
        settings.get("framerate", framerate);
        framerate = SCALAR(1.0) / framerate;
 
-       update_timer_.init(boost::bind(&application::dispatch_update, this, _1, _2),
-                                          timestep_, timer::repeat, this);
+       //timer::default_source().scale(SCALAR(1.2));
+
+       //update_timer_.init(boost::bind(&application::dispatch_update, this, _1, _2),
+                                          //timestep_, timer::repeat, this);
+       next_update_ = update_timer_.expiration();
+
        draw_timer_.init(boost::bind(&application::dispatch_draw, this, _1, _2),
-                                        framerate, timer::repeat, this);
+                                        framerate, timer::repeat);
+       add_timer(draw_timer_);
 }
 
 
@@ -78,26 +84,60 @@ void application::dispatch_update(timer& timer, scalar t)
        }
 
 
-       const int MAX_FRAMESKIP = 15;
+       //const int MAX_FRAMESKIP = 15;
+
+       log_debug("updating", timer.expiration(), "/", t);
 
-       int i = 0;
-       while (next_update_ < t && ++i < MAX_FRAMESKIP)
+       //int i = 0;
+       //while (next_update_ < t && ++i < MAX_FRAMESKIP)
+       //{
+               //total_time_ += timestep_;
+               //update(total_time_, timestep_);
+
+               //next_update_ += timestep_;
+               //log_debug("updated", next_update_, "time:", timer::ticks());
+       //}
+       
+       scalar deltaTime = t - last_update_;
+       accum_ += deltaTime;
+
+       while (timestep_ <= accum_)
        {
-               total_time_ += timestep_;
+               log_debug("UPDATING");
                update(total_time_, timestep_);
-
-               next_update_ += timestep_;
+               total_time_ += timestep_;
+               accum_ -= timestep_;
        }
+
+       last_update_ = t;
 }
 
 void application::dispatch_draw(timer& timer, scalar t)
 {
-       scalar alpha = (t + timestep_ - next_update_) * inverse_timestep_;
-       if (alpha < SCALAR(0.0)) log_error("UH OH!!!!!  It's NEGATIVE", alpha);
-       if (alpha > SCALAR(1.0)) log_error("UH OH!!!!!  It's POSITIVE", alpha);
+       log_debug("next update", update_timer_.expiration());
+       log_debug("draw", timer.expiration(), "/", t);
+
+       dispatch_update(timer, t);
+
+       //if (t < next_update_ - timestep_) return;
+       //scalar alpha = (t + timestep_ - next_update_) * inverse_timestep_;
+       //scalar alpha = (t + timestep_ - update_timer_.expiration()) * inverse_timestep_;
+       //scalar alpha = (next_update_ - t) * inverse_timestep_;
+       scalar alpha = accum_ * inverse_timestep_;
+       //if (alpha < SCALAR(0.0) || SCALAR(1.0) < alpha) return;
+       
+       alpha = cml::clamp(alpha, SCALAR(-1.0), SCALAR(2.0));
+       if (alpha < SCALAR(0.0)) log_warning("alpha:", alpha);
+       else if (alpha > SCALAR(1.0)) log_warning("alpha:", alpha);
+       else log_debug("alpha:", alpha);
 
        draw(alpha);
-       video::current()->swap();
+
+       scalar begin = timer::ticks();
+       video::current()->swap(t);
+
+       scalar duration = timer::ticks() - begin;
+       log_debug("flip duration:", duration);
 }
 
 
index 671011f140ba8b5258cef440b7d4c47a3623146f..494e98ded4ef8910cccaa4b6115cfd2e17b701dd 100644 (file)
@@ -48,7 +48,9 @@ private:
        void dispatch_draw(timer& timer, scalar t);
 
        scalar  next_update_;
+       scalar  last_update_;
        scalar  total_time_;
+       scalar  accum_;
 
        timer   update_timer_;
        timer   draw_timer_;
index 7453b4849be2e9153fa3d1c2d428824e0f96ec19..94d468727107a5e45e8b9fcabb8a73e6344fa2ca 100644 (file)
@@ -340,6 +340,10 @@ void image::set_texture_info(const std::string& info)
                globals.get(mag_filter_, "mag_filter");
                globals.get(wrap_s_, "wrap_s");
                globals.get(wrap_t_, "wrap_t");
+               //min_filter_ = GL_LINEAR;
+               //mag_filter_ = GL_LINEAR;
+               //wrap_s_ = GL_CLAMP;
+               //wrap_t_ = GL_CLAMP;
        }
 }
 
index db598145f17fbb7f14e40d6b02713109cd67cd94..f6f47dd6f87d1f7029970e3802be6eddd6bd1aed 100644 (file)
@@ -9,7 +9,12 @@
 *
 **************************************************************************/
 
+#include "config.h"
+
+#include <algorithm>
+
 #include "hash.hh"
+#include "log.hh"
 #include "runloop.hh"
 #include "timer.hh"
 
@@ -25,18 +30,20 @@ enum registry_action
 
 static uint32_t call_registry(runloop*& runloop, registry_action action)
 {
+#if ENABLE_THREADS
        typedef stlplus::hash<uint32_t,moof::runloop*,hash_function> table_t;
        static table_t table;
 
        uint32_t thread_id = thread::current_identifier();
 
-       static MOOF_DECLARE_MUTEX(table_mutex);
+       MOOF_DECLARE_STATIC_MUTEX(table_mutex);
        MOOF_MUTEX_LOCK(table_mutex);
 
        switch (action)
        {
                case set:
                {
+                       log_info("registering runloop", runloop, "for thread", thread_id);
                        if (runloop) table[thread_id] = runloop;
                        else         table.erase(thread_id);
                        break;
@@ -46,13 +53,21 @@ static uint32_t call_registry(runloop*& runloop, registry_action action)
                {
                        table_t::iterator it = table.find(thread_id);
                        if (it != table.end()) runloop = (*it).second;
+                       else log_warning("runloop is not in registry for thread", thread_id);
                        break;
                }
        }
 
        return thread_id;
+#else
+       return thread::current_identifier();
+#endif
 }
 
+bool comp(timer* a, timer* b)
+{
+       return a->expiration() < b->expiration();
+}
 
 int runloop::run()
 {
@@ -64,6 +79,7 @@ int runloop::run()
        stop_ = false;
        while (!stop_)
        {
+               log_debug("------------------------------------");
                scalar next_event = SCALAR(0.0);
                {
                        MOOF_MUTEX_LOCK(timers_mutex_);
@@ -72,13 +88,23 @@ int runloop::run()
                                 timers_it_ != timers_.end();
                                 ++timers_it_)
                        {
-                               scalar absolute = (*timers_it_)->fire_if_expired();
-                               if (next_event == SCALAR(0.0) ||
-                                       (absolute != SCALAR(0.0) && absolute < next_event))
-                               {
-                                       next_event = absolute;
-                               }
+                               (*timers_it_)->fire_if_expired();
                        }
+
+                       std::sort(timers_.begin(), timers_.end(), comp);
+                       next_event = timers_[0]->expiration();
+
+                       //for (timers_it_ = timers_.begin();
+                                //timers_it_ != timers_.end();
+                                //++timers_it_)
+                       //{
+                               //scalar absolute = (*timers_it_)->fire_if_expired();
+                               //if (next_event == SCALAR(0.0) ||
+                                       //(absolute != SCALAR(0.0) && absolute < next_event))
+                               //{
+                                       //next_event = absolute;
+                               //}
+                       //}
                }
                timer::sleep(next_event, timer::absolute);
        }
@@ -109,36 +135,36 @@ runloop* runloop::current()
 }
 
 
-void runloop::add_timer(timer* timer)
+void runloop::add_timer(timer& timer)
 {
 #if ENABLE_THREADS
        if (thread_id_ != thread::current_identifier())
        {
                MOOF_MUTEX_LOCK(timers_mutex_);
-               timers_.insert(timer);
+               timers_.push_back(&timer);
                timers_it_ = timers_.end();
        }
        else
 #endif
        {
-               timers_.insert(timer);
+               timers_.push_back(&timer);
                timers_it_ = timers_.end();
        }
 }
 
-void runloop::remove_timer(timer* timer)
+void runloop::remove_timer(timer& timer)
 {
 #if ENABLE_THREADS
        if (thread_id_ != thread::current_identifier())
        {
                MOOF_MUTEX_LOCK(timers_mutex_);
-               timers_.erase(timer);
+               timers_.erase(std::find(timers_.begin(), timers_.end(), &timer));
                timers_it_ = timers_.end();
        }
        else
 #endif
        {
-               timers_.erase(timer);
+               timers_.erase(std::find(timers_.begin(), timers_.end(), &timer));
                timers_it_ = timers_.end();
        }
 }
index 0aad06dddaa9a25c82fc2f9d1e17c2c4af3d5667..f70abdef3891bf3b687633f71380099c677790cf 100644 (file)
@@ -17,7 +17,7 @@
  * Thread timer management class.
  */
 
-#include <set>
+#include <vector>
 
 #include <boost/noncopyable.hpp>
 
@@ -35,7 +35,7 @@ class timer;
 /**
  * A runloop is a loop with scheduled timers.
  */
-class runloop
+class runloop : public boost::noncopyable
 {
 public:
 
@@ -43,8 +43,12 @@ public:
         * Construct a runloop.
         */
        runloop() :
-               stop_(false),
-               thread_id_(0) {}
+               stop_(false)
+       {
+#if ENABLE_THREADS
+               thread_id_ = 0;
+#endif
+       }
 
        /**
         * Deconstruct the runloop.
@@ -72,18 +76,16 @@ public:
        static runloop* current();
 
 
-private:
+       void add_timer(timer& timer);
+       void remove_timer(timer& timer);
 
-       friend class timer;
-
-       void add_timer(timer* timer);
-       void remove_timer(timer* timer);
 
+private:
 
        bool            stop_;
        int                     code_;
 
-       typedef std::set<timer*> timer_table;
+       typedef std::vector<timer*> timer_table;
        timer_table     timers_;
        timer_table::iterator timers_it_;
 
index f3060540eba005087560423b4dcdb0d167a524c6..34c30ce78929b172d2165bad3eff78fec4c2081b 100644 (file)
@@ -393,7 +393,7 @@ public:
                        else alDeleteBuffers(1, &buf);
                }
 
-               if (stream_timer_.is_valid() && 0 < target_diff)
+               if (stream_timer_.mode() != timer::invalid && 0 < target_diff)
                {
                        for (int i = 0; i < target_diff; ++i)
                        {
index 72c6dc004147461706c1ae8d405b3c25fc924d62..1e710d8c0e66ef81e913a0a072d0646fa29099a0 100644 (file)
@@ -569,10 +569,12 @@ private:
 
 
 #if ENABLE_THREADS
-#define MOOF_DECLARE_MUTEX(M)  moof::mutex M
-#define MOOF_MUTEX_LOCK(M)             moof::mutex::lock lock_##M(M)
+#define MOOF_DECLARE_MUTEX(M)                  moof::mutex M
+#define MOOF_DECLARE_STATIC_MUTEX(M)   static moof::mutex M
+#define MOOF_MUTEX_LOCK(M)                             moof::mutex::lock lock_##M(M)
 #else
 #define MOOF_DECLARE_MUTEX(M)
+#define MOOF_DECLARE_STATIC_MUTEX(M)
 #define MOOF_MUTEX_LOCK(M)
 #endif
 
index 9b105b4c991fcb73582ff0ad86ca73091ef5c85d..c45e1b8909eb6413e79b9b14a372fca4b0da744c 100644 (file)
@@ -18,6 +18,7 @@
 #include <SDL/SDL.h>
 
 #include "debug.hh"
+#include "runloop.hh"
 #include "timer.hh"
 
 
@@ -26,12 +27,12 @@ namespace moof {
 
 void timer::init(const function& function,
                                 scalar seconds,
-                                mode mode,
-                                runloop* runloop)
+                                enum mode mode,
+                                timer_source& source)
 {
-       invalidate();
-       ASSERT(runloop && "can't schedule timer without a runloop");
+       source_ = &source;
 
+       invalidate();
        if ((mode_ = mode) != invalid)
        {
                function_ = function;
@@ -42,24 +43,35 @@ void timer::init(const function& function,
                }
                else
                {
-                       absolute_ = seconds ticks();
+                       absolute_ = seconds + source_->ticks();
                        interval_ = seconds;
                }
-
-               runloop->add_timer(this);
-               runloop_ = runloop;
        }
 }
 
+timer::~timer()
+{
+       detach_from_runloop();
+}
 
 void timer::invalidate()
 {
-       if (mode_ != invalid)
-       {
-               mode_ = invalid;
-               absolute_ = SCALAR(0.0);
+       mode_ = invalid;
+       absolute_ = SCALAR(0.0);
+}
+
 
-               runloop_->remove_timer(this);
+void timer::added_to_runloop(runloop& runloop)
+{
+       detach_from_runloop();
+       runloop_ = &runloop;
+}
+
+void timer::detach_from_runloop()
+{
+       if (runloop_)
+       {
+               runloop_->remove_timer(*this);
                runloop_ = 0;
        }
 }
@@ -69,7 +81,7 @@ void timer::fire(scalar t)
 {
        if (function_) function_(*this, t);
 
-       if (is_repeating())
+       if (mode_ == repeat)
        {
                if (is_equal(absolute_, t, 1.0)) absolute_ += interval_;
                else absolute_ = interval_ + t;
@@ -78,42 +90,61 @@ void timer::fire(scalar t)
 }
 
 
-#if ENABLE_CLOCK_GETTIME
+scalar timer::ticks()
+{
+       return default_source().ticks();
+}
+
+
 
-// Since the monotonic clock will provide us with the time since the
-// computer started, the number of seconds since that time could easily
-// become so large that it cannot be accurately stored in a float (even
-// with as little two days uptime), therefore we need to start from a more
-// recent reference (when the program starts).  Of course this isn't much
-// of an issue if scalar is a double-precision number.
+#if ENABLE_CLOCK_GETTIME
 
-static time_t set_reference()
+class real_time : public timer_source
 {
-       struct timespec ts;
+public:
 
-       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+       real_time() :
+               scale_(SCALAR(1.0))
        {
-               return 0;
+               reset();
        }
 
-       return ts.tv_sec;
-}
 
-static const time_t reference_ = set_reference();
+       scalar ticks() const
+       {
+               struct timespec ts;
+               int result = clock_gettime(CLOCK_MONOTONIC, &ts);
+               ASSERT(result == 0 && "monotonic clock not available");
+
+               return reference_ +
+                          (scalar(ts.tv_sec - start_.tv_sec) +
+                               scalar(ts.tv_nsec - start_.tv_nsec) *
+                               SCALAR(0.000000001)) * scale_;
+       }
 
+       void reset()
+       {
+               reference_ = SCALAR(0.0);
+               clock_gettime(CLOCK_MONOTONIC, &start_);
+       }
 
-scalar timer::ticks()
-{
-       struct timespec ts;
+       void scale(scalar factor)
+       {
+               reference_ = ticks();
+               clock_gettime(CLOCK_MONOTONIC, &start_);
+               scale_ = factor;
+       }
 
-       int result = clock_gettime(CLOCK_MONOTONIC, &ts);
-       ASSERT(result == 0 && "cannot access clock");
 
-       return scalar(ts.tv_sec - reference_) +
-                  scalar(ts.tv_nsec) * SCALAR(0.000000001);
-}
+private:
 
-void timer::sleep(scalar seconds, mode mode)
+       scalar                  reference_;
+       struct timespec start_;
+       scalar                  scale_;
+};
+
+
+void timer::sleep(scalar seconds, enum mode mode)
 {
        if (mode == absolute) seconds -= ticks();
        if (seconds < SCALAR(0.0)) return;
@@ -130,14 +161,43 @@ void timer::sleep(scalar seconds, mode mode)
 #else // ! ENABLE_CLOCK_GETTIME
 
 
-// If we don't have posix timers, we'll have to use a different timing
-// method.  SDL only promises centisecond accuracy, but that's better than
-// a kick in the pants.  It could end up being just as good anyway.
-
-scalar timer::ticks()
+class real_time : public timer_source
 {
-       return scalar(SDL_GetTicks()) * SCALAR(0.001);
-}
+public:
+
+       real_time() :
+               scale_(SCALAR(1.0))
+       {
+               reset();
+       }
+
+
+       scalar ticks() const
+       {
+               return reference_ + scalar(SDL_GetTicks() - start_) * scale_;
+       }
+
+       void reset()
+       {
+               reference_ = SCALAR(0.0);
+               start_ = SDL_GetTicks();
+       }
+
+       void scale(scalar factor)
+       {
+               reference_ = ticks();
+               start_ = SDL_GetTicks();
+               scale_ = factor * SCALAR(0.001);
+       }
+
+
+private:
+
+       scalar  reference_;
+       Uint32  start_;
+       scalar  scale_;
+};
+
 
 void timer::sleep(scalar seconds, mode mode)
 {
@@ -149,5 +209,12 @@ void timer::sleep(scalar seconds, mode mode)
 #endif // ENABLE_CLOCK_GETTIME
 
 
+timer_source& timer::default_source()
+{
+       static real_time t;
+       return t;
+}
+
+
 } // namespace moof
 
index 90c53ceb034452208b6262aeb039938ea650369f..9f3e9846096d7e09600a053ea929c66e7af91d19 100644 (file)
 
 #include <moof/hash.hh>
 #include <moof/math.hh>
-#include <moof/runloop.hh>
 
 
 namespace moof {
 
 
+/**
+ * A timer source is an object that keeps track of increasing time in units
+ * of seconds.  A timer source does not necessarily have to increment at
+ * the same rate or in the same way as the real time.  The time source must
+ * begin at zero and always remain the same or increase each time the time
+ * is queried.
+ */
+class timer_source
+{
+public:
+
+       /**
+        * Deconstruct a timer source.
+        */
+       virtual ~timer_source() {}
+
+       /**
+        * Get the number seconds since the timer source was created or reset.
+        */
+       virtual scalar ticks() const = 0;
+
+       /**
+        * Reset the timer such that the current time will become zero.
+        */
+       virtual void reset() = 0;
+
+       /**
+        * Scale the time.  After calling this, the timer source should either
+        * increment faster or slower, depending on the scale factor.
+        */
+       virtual void scale(scalar factor) = 0;
+};
+
+
+class runloop;
+
+
 /**
  * A class to represent a timer for scheduled events.  The timer events
  * will be executed on or sometime after their schedculed time.  The
@@ -44,10 +80,10 @@ public:
         */
        enum mode
        {
-               invalid         = -1,   /// Timer is not scheduled.
-               relative        =  0,   /// Timer is scheduled by a relative time.
-               absolute        =  1,   /// Timer is scheduled by an absolute time.
-               repeat          =  2    /// Timer is scheduled by a periodic time.
+               invalid         = 0,    /// Timer is not scheduled.
+               relative        = 1,    /// Timer is scheduled by a relative time.
+               absolute        = 2,    /// Timer is scheduled by an absolute time.
+               repeat          = 3             /// Timer is scheduled by a periodic time.
        };
 
        /**
@@ -64,7 +100,8 @@ public:
         */
        timer() :
                mode_(invalid),
-               absolute_(SCALAR(0.0)) {}
+               absolute_(SCALAR(0.0)),
+               runloop_(0) {}
 
        /**
         * Construct a scheduled timer.
@@ -84,19 +121,18 @@ public:
        timer(const function& function,
                  scalar seconds,
                  mode mode = relative,
-                 runloop* runloop = runloop::current())
+                 timer_source& source = default_source()) :
+               runloop_(0)
        {
-               init(function, seconds, mode, runloop);
+               init(function, seconds, mode, source);
        }
 
+
        /**
         * Deconstruct a timer.  This will automagically invalidate the timer,
         * so it will not expire or fire an event.
         */
-       ~timer()
-       {
-               invalidate();
-       }
+       ~timer();
 
 
        /**
@@ -118,20 +154,10 @@ public:
         */
        void init(const function& function,
                          scalar seconds,
-                         mode mode = relative,
-                         runloop* runloop = runloop::current());
+                         enum mode mode = relative,
+                         timer_source& source = default_source());
 
        
-       /**
-        * Get whether or not the timer is valid.  If a timer is valid, it is
-        * still scheduled to expired.  You can get the time remaining from
-        * seconds_remaining().
-        */
-       bool is_valid() const
-       {
-               return mode_ != invalid;
-       }
-
        /**
         * Manually invalidated the timer, removing any schedule such that the
         * timer will not expired and no event will be fired.
@@ -139,6 +165,12 @@ public:
        void invalidate();
 
 
+       enum mode mode() const
+       {
+               return mode_;
+       }
+
+
        /**
         * Manually fire the timer event.  Usually, the timer event will be
         * fired when the timer expires, but this can be used to fire it
@@ -147,7 +179,11 @@ public:
         * handler), the event will be fired and the timer will remain invalid.
         * \param t The absolute time passed to the timer event function.
         */
-       void fire(scalar t = ticks());
+       void fire(scalar t);
+       void fire()
+       {
+               fire(source_->ticks());
+       }
 
 
        /**
@@ -157,13 +193,26 @@ public:
         * \return The absolute time of the next expiration (if repeating), or
         * 0.0 otherwise.
         */
-       scalar fire_if_expired(scalar t = ticks())
+       scalar fire_if_expired(scalar t)
        {
-               if (is_expired()) fire();
+               if (is_expired(t)) fire(t);
                return absolute_;
        }
+       scalar fire_if_expired()
+       {
+               return fire_if_expired(source_->ticks());
+       }
 
 
+       /**
+        * Get the absolute time of the next expiration of this timer.
+        * \return Seconds.
+        */
+       scalar expiration() const
+       {
+               return absolute_;
+       }
+
        /**
         * Get the number of seconds remaining before the timer is scheduled to
         * expired.  If the timer is invalid, the retured value will be
@@ -172,18 +221,13 @@ public:
         * amount of time left; defaults to the current time.
         * \return Seconds.
         */
-       scalar seconds_remaining(scalar t = ticks()) const
+       scalar remaining(scalar t) const
        {
-               return next_expiration() - t;
+               return expiration() - t;
        }
-
-       /**
-        * Get the absolute time of the next expiration of this timer.
-        * \return Seconds.
-        */
-       scalar next_expiration() const
+       scalar remaining() const
        {
-               return absolute_;
+               return remaining(source_->ticks());
        }
 
 
@@ -197,24 +241,21 @@ public:
         * timer is expired; defaults to the current time.
         * \return True if the timer is expired, false otherwise.
         */
-       bool is_expired(scalar t = ticks()) const
+       bool is_expired(scalar t) const
        {
-               return seconds_remaining(t) < SCALAR(0.0);
+               return remaining(t) < SCALAR(0.0);
        }
-
-       /**
-        * Get whether or not the timer is on a repeating schedule.
-        * \return True if the timer is repeating, false otherwise.
-        */
-       bool is_repeating() const
+       bool is_expired() const
        {
-               return mode_ == repeat;
+               return is_expired(source_->ticks());
        }
 
 
+       static timer_source& default_source();
+
        /**
-        * Get the number of seconds since a fixed, arbitrary point in the
-        * past.
+        * Get the number of real seconds since the default timer was first
+        * created or last reset.
         * \return Seconds.
         */
        static scalar ticks();
@@ -222,25 +263,78 @@ public:
 
        /**
         * Put the thread to sleep for a certain period of time.  If absolute
-        * is true, then it will sleep until seconds after the fixed time in
-        * the past.  If absolute is false, it will sleep for seconds starting
-        * now.  Unlike system sleep functions, this one automatically resumes
-        * sleep if sleep was interrupted by a signal.  Therefore, calling this
-        * function is guaranteed to sleep for the requested amount of time
-        * (and maybe longer).
+        * is true, then it will sleep until the default timer reaches the
+        * specified number of seconds.  If the mode is relative, the thread
+        * will sleep for that many seconds.  Unlike system sleep functions,
+        * this one automatically resumes sleep if sleep was interrupted by a
+        * signal.  Therefore, calling this function is guaranteed to sleep for
+        * at least the requested amount of time.
         * \param seconds Number of seconds.
         * \param mode The timer mode.
         */
-       static void sleep(scalar seconds, mode mode = relative);
+       static void sleep(scalar seconds, enum mode mode = relative);
+
+
+private:
+
+       void added_to_runloop(runloop& runloop);
+       void detach_from_runloop();
+
+
+       function                function_;
+       enum mode               mode_;
+       scalar                  absolute_;
+       scalar                  interval_;
+       timer_source*   source_;
+       runloop*                runloop_;
+};
+
+
+
+
+class game_time : public timer_source
+{
+public:
+
+       game_time(scalar timestep) :
+               timestep_(timestep),
+               scale_(timestep)
+       {
+               reset();
+       }
+
+       scalar ticks() const
+       {
+               return reference_ + scalar(ticks_) * scale_;
+       }
+
+       void reset()
+       {
+               reference_ = SCALAR(0.0);
+               ticks_ = 0;
+       }
+
+       void scale(scalar factor)
+       {
+               reference_ = ticks();
+               ticks_ = 1;
+               scale_ = timestep_ * factor;
+       }
+
+
+       unsigned step(unsigned step = 1)
+       {
+               ticks_ += step;
+               return ticks_;
+       }
 
 
 private:
 
-       function        function_;
-       mode            mode_;
-       scalar          absolute_;
-       scalar          interval_;
-       runloop*        runloop_;
+       scalar          reference_;
+       unsigned        ticks_;
+       scalar          timestep_;
+       scalar          scale_;
 };
 
 
index aa49b03c249b9d2927d0b43e52adfd5a8a8b357b..263ea882bcfce6751078674436ffe155aa555aab 100644 (file)
@@ -9,6 +9,7 @@
 *
 **************************************************************************/
 
+#include <sstream>
 #include <stdexcept>
 
 #include "dispatcher.hh"
@@ -54,6 +55,8 @@ void video::init()
        mode(attributes_.mode);
 
        if (!current_) make_current();
+
+       show_fps(false);
 }
 
 void video::recreate_context()
@@ -158,14 +161,16 @@ bool video::iconify()
 
 void video::caption(const std::string& caption)
 {
+       caption_ = caption;
        SDL_WM_SetCaption(caption.c_str(), 0);
 }
 
-std::string video::caption() const
+const std::string& video::caption() const
 {
-       char* caption;
-       SDL_WM_GetCaption(&caption, 0);
-       return std::string(caption);
+       return caption_;
+       //char* caption;
+       //SDL_WM_GetCaption(&caption, 0);
+       //return std::string(caption);
 }
 
 
@@ -261,8 +266,27 @@ void video::toggle_cursor_captured()
 }
 
 
-void video::swap()
+void video::swap(scalar t)
 {
+       if (show_fps_)
+       {
+               scalar dt = t - last_swap_;
+               last_swap_ = t;
+
+               fps_accumulator_ += dt;
+               if (SCALAR(1.0) <= fps_accumulator_)
+               {
+                       std::ostringstream stream;
+                       stream << caption_ << " - " << fps_counter_ << " fps";
+                       SDL_WM_SetCaption(stream.str().c_str(), 0);
+
+                       fps_accumulator_ -= SCALAR(1.0);
+                       fps_counter_ = 0;
+               }
+
+               ++fps_counter_;
+       }
+
        SDL_GL_SwapBuffers();
 }
 
index ea331a02bfe2a0f76a068e9dc53df16a27e87bfd..8b42cfddd8b9e181f0f94706f97c6aaf41c67c78 100644 (file)
@@ -23,6 +23,8 @@
 #include <SDL/SDL.h>
 
 #include <moof/backend.hh>
+#include <moof/math.hh>
+#include <moof/timer.hh>
 
 
 namespace moof {
@@ -87,7 +89,7 @@ public:
        bool iconify();
 
        void caption(const std::string& caption);
-       std::string caption() const;
+       const std::string& caption() const;
 
        void fullscreen(bool full);
        bool fullscreen() const;
@@ -109,7 +111,7 @@ public:
        /**
         * Swap the video buffers if double-buffered.
         */
-       void swap();
+       void swap(scalar t = timer::ticks());
 
 
        /**
@@ -140,6 +142,20 @@ public:
        int height() const;
 
 
+       void show_fps(bool show)
+       {
+               show_fps_ = show;
+               fps_accumulator_ = SCALAR(0.0);
+               fps_counter_ = 0;
+               last_swap_ = SCALAR(0.0);
+       }
+
+       bool show_fps() const
+       {
+               return show_fps_;
+       }
+
+
 private:
 
        void init();
@@ -152,6 +168,11 @@ private:
        SDL_Surface*            context_;
        int                                     flags_;
        class attributes        attributes_;
+       bool                            show_fps_;
+       std::string                     caption_;
+       scalar                          fps_accumulator_;
+       int                                     fps_counter_;
+       scalar                          last_swap_;
 
        static video*           current_;
 };
diff --git a/src/moof/view.cc b/src/moof/view.cc
deleted file mode 100644 (file)
index 62fcd93..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-
-/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
-**]  All rights reserved.
-*
-* vi:ts=4 sw=4 tw=75
-*
-* Distributable under the terms and conditions of the 2-clause BSD license;
-* see the file COPYING for a complete text of the license.
-*
-**************************************************************************/
-
-#include <algorithm>
-#include <cstdlib>                     // exit, srand
-#include <ctime>                       // time
-#include <string>
-
-#include <SDL/SDL.h>
-#include "fastevents.h"
-
-#include "event.hh"
-#include "log.hh"
-#include "math.hh"
-#include "modal_dialog.hh"
-#include "settings.hh"
-#include "timer.hh"
-#include "video.hh"
-#include "view.hh"
-
-
-namespace moof {
-
-
-// Timestep Example Source Code
-// Copyright (c) Glenn Fiedler 2004
-// http://www.gaffer.org/articles
-
-struct State
-{
-       float x;
-       float v;
-};
-
-struct Derivative
-{
-       float dx;
-       float dv;
-};
-
-State interpolate(const State &previous, const State &current, float alpha)
-{
-       State state;
-       state.x = current.x*alpha + previous.x*(1-alpha);
-       state.v = current.v*alpha + previous.v*(1-alpha);
-       return state;
-}
-
-float acceleration(const State &state, float t)
-{
-       const float k = 10;
-       const float b = 1;
-       return - k*state.x - b*state.v;
-}
-
-Derivative evaluate(const State &initial, float t)
-{
-       Derivative output;
-       output.dx = initial.v;
-       output.dv = acceleration(initial, t);
-       return output;
-}
-
-Derivative evaluate(const State &initial, float t, float dt, const Derivative &d)
-{
-       State state;
-       state.x = initial.x + d.dx*dt;
-       state.v = initial.v + d.dv*dt;
-       Derivative output;
-       output.dx = state.v;
-       output.dv = acceleration(state, t+dt);
-       return output;
-}
-
-void integrate(State &state, float t, float dt)
-{
-       Derivative a = evaluate(state, t);
-       Derivative b = evaluate(state, t, dt*0.5f, a);
-       Derivative c = evaluate(state, t, dt*0.5f, b);
-       Derivative d = evaluate(state, t, dt, c);
-       
-       const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
-       const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv);
-       
-       state.x = state.x + dxdt*dt;
-       state.v = state.v + dvdt*dt;
-}
-
-
-class root_view : public view
-{
-       void update(scalar t, scalar dt)
-       {
-               if (children().size() == 0) stop();
-       }
-};
-
-static root_view gRootView;
-
-
-class view::impl
-{
-public:
-
-       impl(view* view, moof::settings& settings, moof::video& video) :
-               view_(*view),
-               settings_(&settings),
-               video_(&video),
-               parent_(&gRootView)
-       {
-               init();
-
-               unsigned randomSeed;
-               if (settings.get("rngseed", randomSeed)) srand(randomSeed);
-               else srand(time(0));
-
-               scalar timestep = 80.0;
-               settings.get("timestep", timestep);
-               timestep_ = 1.0 / timestep;
-
-               scalar framerate = 40.0;
-               settings.get("framerate", framerate);
-               framerate_ = 1.0 / framerate;
-
-               show_fps_ = false;
-               settings.get("showfps", show_fps_);
-       }
-
-       impl(view* view) :
-               view_(*view),
-               settings_(0),
-               video_(0),
-               parent_(&gRootView)
-       {
-               init();
-       }
-
-       void init()
-       {
-               timestep_ = SCALAR(0.01);
-               framerate_ = SCALAR(0.02);
-               show_fps_ = false;
-       }
-
-
-       /**
-        * The main loop.  This just calls dispatch_events(), update(), and
-        * draw() over and over again.  The timing of the update and draw are
-        * decoupled.  The actual frame rate is also calculated here.  This
-        * function will return the exit code used to stop the loop.
-        */
-
-       scalar nextUpdate;
-       scalar totalTime;
-
-       void U(timer& T, scalar t)
-       {
-               const int MAX_FRAMESKIP = 15;
-
-               log_info("update");
-
-               int i = 0;
-               while (nextUpdate < t && ++i < MAX_FRAMESKIP)
-               {
-                       totalTime += timestep_;                 // 3. update state
-                       view_.update(totalTime, timestep_);
-
-                       //previous = current;
-                       //integrate(current, totalTime, timestep);
-
-                       nextUpdate += timestep_;
-               }
-       }
-
-       void D(timer& T, scalar t)
-       {
-               const scalar inverseTimestep = SCALAR(1.0) / timestep_;
-
-               log_info("draw");
-
-               scalar alpha = (t + timestep_ - nextUpdate) * inverseTimestep;
-               //scalar alpha = (nextUpdate - t) * inverseTimestep;
-               if (alpha < SCALAR(0.0)) log_error("UH OH!!!!!  It's NEGATIVE", alpha);
-               if (alpha > SCALAR(1.0)) log_error("UH OH!!!!!  It's POSITIVE", alpha);
-               log_info("alpha:", alpha);
-
-               view_.draw(alpha);
-               video_->swap();                                 // 4. draw state
-       }
-
-       timer utimer, dtimer;
-
-       void run()
-       {
-               ASSERT(video_ && "running without video set");
-
-               utimer.init(boost::bind(&impl::U, this, _1, _2), timestep_, timer::repeat);
-               dtimer.init(boost::bind(&impl::D, this, _1, _2), framerate_, timer::repeat);
-
-               totalTime = 0.0f;
-               nextUpdate = timer::ticks();
-
-
-               //scalar totalTime = 0.0;
-               //scalar ticks = timer::ticks();
-
-               //scalar nextUpdate = ticks;
-               //scalar nextDraw = ticks;
-               //scalar nextSecond = ticks + SCALAR(1.0);
-
-               fps_ = 0;
-               //int frameCount = 0;
-
-               //const scalar timestep = SCALAR(0.01);//timestep_;
-               //const scalar framerate = framerate_;
-
-               //const int MAX_FRAMESKIP = 15;
-               //const scalar inverseTimestep = SCALAR(1.0) / timestep;
-
-               is_running_ = true;
-               for (;;)
-               {
-                       //timer::fire_expired_timers();         // 1. fire timers
-                       dispatch_events();                                      // 2. dispatch events
-
-                       //if (!is_running_) break;
-
-                       //int i = 0;
-                       //while (nextUpdate < timer::ticks() && i < MAX_FRAMESKIP)
-                       //{
-                               //totalTime += timestep;                        // 3. update state
-                               //view_.update(totalTime, timestep);
-
-                               ////previous = current;
-                               ////integrate(current, totalTime, timestep);
-
-                               //nextUpdate += timestep;
-                               //++i;
-
-                               //if (!is_running_) break;
-                       //}
-
-               ////const float newTime = timer::ticks();
-               ////float deltaTime = newTime - currentTime;
-               ////currentTime = newTime;
-               
-               ////if (deltaTime>0.25f)
-                       ////deltaTime = 0.25f;
-               
-               ////accumulator += deltaTime;
-               
-               ////while (accumulator>=dt)
-               ////{
-                       ////accumulator -= dt;
-                       ////previous = current;
-                       ////integrate(current, t, dt);
-                       ////t += dt;
-               ////}
-
-                       ////if (nextDraw < (ticks = timer::ticks()))
-                       ////{
-                       //ticks = timer::ticks();
-                               //scalar diff = ticks - nextDraw;
-                               ////log_info("difference:", diff);
-                               //scalar alpha = (ticks + timestep - nextUpdate) * inverseTimestep;
-                               ////scalar alpha = (nextUpdate - ticks) * inverseTimestep;
-                               ////float alpha = accumulator/dt;
-                               //if (alpha < SCALAR(0.0)) log_error("UH OH!!!!!  It's NEGATIVE", alpha);
-                               //if (alpha > SCALAR(1.0)) log_error("UH OH!!!!!  It's POSITIVE", alpha);
-                               //log_info("alpha:", alpha);
-
-                               //view_.draw(alpha);
-
-                               //// TEMP
-                       ////State state = interpolate(previous, current, alpha);
-                       ////glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-                       ////glBegin(GL_POINTS);
-                       ////glColor3f(1,1,1);
-                       ////glVertex3f(state.x, 0, 0);
-                       ////glEnd();
-               
-
-
-                               //video_->swap();                                       // 4. draw state
-
-                               //nextDraw += framerate;
-                               //++frameCount;
-
-                               //if (nextSecond < ticks)//timer::ticks())
-                               //{
-                                       //fps_ = frameCount;
-                                       //frameCount = 0;
-
-                                       //if (show_fps_) log_info << fps_ << " fps" << std::endl;
-
-                                       //nextSecond += SCALAR(1.0);
-                               //}
-                       ////}
-
-                       if (!is_running_) break;
-
-                       //ticks = timer::ticks();                               // 5. yield timeslice
-                       //scalar next = std::min(nextUpdate, nextDraw);
-                       //next = std::min(next, timer::next_event());
-                       //if (ticks < next) timer::sleep(next, timer::absolute);
-
-                       //timer::sleep(timer::next_event(), timer::absolute);
-
-                       // Animation is choppy... the sound timer makes the draw occur
-                       // late.  It's not usually enough to make the FPS drop, but it
-                       // certainly is noticeably choppy.  Maybe update and draw
-                       // should both be scheduled like timers.  That should reduce
-                       // the number of times either update or draw occur late.  It
-                       // doesn't really matter if update is late, but it's ugly if
-                       // draw is late.
-               }
-       }
-
-       void stop()
-       {
-               is_running_ = false;
-       }
-
-
-       void dispatch_events()
-       {
-               event event;
-
-               while (FE_PollEvent(&event) == 1)
-               {
-                       switch (event.type)
-                       {
-                               case SDL_KEYDOWN:
-                                       if (event.key.keysym.sym == SDLK_ESCAPE &&
-                                                       (SDL_GetModState() & KMOD_CTRL) )
-                                       {
-                                               // emergency escape
-                                               log_warning("escape forced");
-                                               exit(1);
-                                       }
-                                       break;
-
-                               case SDL_VIDEORESIZE:
-                                       video_->resize(event.resize.w, event.resize.h);
-                                       break;
-                       }
-
-                       view_.handle_event(event);
-               }
-       }
-
-       bool handle_event(const event& event)
-       {
-               std::list<view_ptr>::iterator it;
-               for (it = children_.begin(); it != children_.end(); ++it)
-               {
-                       if ((*it)->handle_event(event)) return true;
-               }
-
-               return false;
-       }
-
-       void update(scalar t, scalar dt)
-       {
-               std::list<view_ptr>::iterator it;
-               for (it = children_.begin(); it != children_.end(); ++it)
-               {
-                       (*it)->update(t, dt);
-               }
-       }
-
-       void draw(scalar alpha)
-       {
-               std::list<view_ptr>::iterator it;
-               for (it = children_.begin(); it != children_.end(); ++it)
-               {
-                       (*it)->draw(alpha);
-               }
-       }
-
-
-       void add_child(view_ptr child)
-       {
-               ASSERT(child && "adding null view");
-               ASSERT(child.get() != &view_ && "adding view to itself");
-
-               child->impl_->parent_->remove_child(child);
-               children_.push_back(child);
-
-               child->impl_->parent_ = &view_;
-               child->impl_->percolate_objects();
-
-               child->did_add_to_view();
-       }
-
-       void percolate_objects()
-       {
-               bool recurseAgain = false;
-
-               if (parent_->impl_->video_ && parent_->impl_->video_ != video_)
-               {
-                       video_ = parent_->impl_->video_;
-                       recurseAgain = true;
-               }
-
-               if (parent_->impl_->settings_ &&
-                       parent_->impl_->settings_ != settings_)
-               {
-                       settings_ = parent_->impl_->settings_;
-                       recurseAgain = true;
-               }
-
-               if (recurseAgain)
-               {
-                       std::list<view_ptr>::iterator it;
-                       for (it = children_.begin(); it != children_.end(); ++it)
-                       {
-                               (*it)->impl_->percolate_objects();
-                       }
-               }
-       }
-
-       view_ptr remove_child(view* child)
-       {
-               ASSERT(child && "cannot remove null child");
-
-               std::list<view_ptr>::iterator it;
-               for (it = children_.begin(); it != children_.end(); ++it)
-               {
-                       if ((*it).get() == child)
-                       {
-                               view_ptr found = *it;
-                               found->will_remove_from_view();
-                               children_.erase(it);
-
-                               found->impl_->parent_ = &gRootView;
-
-                               return found;
-                       }
-               }
-
-               return view_ptr();
-       }
-
-       void clear()
-       {
-               children_.clear();
-       }
-
-
-       bool                                    is_running_;
-       view&                                   view_;
-
-       moof::settings*                 settings_;
-       moof::video*                    video_;
-
-       view*                                   parent_;
-       std::list<view_ptr>             children_;
-
-       scalar                                  timestep_;
-       scalar                                  framerate_;
-
-       int                                             fps_;
-       bool                                    show_fps_;
-};
-
-
-view::view(moof::settings& settings, moof::video& video) :
-       // pass through
-       impl_(new view::impl(this, settings, video)) {}
-
-view::view() :
-       impl_(new view::impl(this)) {}
-
-
-void view::update(scalar t, scalar dt)
-{
-       // pass through
-       impl_->update(t, dt);
-}
-
-void view::draw(scalar alpha) const
-{
-       // pass through
-       impl_->draw(alpha);
-}
-
-bool view::handle_event(const event& event)
-{
-       // pass through
-       return impl_->handle_event(event);
-}
-
-
-void view::add_child(view_ptr view)
-{
-       // pass through
-       impl_->add_child(view);
-}
-
-view_ptr view::remove_child(view* view)
-{
-       // pass through
-       return impl_->remove_child(view);
-}
-
-view_ptr view::remove_child(view_ptr view)
-{
-       // pass through
-       return impl_->remove_child(view.get());
-}
-
-void view::clear()
-{
-       // pass through
-       impl_->clear();
-}
-
-
-view& view::parent() const
-{
-       return *(impl_->parent_);
-}
-
-const std::list<view_ptr>& view::children() const
-{
-       return impl_->children_;
-}
-
-
-moof::settings& view::settings() const
-{
-       ASSERT(impl_->settings_ && "accessing null reference");
-       // pass through
-       return *(impl_->settings_);
-}
-
-video& view::video() const
-{
-       ASSERT(impl_->video_ && "accessing null reference");
-       // pass through
-       return *(impl_->video_);
-}
-
-
-void view::run()
-{
-       // pass through
-       return impl_->run();
-}
-
-void view::stop()
-{
-       // pass through
-       return impl_->stop();
-}
-
-bool view::is_running() const
-{
-       // pass through
-       return impl_->is_running_;
-}
-
-
-} // namespace moof
-
diff --git a/src/moof/view.hh b/src/moof/view.hh
deleted file mode 100644 (file)
index 406c8ae..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
-**]  All rights reserved.
-*
-* vi:ts=4 sw=4 tw=75
-*
-* Distributable under the terms and conditions of the 2-clause BSD license;
-* see the file COPYING for a complete text of the license.
-*
-**************************************************************************/
-
-#ifndef _MOOF_VIEW_HH_
-#define _MOOF_VIEW_HH_
-
-/**
- * \file view.hh
- * Fundamental architectural classes.
- */
-
-#include <list>
-#include <string>
-
-#include <boost/shared_ptr.hpp>
-
-#include <moof/event.hh>
-#include <moof/math.hh>
-
-
-namespace moof {
-
-       
-class settings;
-class video;
-
-class view;
-typedef boost::shared_ptr<view> view_ptr;
-
-
-/**
- * The core 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 sent
- * to each layer from the top down until a layer signals the event was
- * handled.  The core is also responsible for firing timers on time.  The
- * core will continue running as long as there are layers on the stack.
- */
-class view
-{
-public:
-
-       // loads settings: rngseed, timestep, framerate, showfps
-       view(moof::settings& settings, moof::video& video);
-       view();
-
-       virtual ~view() {}
-
-       virtual void did_add_to_view() {}
-       virtual void will_remove_from_view() {}
-
-       virtual void update(scalar t, scalar dt);
-       virtual void draw(scalar alpha) const;
-       virtual bool handle_event(const event& event);
-
-
-       void add_child(view_ptr view);
-       view_ptr remove_child(view* view);
-       view_ptr remove_child(view_ptr view);
-       void clear();
-
-       view& parent() const;
-       const std::list<view_ptr>& children() const;
-
-       // do not call these without adding the view to a hierarchy with a base
-       // view constructed with settings and a video context
-       moof::settings& settings() const;
-       moof::video& video() const;
-
-       // set this machine in motion
-       void run();
-       void stop();
-       bool is_running() const;
-
-
-private:
-
-       class impl;
-       boost::shared_ptr<impl> impl_;
-};
-
-
-} // namespace moof
-
-#endif // _MOOF_VIEW_HH_
-
similarity index 69%
rename from src/GameLayer.cc
rename to src/yoink.cc
index 7d36f3312045ca00781a6294e7cd0f4e45701fc9..72fef6d01b3f59d3a354f0998aae93f29e2a9c18 100644 (file)
 #include <moof/math.hh>
 #include <moof/mesh.hh>
 #include <moof/opengl.hh>
-#include <moof/settings.hh>
+//#include <moof/settings.hh>
 #include <moof/video.hh>
 
-#include "GameLayer.hh"
+#include "yoink.hh"
 
 
-void GameLayer::loadSceneLoader()
+void yoink::load_scene_loader()
 {
        state_.script.import_safe_standard_libraries();
        moof::log::import(state_.script);
@@ -52,15 +52,24 @@ void GameLayer::loadSceneLoader()
        }
 }
 
-void GameLayer::advanceScene(moof::settings& settings)
+void yoink::advance_scene()
 {
        if (state_.sceneList.size() != 0)
        {
-               state_.scene = Scene::alloc(state_.sceneList[0]);
-               state_.sceneList.erase(state_.sceneList.begin());
+               //state_.scene = Scene::alloc(state_.sceneList[0]);
+               //state_.sceneList.erase(state_.sceneList.begin());
 
-               moof::script::status status = state_.scene->load(settings,
-                                                                                                          state_.script);
+               //moof::script::status status = state_.scene->load(settings,
+                                                                                                          //state_.script);
+
+               std::string path = moof::resource::find_file("scenes/"+state_.sceneList[0], "lua");
+               if (path.empty())
+               {
+                       throw "the scene file could not be found";
+               }
+
+               //importSceneBindings(settings, script);
+               moof::script::status status = state_.script.do_file(path);
                if (status != moof::script::success)
                {
                        std::string str;
@@ -88,7 +97,7 @@ void GameLayer::advanceScene(moof::settings& settings)
 }
 
 
-GameLayer::GameLayer()
+yoink::yoink()
 {
        music_.queue("NightFusionIntro");
        music_.loop(true);
@@ -101,20 +110,17 @@ GameLayer::GameLayer()
        state_.heroine->animation.startSequence("FlyDiagonallyUp");
 
        state_.interp.init(0.0, 1.0, 4.0, moof::lerp_scalar::oscillate);
-}
 
 
-void GameLayer::did_add_to_view()
-{
-       bool isMute = false;
-       settings().get("nomusic", isMute);
-       music_.play();
+       //bool isMute = false;
+       //settings().get("nomusic", isMute);
+       //music_.play();
 
-       loadSceneLoader();
-       advanceScene(settings());               // load the first scene
+       load_scene_loader();
+       advance_scene();                // load the first scene
 
        mHud = Hud::alloc(state_);
-       add_child(mHud);
+       //add_child(mHud);
 
        mRay.direction.set(1.0, 0.0);
 
@@ -124,20 +130,20 @@ void GameLayer::did_add_to_view()
        mCircle.point.set(22, 5);
        mCircle.radius = 2;
 
-       mRayTimer.init(boost::bind(&GameLayer::rayTimer, this),
-                                  1.0, moof::timer::repeat);
+       //mRayTimer.init(boost::bind(&yoink::rayTimer, this),
+                                  //1.0, moof::timer::repeat);
 
        projection();
 }
 
 
-void GameLayer::update(moof::scalar t, moof::scalar dt)
+void yoink::update(moof::scalar t, moof::scalar dt)
 {
-       if (!state_.scene) return;
+       //if (!state_.scene) return;
        state_.camera.update(t, dt);
        state_.heroine->update(t, dt);
 
-       state_.scene->checkForCollision(*state_.heroine);
+       //state_.scene->checkForCollision(*state_.heroine);
 
        moof::vector3 cam= -moof::promote(state_.heroine->state().position, 8);
        state_.camera.position(cam);
@@ -148,10 +154,10 @@ void GameLayer::update(moof::scalar t, moof::scalar dt)
        if (state_.script[-1].is_function()) state_.script.call();
        else                                 state_.script.pop();
 
-       moof::view::update(t, dt);
+       //moof::view::update(t, dt);
 }
 
-void GameLayer::rayTimer()
+void yoink::rayTimer()
 {
        moof::ray2::contact meh;
        std::list<moof::ray2::contact> hits;
@@ -175,20 +181,20 @@ void GameLayer::rayTimer()
                hits.push_back(meh);
        }
 
-       if (state_.scene->castRay(mRay, hits))
-       {
-               hits.front().normal.normalize();
-               mRay.solve(point, hits.front().distance);
-               moof::log_info << "scene: d = " << hits.front().distance << std::endl;
-               moof::log_info << "       P = " << point << std::endl;
-               moof::log_info << "       n = " << hits.front().normal << std::endl;
-       }
+       //if (state_.scene->castRay(mRay, hits))
+       //{
+               //hits.front().normal.normalize();
+               //mRay.solve(point, hits.front().distance);
+               //moof::log_info << "scene: d = " << hits.front().distance << std::endl;
+               //moof::log_info << "       P = " << point << std::endl;
+               //moof::log_info << "       n = " << hits.front().normal << std::endl;
+       //}
 }
 
 
-void GameLayer::draw(moof::scalar alpha) const
+void yoink::draw(moof::scalar alpha) const
 {
-       if (!state_.scene) return;
+       //if (!state_.scene) return;
        state_.camera.upload_to_gl(alpha);
 
        float pos[] = {state_.heroine->state().position[0],
@@ -222,16 +228,18 @@ void GameLayer::draw(moof::scalar alpha) const
 
        state_.heroine->draw(alpha);
 
-       mRay.draw();
+       //mRay.draw();
        mLine.draw();
        mCircle.draw();
 
-       moof::view::draw(alpha);
+       //moof::view::draw(alpha);
 }
 
-bool GameLayer::handle_event(const moof::event& event)
+bool yoink::handle_event(const moof::event& event)
 {
-       if (moof::view::handle_event(event)) return true;
+       //if (moof::view::handle_event(event)) return true;
+       
+       static moof::scalar scale = SCALAR(1.0);
 
        switch (event.type)
        {
@@ -250,20 +258,24 @@ bool GameLayer::handle_event(const moof::event& event)
                        }
                        else if (event.key.keysym.sym == SDLK_PAGEUP)
                        {
-                               mRay.direction = moof::rotate_vector_2D(mRay.direction,
-                                                                                                               moof::rad(10.0));
+                               //mRay.direction = moof::rotate_vector_2D(mRay.direction,
+                                                                                                               //moof::rad(10.0));
+                               scale += SCALAR(0.1);
+                               moof::timer::default_source().scale(scale);
                                return true;
                        }
                        else if (event.key.keysym.sym == SDLK_PAGEDOWN)
                        {
-                               mRay.direction = moof::rotate_vector_2D(mRay.direction,
-                                                                                                               moof::rad(-10.0));
+                               //mRay.direction = moof::rotate_vector_2D(mRay.direction,
+                                                                                                               //moof::rad(-10.0));
+                               scale -= SCALAR(0.1);
+                               moof::timer::default_source().scale(scale);
                                return true;
                        }
                        else if (event.key.keysym.sym == SDLK_r)
                        {
-                               loadSceneLoader();
-                               advanceScene(settings());
+                               load_scene_loader();
+                               advance_scene();
                                return true;
                        }
                        return state_.heroine->handle_event(event);
@@ -271,12 +283,12 @@ bool GameLayer::handle_event(const moof::event& event)
                case SDL_KEYUP:
                        if (event.key.keysym.sym == SDLK_ESCAPE)
                        {
-                               parent().remove_child(this);
-                               return true;
+                               //parent().remove_child(this);
+                               return false;
                        }
                        else if (event.key.keysym.sym == SDLK_h)
                        {
-                               add_child(mHud);
+                               //add_child(mHud);
                                return true;
                        }
                        return state_.heroine->handle_event(event);
@@ -295,12 +307,13 @@ bool GameLayer::handle_event(const moof::event& event)
 }
 
 
-void GameLayer::projection()
+void yoink::projection()
 {
-       projection(video().width(), video().height());
+       moof::video* video = moof::video::current();
+       projection(video->width(), video->height());
 }
 
-void GameLayer::projection(moof::scalar width, moof::scalar height)
+void yoink::projection(moof::scalar width, moof::scalar height)
 {
        state_.camera.projection(moof::rad(60.0),
                                                         width / height,
similarity index 75%
rename from src/GameLayer.hh
rename to src/yoink.hh
index f3814430e72417f87cd007fe29f4ab23efec5656..cc4446a387875714cb950bb3769aaa5f54e15ed1 100644 (file)
@@ -9,11 +9,11 @@
 *
 **************************************************************************/
 
-#ifndef _GAMELAYER_HH_
-#define _GAMELAYER_HH_
+#ifndef _YOINK_HH_
+#define _YOINK_HH_
 
 /**
- * @file GameLayer.hh
+ * \file yoink.hh
  * This is the big enchilada.
  */
 
 #include <moof/ray.hh>
 #include <moof/sphere.hh>
 #include <moof/timer.hh>
-#include <moof/view.hh>
 
 #include "GameState.hh"
 #include "Hud.hh"
 
 
-class GameLayer;
-typedef boost::shared_ptr<GameLayer> GameLayerP;
-
-class GameLayer : public moof::view
+class yoink
 {
 public:
 
-       static GameLayerP alloc()
-       {
-               return GameLayerP(new GameLayer);
-       }
-       GameLayer();
-
-       void did_add_to_view();
+       yoink();
 
        void update(moof::scalar t, moof::scalar dt);
        void draw(moof::scalar alpha) const;
@@ -58,8 +48,8 @@ public:
 
 private:
 
-       void loadSceneLoader();
-       void advanceScene(moof::settings& settings);
+       void load_scene_loader();
+       void advance_scene();
 
        void projection();
        void projection(moof::scalar width, moof::scalar height);
@@ -80,5 +70,5 @@ private:
 };
 
 
-#endif // _GAMELAYER_HH_
+#endif // _YOINK_HH_
 
This page took 0.095736 seconds and 4 git commands to generate.