From af88821a172c4dfd138b91b2a5148ae50b502fa2 Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Fri, 20 Aug 2010 22:28:47 -0600 Subject: [PATCH] further implementing runloop support --- data/scenes/Classic.lua | 2 +- data/yoinkrc | 34 +- src/Hud.cc | 2 +- src/Hud.hh | 3 +- src/Main.cc | 16 +- src/Main.hh | 4 + src/TitleLayer.cc | 68 ---- src/TitleLayer.hh | 48 --- src/moof/application.cc | 70 +++- src/moof/application.hh | 2 + src/moof/image.cc | 4 + src/moof/runloop.cc | 52 ++- src/moof/runloop.hh | 22 +- src/moof/sound.cc | 2 +- src/moof/thread.hh | 6 +- src/moof/timer.cc | 155 ++++++--- src/moof/timer.hh | 212 ++++++++---- src/moof/video.cc | 34 +- src/moof/video.hh | 25 +- src/moof/view.cc | 575 --------------------------------- src/moof/view.hh | 94 ------ src/{GameLayer.cc => yoink.cc} | 115 ++++--- src/{GameLayer.hh => yoink.hh} | 26 +- 23 files changed, 540 insertions(+), 1031 deletions(-) delete mode 100644 src/TitleLayer.cc delete mode 100644 src/TitleLayer.hh delete mode 100644 src/moof/view.cc delete mode 100644 src/moof/view.hh rename src/{GameLayer.cc => yoink.cc} (69%) rename src/{GameLayer.hh => yoink.hh} (75%) diff --git a/data/scenes/Classic.lua b/data/scenes/Classic.lua index c2ca183..b1364b0 100644 --- a/data/scenes/Classic.lua +++ b/data/scenes/Classic.lua @@ -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") diff --git a/data/yoinkrc b/data/yoinkrc index af051b3..1d58bef 100644 --- a/data/yoinkrc +++ b/data/yoinkrc @@ -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 +-- display; use 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 diff --git a/src/Hud.cc b/src/Hud.cc index 58bc721..cc25dd5 100644 --- a/src/Hud.cc +++ b/src/Hud.cc @@ -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; diff --git a/src/Hud.hh b/src/Hud.hh index 1bb5576..30c0136 100644 --- a/src/Hud.hh +++ b/src/Hud.hh @@ -21,7 +21,6 @@ #include //#include #include -#include #include "GameState.hh" @@ -58,7 +57,7 @@ private: class Hud; typedef boost::shared_ptr HudP; -class Hud : public moof::view +class Hud { public: diff --git a/src/Main.cc b/src/Main.cc index e168037..070912e 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -26,6 +26,7 @@ inline int isatty(int dummy) { return 0; } #include #include +#include #include #include #include @@ -34,9 +35,7 @@ inline int isatty(int dummy) { return 0; } #include #include -#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(); diff --git a/src/Main.hh b/src/Main.hh index 47163d1..088bd3c 100644 --- a/src/Main.hh +++ b/src/Main.hh @@ -27,6 +27,8 @@ #include #include +#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 index 92484d0..0000000 --- a/src/TitleLayer.cc +++ /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 - -#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::Ptr transition = - //moof::Transition::alloc(mGameLayer, titleLayer, - //interp); - - return true; - } - - return false; -} - diff --git a/src/TitleLayer.hh b/src/TitleLayer.hh deleted file mode 100644 index be8aba1..0000000 --- a/src/TitleLayer.hh +++ /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 - -#include -#include -#include - - -class TitleLayer; -typedef boost::shared_ptr 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_ - diff --git a/src/moof/application.cc b/src/moof/application.cc index fd9ea45..b462a0e 100644 --- a/src/moof/application.cc +++ b/src/moof/application.cc @@ -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); } diff --git a/src/moof/application.hh b/src/moof/application.hh index 671011f..494e98d 100644 --- a/src/moof/application.hh +++ b/src/moof/application.hh @@ -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_; diff --git a/src/moof/image.cc b/src/moof/image.cc index 7453b48..94d4687 100644 --- a/src/moof/image.cc +++ b/src/moof/image.cc @@ -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; } } diff --git a/src/moof/runloop.cc b/src/moof/runloop.cc index db59814..f6f47dd 100644 --- a/src/moof/runloop.cc +++ b/src/moof/runloop.cc @@ -9,7 +9,12 @@ * **************************************************************************/ +#include "config.h" + +#include + #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 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(); } } diff --git a/src/moof/runloop.hh b/src/moof/runloop.hh index 0aad06d..f70abde 100644 --- a/src/moof/runloop.hh +++ b/src/moof/runloop.hh @@ -17,7 +17,7 @@ * Thread timer management class. */ -#include +#include #include @@ -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_table; + typedef std::vector timer_table; timer_table timers_; timer_table::iterator timers_it_; diff --git a/src/moof/sound.cc b/src/moof/sound.cc index f306054..34c30ce 100644 --- a/src/moof/sound.cc +++ b/src/moof/sound.cc @@ -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) { diff --git a/src/moof/thread.hh b/src/moof/thread.hh index 72c6dc0..1e710d8 100644 --- a/src/moof/thread.hh +++ b/src/moof/thread.hh @@ -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 diff --git a/src/moof/timer.cc b/src/moof/timer.cc index 9b105b4..c45e1b8 100644 --- a/src/moof/timer.cc +++ b/src/moof/timer.cc @@ -18,6 +18,7 @@ #include #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 diff --git a/src/moof/timer.hh b/src/moof/timer.hh index 90c53ce..9f3e984 100644 --- a/src/moof/timer.hh +++ b/src/moof/timer.hh @@ -23,12 +23,48 @@ #include #include -#include 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_; }; diff --git a/src/moof/video.cc b/src/moof/video.cc index aa49b03..263ea88 100644 --- a/src/moof/video.cc +++ b/src/moof/video.cc @@ -9,6 +9,7 @@ * **************************************************************************/ +#include #include #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(); } diff --git a/src/moof/video.hh b/src/moof/video.hh index ea331a0..8b42cfd 100644 --- a/src/moof/video.hh +++ b/src/moof/video.hh @@ -23,6 +23,8 @@ #include #include +#include +#include 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 index 62fcd93..0000000 --- a/src/moof/view.cc +++ /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 -#include // exit, srand -#include // time -#include - -#include -#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 ¤t, 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::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::iterator it; - for (it = children_.begin(); it != children_.end(); ++it) - { - (*it)->update(t, dt); - } - } - - void draw(scalar alpha) - { - std::list::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::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::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 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::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 index 406c8ae..0000000 --- a/src/moof/view.hh +++ /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 -#include - -#include - -#include -#include - - -namespace moof { - - -class settings; -class video; - -class view; -typedef boost::shared_ptr 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& 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_; -}; - - -} // namespace moof - -#endif // _MOOF_VIEW_HH_ - diff --git a/src/GameLayer.cc b/src/yoink.cc similarity index 69% rename from src/GameLayer.cc rename to src/yoink.cc index 7d36f33..72fef6d 100644 --- a/src/GameLayer.cc +++ b/src/yoink.cc @@ -17,13 +17,13 @@ #include #include #include -#include +//#include #include -#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 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, diff --git a/src/GameLayer.hh b/src/yoink.hh similarity index 75% rename from src/GameLayer.hh rename to src/yoink.hh index f381443..cc4446a 100644 --- a/src/GameLayer.hh +++ b/src/yoink.hh @@ -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. */ @@ -31,26 +31,16 @@ #include #include #include -#include #include "GameState.hh" #include "Hud.hh" -class GameLayer; -typedef boost::shared_ptr 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_ -- 2.45.2