From e0c0a3b5e7337cde55e520801d2e59e03dc97d9c Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Mon, 1 Mar 2010 00:27:38 -0700 Subject: [PATCH] destroyed global classes; view hierarchy instead --- configure.ac | 4 +- src/Character.cc | 2 +- src/GameLayer.cc | 61 +++--- src/GameLayer.hh | 11 +- src/Hud.cc | 10 +- src/Hud.hh | 8 +- src/Main.cc | 95 ++++----- src/Main.hh | 21 +- src/Makefile.am | 12 +- src/Moof/Backend.cc | 94 +++++++++ src/Moof/Backend.hh | 46 ++++ src/Moof/Contact.hh | 40 ++++ src/Moof/Core.cc | 451 ---------------------------------------- src/Moof/Core.hh | 98 --------- src/Moof/Dispatch.cc | 85 ++++---- src/Moof/Dispatch.hh | 47 +++-- src/Moof/Image.cc | 2 +- src/Moof/Layer.hh | 47 ----- src/Moof/Line.hh | 136 ++++++++++++ src/Moof/ModalDialog.hh | 15 +- src/Moof/Resource.cc | 4 +- src/Moof/Settings.cc | 5 +- src/Moof/Settings.hh | 8 +- src/Moof/Shape.hh | 6 +- src/Moof/Sphere.hh | 86 ++++---- src/Moof/Texture.cc | 11 +- src/Moof/Transition.hh | 21 +- src/Moof/Video.cc | 105 ++++++---- src/Moof/Video.hh | 53 +++-- src/Moof/View.cc | 411 ++++++++++++++++++++++++++++++++++++ src/Moof/View.hh | 88 ++++++++ src/Scene.cc | 12 +- src/Scene.hh | 6 +- src/TitleLayer.cc | 29 +-- src/TitleLayer.hh | 8 +- 35 files changed, 1214 insertions(+), 924 deletions(-) create mode 100644 src/Moof/Backend.cc create mode 100644 src/Moof/Backend.hh create mode 100644 src/Moof/Contact.hh delete mode 100644 src/Moof/Core.cc delete mode 100644 src/Moof/Core.hh delete mode 100644 src/Moof/Layer.hh create mode 100644 src/Moof/View.cc create mode 100644 src/Moof/View.hh diff --git a/configure.ac b/configure.ac index fa99616..7a01c45 100644 --- a/configure.ac +++ b/configure.ac @@ -102,8 +102,8 @@ AC_ARG_ENABLE([qt4], if test x$debug = xyes then - CFLAGS="$CFLAGS -DDEBUG -Wall -Wno-uninitialized" - CXXFLAGS="$CXXFLAGS -DDEBUG -Wall -Wno-uninitialized" + CFLAGS="$CFLAGS -DDEBUG -ggdb -O0 -Wall -Wno-uninitialized" + CXXFLAGS="$CXXFLAGS -DDEBUG -ggdb -O0 -Wall -Wno-uninitialized" else CFLAGS="$CFLAGS -DNDEBUG" CXXFLAGS="$CXXFLAGS -DNDEBUG" diff --git a/src/Character.cc b/src/Character.cc index 840099c..82d5e54 100644 --- a/src/Character.cc +++ b/src/Character.cc @@ -73,7 +73,7 @@ Character::Character(const std::string& name) : // forces mState.force = Mf::Vector2(0.0, 0.0); //mState.forces.push_back(SpringForce(Mf::Vector2(5.0, 4.0))); - //mState.forces.push_back(ResistanceForce(2.0)); + mState.forces.push_back(ResistanceForce(2.0)); //mState.forces.push_back(Mf::LinearState<2>::GravityForce(-9.8)); // starting position diff --git a/src/GameLayer.cc b/src/GameLayer.cc index 331d04f..0be8eb7 100644 --- a/src/GameLayer.cc +++ b/src/GameLayer.cc @@ -9,7 +9,6 @@ * **************************************************************************/ -#include #include #include #include @@ -53,14 +52,15 @@ void GameLayer::loadSceneLoader() } } -void GameLayer::advanceScene() +void GameLayer::advanceScene(Mf::Settings& settings) { if (mState.sceneList.size() != 0) { mState.scene = Scene::alloc(mState.sceneList[0]); mState.sceneList.erase(mState.sceneList.begin()); - Mf::Script::Result status = mState.scene->load(mState.script); + Mf::Script::Result status = mState.scene->load(settings, + mState.script); if (status != Mf::Script::SUCCESS) { std::string str; @@ -85,22 +85,14 @@ void GameLayer::advanceScene() GameLayer::GameLayer() : - mHud(Hud::alloc(mState)), mMusic("NightFusionIntro"), mPunchSound("Thump") { mMusic.setLooping(true); mMusic.enqueue("NightFusionLoop"); - bool isMute = false; - Mf::settings.get("nomusic", isMute); - if (!isMute) mMusic.play(); - //mMusic.setPosition(Mf::Vector3(10.0, 5.0, 0.0)); - loadSceneLoader(); - advanceScene(); // load the first scene - mThinkTimer.init(boost::bind(&GameLayer::thinkTimer, this), 0.1, Mf::Timer::REPEAT); @@ -109,14 +101,20 @@ GameLayer::GameLayer() : mState.interp.init(0.0, 1.0); mState.interp.reset(4.0, Mf::Interp::OSCILLATE); - - setProjection(); } -void GameLayer::addedToCore() +void GameLayer::didAddToView() { - Mf::core.push(mHud); + bool isMute = false; + settings().get("nomusic", isMute); + if (!isMute) mMusic.play(); + + loadSceneLoader(); + advanceScene(settings()); // load the first scene + + mHud = Hud::alloc(mState); + addChild(mHud); mRay.direction.set(1.0, 0.0); @@ -128,21 +126,25 @@ void GameLayer::addedToCore() mRayTimer.init(boost::bind(&GameLayer::rayTimer, this), 1.0, Mf::Timer::REPEAT); + + setProjection(); } void GameLayer::update(Mf::Scalar t, Mf::Scalar dt) { + if (!mState.scene) return; mState.camera.update(t, dt); mState.heroine->update(t, dt); mState.scene->checkForCollision(*mState.heroine); - Mf::Vector3 camPosition(-mState.heroine->getState().position[0], - -mState.heroine->getState().position[1], -8); - mState.camera.setPosition(camPosition); + Mf::Vector3 cam= -Mf::promote(mState.heroine->getState().position, 8); + mState.camera.setPosition(cam); mRay.point = mState.heroine->getState().position; + + Mf::View::update(t, dt); } void GameLayer::thinkTimer() @@ -162,8 +164,12 @@ void GameLayer::rayTimer() bool bam = mLine.intersectRay(mRay, meh); if (bam) { - meh.normal.normalize(); - hits.push_back(meh); + //meh.normal.normalize(); + //hits.push_back(meh); + mRay.solve(point, meh.distance); + Mf::logInfo << "line: d = " << meh.distance << std::endl; + Mf::logInfo << " P = " << point << std::endl; + Mf::logInfo << " n = " << meh.normal << std::endl; } bam = mCircle.intersectRay(mRay, meh); @@ -186,6 +192,7 @@ void GameLayer::rayTimer() void GameLayer::draw(Mf::Scalar alpha) const { + if (!mState.scene) return; mState.camera.uploadToGL(alpha); // DRAW THE SCENE @@ -200,10 +207,14 @@ void GameLayer::draw(Mf::Scalar alpha) const mRay.draw(); mLine.draw(); mCircle.draw(); + + Mf::View::draw(alpha); } bool GameLayer::handleEvent(const Mf::Event& event) { + if (Mf::View::handleEvent(event)) return true; + switch (event.type) { case SDL_KEYDOWN: @@ -234,7 +245,7 @@ bool GameLayer::handleEvent(const Mf::Event& event) else if (event.key.keysym.sym == SDLK_r) { loadSceneLoader(); - advanceScene(); + advanceScene(settings()); return true; } return mState.heroine->handleEvent(event); @@ -242,12 +253,12 @@ bool GameLayer::handleEvent(const Mf::Event& event) case SDL_KEYUP: if (event.key.keysym.sym == SDLK_ESCAPE) { - Mf::core.pop(this); + parent().removeChild(this); return true; } else if (event.key.keysym.sym == SDLK_h) { - Mf::core.push(mHud); + addChild(mHud); return true; } return mState.heroine->handleEvent(event); @@ -268,9 +279,7 @@ bool GameLayer::handleEvent(const Mf::Event& event) void GameLayer::setProjection() { - ASSERT(Mf::video && - "no current video context from which to get dimensions"); - setProjection(Mf::video->getWidth(), Mf::video->getHeight()); + setProjection(video().getWidth(), video().getHeight()); } void GameLayer::setProjection(Mf::Scalar width, Mf::Scalar height) diff --git a/src/GameLayer.hh b/src/GameLayer.hh index c537af6..145cf76 100644 --- a/src/GameLayer.hh +++ b/src/GameLayer.hh @@ -23,7 +23,6 @@ #include -#include #include #include @@ -32,6 +31,7 @@ #include #include #include +#include #include "GameState.hh" #include "Hud.hh" @@ -40,18 +40,17 @@ class GameLayer; typedef boost::shared_ptr GameLayerP; -class GameLayer : public Mf::Layer +class GameLayer : public Mf::View { public: - GameLayer(); - static GameLayerP alloc() { return GameLayerP(new GameLayer); } + GameLayer(); - void addedToCore(); + void didAddToView(); void update(Mf::Scalar t, Mf::Scalar dt); void draw(Mf::Scalar alpha) const; @@ -60,7 +59,7 @@ public: private: void loadSceneLoader(); - void advanceScene(); + void advanceScene(Mf::Settings& settings); void thinkTimer(); diff --git a/src/Hud.cc b/src/Hud.cc index f4134cf..28b7c34 100644 --- a/src/Hud.cc +++ b/src/Hud.cc @@ -10,7 +10,6 @@ **************************************************************************/ #include -#include #include #include #include @@ -111,9 +110,9 @@ Hud::Hud(GameState& state) : mBar2(Mf::Texture("StatusBars"), 2), mFont("Font") { - ASSERT(Mf::video && - "no current video context from which to get dimensions"); - resize(Mf::video->getWidth(), Mf::video->getHeight()); + Mf::Video* video = Mf::Video::current(); + ASSERT(video && "a current video context should be set"); + resize(video->getWidth(), video->getHeight()); } @@ -174,7 +173,8 @@ bool Hud::handleEvent(const Mf::Event& event) if (event.key.keysym.sym == SDLK_h) { // don't want the hud anymore - Mf::core.pop(this); + parent().removeChild(this); + Mf::logWarning("okay bye bye hud"); return true; } diff --git a/src/Hud.hh b/src/Hud.hh index bc8a313..0bc0a46 100644 --- a/src/Hud.hh +++ b/src/Hud.hh @@ -18,10 +18,10 @@ */ #include -#include #include //#include #include +#include #include "GameState.hh" @@ -58,16 +58,16 @@ private: class Hud; typedef boost::shared_ptr HudP; -class Hud : public Mf::Layer +class Hud : public Mf::View { public: - Hud(GameState& state); - static HudP alloc(GameState& state) { return HudP(new Hud(state)); } + Hud(GameState& state); + void setBar1Progress(Mf::Scalar progress) { diff --git a/src/Main.cc b/src/Main.cc index 91a8d08..7b31ae4 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -10,6 +10,7 @@ **************************************************************************/ #include // atexit, getenv +#include #include #include #include // access @@ -19,7 +20,6 @@ #include #include #include -#include #include #include "ErrorHandler.hh" @@ -33,35 +33,28 @@ #include "version.h" -Main::Main() +Main::Main(Mf::Settings& settings, Mf::Video& video) : + Mf::View(settings, video) { - mDispatchHandler = Mf::core.addHandler("video.newcontext", - boost::bind(&Main::contextCreated)); + Mf::Dispatch& dispatch = Mf::Dispatch::global(); + mNewContextDispatch = dispatch.addTarget("video.newcontext", + boost::bind(&Main::setupGL)); setupGL(); -} -void Main::addedToCore() -{ - //Mf::Scalar coeff[] = {0.0, 1.0}; - //Mf::Lerp interp(coeff, 0.25); - - //Mf::LayerP gameLayer = GameLayer::alloc(); - //Mf::Transition::Ptr transition = - //Mf::Transition::alloc(gameLayer, Mf::LayerP(), interp); - //core.push(transition); - //core.push(GameLayer::alloc()); - Mf::core.push(TitleLayer::alloc()); + addChild(TitleLayer::alloc()); } void Main::update(Mf::Scalar t, Mf::Scalar dt) { - if (Mf::core.getSize() == 1) + if (children().size() == 0) { - // this is the only layer left on the stack - //Mf::core.push(TitleLayer::alloc()); - Mf::core.clear(); + Mf::logWarning("main view has no children"); + stop(); + return; } + + Mf::View::update(t, dt); } void Main::draw(Mf::Scalar alpha) const @@ -73,25 +66,25 @@ void Main::draw(Mf::Scalar alpha) const glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + + Mf::View::draw(alpha); } bool Main::handleEvent(const Mf::Event& event) { + if (Mf::View::handleEvent(event)) return true; + switch (event.type) { case SDL_KEYUP: - if (event.key.keysym.sym == SDLK_ESCAPE) + if (event.key.keysym.sym == SDLK_f) { - Mf::core.clear(); - } - else if (event.key.keysym.sym == SDLK_f) - { - Mf::video->toggleFull(); + video().toggleFull(); } else if (event.key.keysym.sym == SDLK_l) { - Mf::video->toggleCursorGrab(); - Mf::video->toggleCursorVisible(); + video().toggleCursorGrab(); + video().toggleCursorVisible(); } break; @@ -100,8 +93,8 @@ bool Main::handleEvent(const Mf::Event& event) break; case SDL_QUIT: - Mf::core.clear(); - break; + stop(); + return true; } return false; @@ -137,7 +130,7 @@ std::string Main::getConfigPath() std::string path = Mf::Resource::getPath("yoinkrc"); -#if !defined(_WIN32) && !defined(__WIN32__) +#if !defined(_WIN32) path += ":/etc/yoinkrc"; #endif path += ":$HOME/.yoinkrc"; @@ -178,14 +171,6 @@ void Main::setupGL() //glMatrixMode(GL_MODELVIEW); } -void Main::contextCreated() -{ - // whenever the context is destroyed and a new one created, it probably - // won't contain our state so we need to set that up again - setupGL(); -} - - void Main::printUsage() { @@ -283,6 +268,7 @@ void goodbye() std::cout << std::endl << "Goodbye..." << std::endl << std::endl; } + int main(int argc, char* argv[]) { if (argc > 1) @@ -305,33 +291,32 @@ int main(int argc, char* argv[]) Mf::Resource::addSearchPaths(Main::getSearchPath()); - Mf::settings.loadFromFiles(Main::getConfigPath()); - Mf::settings.parseArgs(argc, argv); + Mf::Settings settings(argc, argv, Main::getConfigPath()); Mf::Log::Level logLevel = Mf::Log::INFO; - Mf::settings.get("loglevel", logLevel); + settings.get("loglevel", logLevel); Mf::Log::setLevel(logLevel); try { - Mf::Video video(PACKAGE_STRING, - Mf::Resource::getPath(PACKAGE".png")); - MainP app = Main::alloc(); - Mf::core.push(app); - Mf::core.run(); + Mf::Video::Attributes attributes(settings); + attributes.caption = PACKAGE_STRING; + attributes.icon = Mf::Resource::getPath(PACKAGE".png"); + + Mf::Video video(attributes); + Main mainView(settings, video); + + mainView.run(); + return 0; } catch (const Mf::Error& error) { - Mf::ModalDialog dialog; - dialog.title = PACKAGE_STRING; - dialog.text1 = "Unhandled Exception"; - dialog.text2 = getErrorString(error); - dialog.type = Mf::ModalDialog::CRITICAL; - dialog.run(); + Mf::ModalDialog dialog(Mf::ModalDialog::CRITICAL, + PACKAGE_STRING, "Unhandled Exception", + getErrorString(error)); + dialog.run(); return 1; } - - return 0; } diff --git a/src/Main.hh b/src/Main.hh index 91a4b4c..a5ce293 100644 --- a/src/Main.hh +++ b/src/Main.hh @@ -23,25 +23,23 @@ #include #include -#include #include +#include +namespace Mf { +class Settings; +class View; +} + class Main; typedef boost::shared_ptr
MainP; -class Main : public Mf::Layer +class Main : public Mf::View { public: - Main(); - - static MainP alloc() - { - return MainP(new Main); - } - - void addedToCore(); + Main(Mf::Settings& settings, Mf::Video& video); void update(Mf::Scalar t, Mf::Scalar dt); void draw(Mf::Scalar alpha) const; @@ -59,9 +57,8 @@ private: * Set OpenGL to a state we can know and depend on. */ static void setupGL(); - static void contextCreated(); - Mf::Dispatch::Handler mDispatchHandler; + Mf::Dispatch::Handle mNewContextDispatch; }; diff --git a/src/Makefile.am b/src/Makefile.am index 4e8f65d..c87c412 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,12 +13,13 @@ noinst_LIBRARIES = libmoof.a libmoof_a_SOURCES = \ Moof/Aabb.hh \ + Moof/Backend.cc \ + Moof/Backend.hh \ Moof/Camera.cc \ Moof/Camera.hh \ + Moof/Contact.hh \ Moof/ConvertUTF.c \ Moof/ConvertUTF.h \ - Moof/Core.cc \ - Moof/Core.hh \ Moof/Cullable.hh \ Moof/Dispatch.cc \ Moof/Dispatch.hh \ @@ -33,7 +34,6 @@ libmoof_a_SOURCES = \ Moof/Image.cc \ Moof/Image.hh \ Moof/Interpolator.hh \ - Moof/Layer.hh \ Moof/Line.hh \ Moof/Log.cc \ Moof/Log.hh \ @@ -62,9 +62,10 @@ libmoof_a_SOURCES = \ Moof/Thread.hh \ Moof/Timer.cc \ Moof/Timer.hh \ - Moof/Transition.hh \ Moof/Video.cc \ Moof/Video.hh \ + Moof/View.cc \ + Moof/View.hh \ Moof/fastevents.c \ Moof/fastevents.h \ $(ENDLIST) @@ -89,6 +90,7 @@ yoink_SOURCES = \ ErrorHandler.hh \ GameLayer.cc \ GameLayer.hh \ + GameState.hh \ Heroine.cc \ Heroine.hh \ Hud.cc \ @@ -123,5 +125,5 @@ run: all $(YOINK_ENVIRONMENT) ./yoink $(YOINK_OPTS) debug: all - $(YOINK_ENVIRONMENT) gdb ./yoink + $(YOINK_ENVIRONMENT) ddd ./yoink diff --git a/src/Moof/Backend.cc b/src/Moof/Backend.cc new file mode 100644 index 0000000..95f4dc3 --- /dev/null +++ b/src/Moof/Backend.cc @@ -0,0 +1,94 @@ + +/*] 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 "fastevents.h" + +#include "Backend.hh" +#include "Error.hh" +#include "Log.hh" + + +namespace Mf { + + +struct Impl +{ + static Error error; + static int retainCount; +}; + +Error Impl::error(Error::UNINITIALIZED); +int Impl::retainCount = 0; + + +Backend::Backend() +{ + if (Impl::retainCount++ == 0) + { +#if defined(_WIN32) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) +#else + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) != 0) +#endif + { + const char* error = SDL_GetError(); + Impl::error.init(Error::SDL_INIT, error); + return; // fatal + } + else + { + char name[128]; + SDL_VideoDriverName(name, sizeof(name)); + logInfo << "initialized SDL; using video driver `" + << name << "'" << std::endl; + } + + if (FE_Init() != 0) + { + const char* error = FE_GetError(); + Impl::error.init(Error::FASTEVENTS_INIT, error); + return; // fatal + } + + Impl::error.init(Error::NONE); + } +} + +Backend::Backend(const Backend& backend) +{ + ++Impl::retainCount; +} + +Backend::~Backend() +{ + if (--Impl::retainCount == 0) + { + FE_Quit(); + SDL_Quit(); + + Impl::error.reset(); + } +} + +bool Backend::isInitialized() +{ + return Impl::error.code() == Error::NONE; +} + +const Error& Backend::getError() +{ + return Impl::error; +} + + +} // namespace Mf + diff --git a/src/Moof/Backend.hh b/src/Moof/Backend.hh new file mode 100644 index 0000000..8209b06 --- /dev/null +++ b/src/Moof/Backend.hh @@ -0,0 +1,46 @@ + +/*] 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_BACKEND_HH_ +#define _MOOF_BACKEND_HH_ + + +namespace Mf { + + +class Error; + + +/* + * Some classes and subsystems require certain backend libraries to be + * initialized. This is the mechanism to accomplish that. Classes which + * rely on any backend libraries just need to instantiate this class as a + * member. Backend cleanup will occur automagically when there are no more + * instances. + */ + +class Backend +{ +public: + + Backend(); + Backend(const Backend& backend); + ~Backend(); + + static bool isInitialized(); + static const Error& getError(); +}; + + +} // namespace Mf + +#endif // _MOOF_BACKEND_HH_ + diff --git a/src/Moof/Contact.hh b/src/Moof/Contact.hh new file mode 100644 index 0000000..82e049d --- /dev/null +++ b/src/Moof/Contact.hh @@ -0,0 +1,40 @@ + +/*] 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_CONTACT_HH_ +#define _MOOF_CONTACT_HH_ + +#include + + +namespace Mf { + + +template +struct Contact +{ + typedef cml::vector< Scalar, cml::fixed > Vector; + + Vector point; // point of contact + Scalar distance; // distance of penetration + Vector normal; // normal of surface at point of contact + + bool operator < (const Contact& rhs) + { + return distance < rhs.distance; + } +}; + + +} // namespace Mf + +#endif // _MOOF_CONTACT_HH_ + diff --git a/src/Moof/Core.cc b/src/Moof/Core.cc deleted file mode 100644 index b659f98..0000000 --- a/src/Moof/Core.cc +++ /dev/null @@ -1,451 +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 -#include "fastevents.h" - -#include "Core.hh" -#include "Event.hh" -#include "Log.hh" -#include "Math.hh" -#include "ModalDialog.hh" -#include "Settings.hh" -#include "Timer.hh" -#include "Video.hh" - - -namespace Mf { - - -class Core::Impl -{ -public: - - Impl() : - mError(Error::NONE), - mTimestep(0.01), - mFramerate(0.02), - mShowFps(false) {} - - void init() - { - unsigned randomSeed; - if (settings.get("rngseed", randomSeed)) srand(randomSeed); - else srand(time(0)); - - Scalar timestep = 80.0; - settings.get("timestep", timestep); - mTimestep = 1.0 / timestep; - - Scalar framerate = 40.0; - settings.get("framerate", framerate); - mFramerate = 1.0 / framerate; - - mShowFps = false; - settings.get("showfps", mShowFps); - } - - - /** - * The main loop. This just calls dispatchEvents(), 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. - */ - - void run() - { - init(); - ASSERT(video && "cannot run core without a current video context"); - - Scalar totalTime = 0.0; - Scalar ticks = Timer::getTicks(); - - Scalar nextUpdate = ticks; - Scalar nextDraw = ticks; - Scalar nextSecond = ticks + SCALAR(1.0); - - mFps = 0; - int frameCount = 0; - - const Scalar timestep = mTimestep; - const Scalar framerate = mFramerate; - - const int MAX_FRAMESKIP = 15; - const Scalar inverseTimestep = SCALAR(1.0) / timestep; - - do - { - Timer::fireIfExpired(); // 1. fire timers - dispatchEvents(); // 2. dispatch events - - int i = 0; - while (nextUpdate < Timer::getTicks() && i < MAX_FRAMESKIP) - { - totalTime += timestep; - update(totalTime, timestep); // 3. update state - - nextUpdate += timestep; - ++i; - } - - if (nextDraw < (ticks = Timer::getTicks())) - { - draw((ticks + timestep - nextUpdate) * inverseTimestep); - video->swap(); // 4. draw state - - nextDraw += framerate; - ++frameCount; - - if (nextSecond < Timer::getTicks()) - { - mFps = frameCount; - frameCount = 0; - - if (mShowFps) logInfo << mFps << " fps" << std::endl; - - nextSecond += SCALAR(1.0); - } - } - - ticks = Timer::getTicks(); // 5. yield timeslice - if (ticks < nextUpdate && ticks < nextDraw) Timer::sleep(0.0); - } - while (!mStack.empty()); - - mDispatch.dispatch("engine.stopping"); - } - - - void dispatchEvents() - { - SDL_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 - logWarning("escape forced"); - exit(1); - } - break; - - case SDL_VIDEORESIZE: - video->resize(event.resize.w, event.resize.h); - break; - } - - handleEvent(event); - } - } - - - void update(Scalar t, Scalar dt) - { - for (mStackIt = mStack.begin(); mStackIt != mStack.end(); - ++mStackIt) - { - (*mStackIt)->update(t, dt); - } - } - - void draw(Scalar alpha) - { - // FIXME - this will crash if the layer being drawn pops itself - std::list::reverse_iterator it; - for (it = mStack.rbegin(); it != mStack.rend(); ++it) - { - (*it)->draw(alpha); - } - } - - void handleEvent(const Event& event) - { - for (mStackIt = mStack.begin(); mStackIt != mStack.end(); - ++mStackIt) - { - if ((*mStackIt)->handleEvent(event)) break; - } - } - - - void push(LayerP layer) - { - ASSERT(layer && "cannot push null layer"); - mStack.push_front(layer); - logInfo << "stack: " << mStack.size() - << " [pushed " << layer.get() << "]" << std::endl; - layer->addedToCore(); - } - - LayerP pop() - { - bool fixIt = false; - if (mStack.begin() == mStackIt) fixIt = true; - - LayerP layer = mStack.front(); - mStack.pop_front(); - logInfo << "stack: " << mStack.size() - << " [popped " << layer.get() << "]" << std::endl; - layer->removedFromCore(); - - if (fixIt) mStackIt = --mStack.begin(); - - return layer; - } - - LayerP pop(Layer* layer) - { - bool fixIt = false; - - std::list layers; - - std::list::iterator it; - for (it = mStack.begin(); it != mStack.end(); ++it) - { - layers.push_back(*it); - - if (it == mStackIt) fixIt = true; - - if ((*it).get() == layer) - { - ++it; - mStack.erase(mStack.begin(), it); - - for (it = layers.begin(); it != layers.end(); ++it) - { - (*it)->removedFromCore(); - logInfo << "stack: " << mStack.size() - << " [popped " << (*it).get() << "]" - << std::endl; - } - - if (fixIt) mStackIt = --mStack.begin(); - - return layers.back(); - } - } - - return LayerP(); - } - - void clear() - { - mStack.clear(); - mStackIt = mStack.begin(); - logInfo("stack: 0 [cleared]"); - } - - - Error mError; - - Dispatch mDispatch; - - std::list mStack; - std::list::iterator mStackIt; - - Scalar mTimestep; - Scalar mFramerate; - - int mFps; - bool mShowFps; -}; - - -Core::Core() : - // pass through - mImpl(new Core::Impl) {} - - -void Core::init() -{ - // pass through - mImpl->init(); -} - - -int Core::getFps() const -{ - return mImpl->mFps; -} - - -void Core::push(LayerP layer) -{ - // pass through - mImpl->push(layer); -} - -LayerP Core::pop() -{ - // pass through - return mImpl->pop(); -} - -LayerP Core::pop(Layer* layer) -{ - // pass through - return mImpl->pop(layer); -} - -void Core::clear() -{ - // pass through - mImpl->clear(); -} - -int Core::getSize() const -{ - return mImpl->mStack.size(); -} - - -void Core::run() -{ - // pass through - return mImpl->run(); -} - - -Dispatch::Handler Core::addHandler(const std::string& event, - const Dispatch::Function& callback) -{ - return mImpl->mDispatch.addHandler(event, callback); -} - -Dispatch::Handler Core::addHandler(const std::string& event, - const Dispatch::Function& callback, - Dispatch::Handler handler) -{ - return mImpl->mDispatch.addHandler(event, callback, handler); -} - -void Core::dispatch(const std::string& event, - const Dispatch::Message* message) -{ - mImpl->mDispatch.dispatch(event, message); -} - - -Core core; - - -class Backend_; -typedef boost::shared_ptr BackendP; - -class Backend_ -{ -public: - - Backend_() - { -#if defined(_WIN32) || defined(__WIN32__) - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) -#else - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) != 0) -#endif - { - const char* error = SDL_GetError(); - gError.init(Error::SDL_INIT, error); - return; // fatal - } - else - { - char name[128]; - SDL_VideoDriverName(name, sizeof(name)); - logInfo << "initialized SDL; using video driver `" - << name << "'" << std::endl; - } - - if (FE_Init() != 0) - { - const char* error = FE_GetError(); - gError.init(Error::FASTEVENTS_INIT, error); - return; // fatal - } - - gError.init(Error::NONE); - } - - ~Backend_() - { - FE_Quit(); - SDL_Quit(); - } - - static void retain() - { - if (gRetainCount++ == 0) - { - gInstance = BackendP(new Backend_); - } - } - - static void release() - { - if (--gRetainCount == 0) - { - gInstance.reset(); - gError.reset(); - } - } - - static const Error& getError() - { - return gError; - } - -private: - - static Error gError; - static int gRetainCount; - static BackendP gInstance; -}; - -Error Backend_::gError(Error::UNINITIALIZED); -int Backend_::gRetainCount = 0; -BackendP Backend_::gInstance; - - -Backend::Backend() -{ - Backend_::retain(); -} - -Backend::~Backend() -{ - Backend_::release(); -} - -bool Backend::isInitialized() -{ - return getError().code() == Error::NONE; -} - -const Error& Backend::getError() -{ - return Backend_::getError(); -} - - -} // namespace Mf - diff --git a/src/Moof/Core.hh b/src/Moof/Core.hh deleted file mode 100644 index eaa98b4..0000000 --- a/src/Moof/Core.hh +++ /dev/null @@ -1,98 +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_CORE_HH_ -#define _MOOF_CORE_HH_ - -#include - -#include - -#include -#include -#include - - -namespace Mf { - - -/** - * 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 Core -{ -public: - - Core(); - - // loads settings: rngseed, timestep, framerate, showfps - void init(); - - int getFps() const; - - void push(LayerP layer); // push a layer onto the top - LayerP pop(); // pop the top layer - LayerP pop(Layer* layer); // pops a specific layer and layers above it - void clear(); // remove all layers (the core will stop) - - int getSize() const; // get the size of the stack - - // set this machine in motion - void run(); - - Dispatch::Handler addHandler(const std::string& event, - const Dispatch::Function& callback); - Dispatch::Handler addHandler(const std::string& event, - const Dispatch::Function& callback, - Dispatch::Handler handler); - - void dispatch(const std::string& event, - const Dispatch::Message* message = 0); - -private: - - class Impl; - boost::shared_ptr mImpl; -}; - -extern Core core; - - -/* - * Some classes and subsystems require certain backend libraries to be - * initialized. This is the mechanism to accomplish that. Classes which - * rely on any backend libraries just need to instantiate this class as a - * member. Backend cleanup will occur automagically when there are no more - * instances. - */ - -class Backend -{ -public: - - Backend(); - ~Backend(); - - static bool isInitialized(); - static const Error& getError(); -}; - - -} // namespace Mf - -#endif // _MOOF_CORE_HH_ - diff --git a/src/Moof/Dispatch.cc b/src/Moof/Dispatch.cc index 52f28f8..83fecae 100644 --- a/src/Moof/Dispatch.cc +++ b/src/Moof/Dispatch.cc @@ -21,46 +21,45 @@ class Dispatch::Impl { public: - Impl() : + Impl(Dispatch* dispatch) : + mDispatch(dispatch), mId(0) {} - Dispatch::Handler getNewHandler() + Dispatch::Handle getNewHandle() { ++mId; - //return Dispatch::Handler(this, mId); - Dispatch::Handler handler(this, mId); - return handler; + Dispatch::Handle handle(mDispatch->mImpl, mId); + return handle; } typedef std::pair Callback; typedef std::multimap CallbackLookup; - typedef CallbackLookup::iterator CallbackIter; + typedef CallbackLookup::iterator CallbackIt; - typedef std::multimap HandlerLookup; - typedef HandlerLookup::iterator HandlerIter; + typedef std::multimap HandleLookup; + typedef HandleLookup::iterator HandleIt; - inline Handler addHandler(const std::string& event, - const Function& callback, Handler handler) + inline Handle addTarget(const std::string& event, + const Function& callback, Handle handle) { mCallbacks.insert(std::make_pair(event, - std::make_pair(handler.getId(), callback))); - mHandlers.insert(std::make_pair(handler.getId(), event)); + std::make_pair(handle.getId(), callback))); + mHandles.insert(std::make_pair(handle.getId(), event)); - return handler; + return handle; } - inline void removeHandler(unsigned id) + inline void removeTarget(unsigned id) { - std::pair - matching(mHandlers.equal_range(id)); + std::pair matching(mHandles.equal_range(id)); - for (HandlerIter it = matching.first; it != matching.second; ++it) + for (HandleIt it = matching.first; it != matching.second; ++it) { - CallbackIter first = mCallbacks.find((*it).second); - CallbackIter last = mCallbacks.end(); + CallbackIt first = mCallbacks.find((*it).second); + CallbackIt last = mCallbacks.end(); - for (CallbackIter jt = first; jt != last; ++jt) + for (CallbackIt jt = first; jt != last; ++jt) { if ((*jt).second.first == id) { @@ -70,16 +69,15 @@ public: } } - mHandlers.erase(id); + mHandles.erase(id); } void dispatch(const std::string& event, const Message* message) { - std::pair + std::pair callbacks(mCallbacks.equal_range(event)); - for (CallbackIter it = callbacks.first; it != callbacks.second; - ++it) + for (CallbackIt it = callbacks.first; it != callbacks.second; ++it) { Function callback = (*it).second.second; callback(message); @@ -87,45 +85,49 @@ public: } + Dispatch* mDispatch; + unsigned mId; CallbackLookup mCallbacks; - HandlerLookup mHandlers; + HandleLookup mHandles; }; -Dispatch::Handler::~Handler() +void Dispatch::Handle::clear() { - if (mId) + boost::shared_ptr dispatch; + if (mId && (dispatch = mDispatch.lock())) { - mDispatch->removeHandler(mId); + dispatch->removeTarget(mId); + mId = 0; } } Dispatch::Dispatch() : - mImpl(new Dispatch::Impl) {} + mImpl(new Dispatch::Impl(this)) {} -Dispatch::Handler Dispatch::addHandler(const std::string& event, - const Function& callback) +Dispatch::Handle Dispatch::addTarget(const std::string& event, + const Function& callback) { - return addHandler(event, callback, mImpl->getNewHandler()); + return addTarget(event, callback, mImpl->getNewHandle()); } -Dispatch::Handler Dispatch::addHandler(const std::string& event, - const Function& callback, - Handler handler) +Dispatch::Handle Dispatch::addTarget(const std::string& event, + const Function& callback, + Handle handle) { // pass through - return mImpl->addHandler(event, callback, handler); + return mImpl->addTarget(event, callback, handle); } -void Dispatch::removeHandler(unsigned id) +void Dispatch::removeTarget(unsigned id) { // pass through - return mImpl->removeHandler(id); + return mImpl->removeTarget(id); } @@ -136,5 +138,12 @@ void Dispatch::dispatch(const std::string& event, const Message* message) } +Dispatch& Dispatch::global() +{ + static Dispatch dispatch; + return dispatch; +} + + } // namespace Mf diff --git a/src/Moof/Dispatch.hh b/src/Moof/Dispatch.hh index fd328fe..4911c12 100644 --- a/src/Moof/Dispatch.hh +++ b/src/Moof/Dispatch.hh @@ -17,6 +17,7 @@ #include #include #include +#include namespace Mf { @@ -31,7 +32,7 @@ class Dispatch class Impl; boost::shared_ptr mImpl; - void removeHandler(unsigned id); + void removeTarget(unsigned id); public: @@ -46,32 +47,35 @@ public: }; - class Handler + class Handle { public: - Handler() : - mDispatch(0), + Handle() : mId(0) {} - Handler(Impl* dispatch, unsigned id) : + Handle(boost::weak_ptr dispatch, unsigned id) : mDispatch(dispatch), mId(id) {} - Handler(const Handler& handler) : - mDispatch(handler.mDispatch), - mId(handler.mId) + Handle(const Handle& handle) : + mDispatch(handle.mDispatch), + mId(handle.mId) { - handler.mId = 0; + handle.mId = 0; } - ~Handler(); + ~Handle() + { + clear(); + } - Handler& operator = (const Handler& handler) + Handle& operator = (const Handle& handle) { - mDispatch = handler.mDispatch; - mId = handler.mId; - handler.mId = 0; + clear(); + mDispatch = handle.mDispatch; + mId = handle.mId; + handle.mId = 0; return *this; } @@ -79,12 +83,13 @@ public: { return mId; } + + void clear(); private: - Impl* mDispatch; - mutable unsigned mId; - + boost::weak_ptr mDispatch; + mutable unsigned mId; }; typedef boost::function Function; @@ -92,11 +97,13 @@ public: Dispatch(); - Handler addHandler(const std::string& event, const Function& callback); - Handler addHandler(const std::string& event, const Function& callback, - Handler handler); + Handle addTarget(const std::string& event, const Function& callback); + Handle addTarget(const std::string& event, const Function& callback, + Handle handle); void dispatch(const std::string& event, const Message* message = 0); + + static Dispatch& global(); }; diff --git a/src/Moof/Image.cc b/src/Moof/Image.cc index c5566d5..54e9972 100644 --- a/src/Moof/Image.cc +++ b/src/Moof/Image.cc @@ -17,7 +17,7 @@ #include #include -#include "Core.hh" +#include "Backend.hh" #include "Error.hh" #include "Image.hh" #include "Log.hh" diff --git a/src/Moof/Layer.hh b/src/Moof/Layer.hh deleted file mode 100644 index 8bbb94b..0000000 --- a/src/Moof/Layer.hh +++ /dev/null @@ -1,47 +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_LAYER_HH_ -#define _MOOF_LAYER_HH_ - -#include - -#include -#include - - -namespace Mf { - - -class Layer -{ -public: - - virtual ~Layer() {} - - virtual void addedToCore() {} - virtual void removedFromCore() {} - - virtual void update(Scalar t, Scalar dt) {} - virtual void draw(Scalar alpha) const {} - virtual bool handleEvent(const Event& event) - { - return false; - } -}; - -typedef boost::shared_ptr LayerP; - - -} // namespace Mf - -#endif // _MOOF_LAYER_HH_ - diff --git a/src/Moof/Line.hh b/src/Moof/Line.hh index f8a2b66..679e564 100644 --- a/src/Moof/Line.hh +++ b/src/Moof/Line.hh @@ -12,11 +12,14 @@ #ifndef _MOOF_LINE_HH_ #define _MOOF_LINE_HH_ +#include #include +#include #include #include #include #include +#include #include @@ -38,8 +41,131 @@ struct Line : public Drawable, public Shape a(point1), b(point2) {} + + Vector getDirection() const + { + return b - a; + } + + Scalar getLength() const + { + return getDirection().length(); + } + + + bool intersect(const Line& other, Contact& hit) const + { + Scalar d = (other.b[1] - other.a[1]) * (b[0] - a[0]) - + (other.b[0] - other.a[0]) * (b[1] - a[1]); + + if (d == SCALAR(0.0)) return false; // lines are parallel + // ignoring the (somewhat remote) possibility of coincidence + + Scalar m = ((other.b[0] - other.a[0]) * (a[1] - other.a[1]) - + (other.b[1] - other.a[1]) * (a[0] - other.a[0])) / d; + + Scalar n = ((b[0] - a[0]) * (b[1] - other.a[1]) - + (b[1] - a[1]) * (b[0] - other.a[0])) / d; + + if (m < SCALAR(0.0) || m > SCALAR(1.0) || // not intersecting + n < SCALAR(0.0) || n > SCALAR(1.0)) return false; + + Vector2 tangent = b - a; + Vector2 normal = cml::perp(tangent).normalize(); + + if (cml::dot(normal, other.a - other.b) < SCALAR(0.0)) + { + normal = -normal; + } + + hit.point = a + m * tangent; + hit.normal = normal; + hit.distance = (other.b - hit.point).length(); + + return true; + } + + bool intersect(const Sphere& other, Contact& hit) const + { + Vector surface = b - a; + Vector toPoint = other.point - a; + + Scalar surfaceLength = surface.length(); + surface.normalize(); + + Scalar projection = cml::dot(surface, toPoint); + + if (projection < SCALAR(0.0) || projection > surfaceLength) + { + // try endpoints + + if (other.intersect(a, hit)) + { + hit.normal = -hit.normal; + hit.point = a; + return true; + } + else if (other.intersect(b, hit)) + { + hit.normal = -hit.normal; + hit.point = b; + return true; + } + + return false; + } + + Vector point = a + surface * projection; + Vector normal = other.point - point; + + Scalar distance = normal.length(); + + if (distance > other.radius) false; // not intersecting + + normal.normalize(); + + hit.distance = other.radius - distance; + hit.point = point; + hit.normal = normal; + + return true; + } + + bool intersectRay(const Ray<2>& ray, Ray<2>::Contact& hit) const { + Vector2 v1 = a - ray.point; + Scalar a1 = cml::signed_angle_2D(v1, b - ray.point); + + //logWarning << "angle:::::::::: " << a1 << std::endl; + + if (a1 == Constants::pi()) + { + hit.distance = 5.4321; + return true; + } + else if (a1 == SCALAR(0.0)) + { + hit.distance = 99999.0; + return true; + } + + Scalar a2 = cml::signed_angle_2D(v1, ray.direction); + + if (a2 < SCALAR(0.0) || a2 > a1) return false; + + //hit.distance = 1.23456; + //hit.normal = Vector2(0.0, 0.0); + + Vector2 n = (b - a).normalize(); + Scalar z = cml::dot(ray.point - a, n); + Vector2 p = a + n * z; + hit.distance = (ray.point - p).length(); + hit.normal = cml::perp(a - b); + return true; + + + /* // solve: Cx + r*Dx = Ax + s(Bx - Ax) // Cy + r*Dy = Ay + s(By - Ay) // where: 0 <= s <= 1 if intersection @@ -87,8 +213,10 @@ struct Line : public Drawable, public Shape if (cml::dot(a - ray.point, normal) < 0) hit.normal = normal; else hit.normal = -normal; return true; + */ } + void draw(Scalar alpha = 0.0) const { Mf::Texture::resetBind(); @@ -135,6 +263,14 @@ typedef Polygon<2,3> Triangle2; typedef Polygon<3,3> Triangle3; +template +bool intersect(const Line& line, const Sphere& sphere, + Contact& hit) +{ + return false; +} + + } // namespace Mf #endif // _MOOF_LINE_HH_ diff --git a/src/Moof/ModalDialog.hh b/src/Moof/ModalDialog.hh index 8bb6741..d56d8ea 100644 --- a/src/Moof/ModalDialog.hh +++ b/src/Moof/ModalDialog.hh @@ -18,7 +18,7 @@ #include "../config.h" #endif -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) #include #elif defined(__APPLE__) && defined(__MACH__) #include @@ -57,6 +57,17 @@ struct ModalDialog std::string text2; + + ModalDialog(Type pType = INFO, + const std::string& pTitle = "", + const std::string& pText1 = "", + const std::string& pText2 = "") : + title(pTitle), + type(pType), + text1(pText1), + text2(pText2) {} + + void run() const { switch (type) @@ -75,7 +86,7 @@ struct ModalDialog break; } -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) int iconType; switch (type) diff --git a/src/Moof/Resource.cc b/src/Moof/Resource.cc index ca127a9..b04acd7 100644 --- a/src/Moof/Resource.cc +++ b/src/Moof/Resource.cc @@ -48,7 +48,7 @@ void Resource::addSearchPaths(const std::vector& path) onePath += '/'; } -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) boost::replace_all(onePath, "/", "\\"); #endif @@ -64,7 +64,7 @@ std::string Resource::getPath(const std::string& name) std::string path(name); -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) boost::replace_all(path, "/", "\\"); #endif diff --git a/src/Moof/Settings.cc b/src/Moof/Settings.cc index 94845c2..bc503c5 100644 --- a/src/Moof/Settings.cc +++ b/src/Moof/Settings.cc @@ -45,7 +45,7 @@ void Settings::loadFromFiles(const std::vector& path) std::vector copy(path); std::vector::iterator it; -#if defined(_WIN32) || defined(__WIN32__) +#if defined(_WIN32) char* homeDrive = getenv("HOMEDRIVE"); char* homePath = getenv("HOMEPATH"); std::string home(homeDrive ? homeDrive : ""); @@ -96,8 +96,5 @@ void Settings::save() const } -Settings settings; // global instance - - } // namepsace Mf diff --git a/src/Moof/Settings.hh b/src/Moof/Settings.hh index f7503dd..42ef70c 100644 --- a/src/Moof/Settings.hh +++ b/src/Moof/Settings.hh @@ -33,10 +33,13 @@ class Settings { public: - Settings() + Settings(int argc, char* argv[], const std::string& path) { mScript.importBaseLibrary(); importLogFunctions(mScript); + + parseArgs(argc, argv); + loadFromFiles(path); } ~Settings(); @@ -93,9 +96,6 @@ bool Settings::get(const std::string& key, T& value) const } -extern Settings settings; - - } // namepsace Mf #endif // _MOOF_SETTINGS_HH_ diff --git a/src/Moof/Shape.hh b/src/Moof/Shape.hh index c059d46..d21e84d 100644 --- a/src/Moof/Shape.hh +++ b/src/Moof/Shape.hh @@ -53,13 +53,17 @@ public: * returned if there is no contact. */ virtual bool intersectRay(const Ray& ray, - typename Ray::Contact& hit) + typename Ray::Contact& hit) const { return false; } }; +typedef Shape<2> Shape2; +typedef Shape<3> Shape3; + + } // namespace Mf #endif // _MOOF_SHAPE_HH_ diff --git a/src/Moof/Sphere.hh b/src/Moof/Sphere.hh index d42bfd8..f528554 100644 --- a/src/Moof/Sphere.hh +++ b/src/Moof/Sphere.hh @@ -12,6 +12,7 @@ #ifndef _MOOF_SPHERE_HH_ #define _MOOF_SPHERE_HH_ +#include #include #include #include @@ -28,24 +29,22 @@ namespace Mf { * A round object. */ + template struct Sphere : public Cullable, public Drawable, public Shape { typedef cml::vector< Scalar, cml::fixed > Vector; - // (solution - point)^2 - radius^2 = 0 Vector point; Scalar radius; + Sphere() {} Sphere(const Vector& p, Scalar r) : point(p), radius(r) {} - //Sphere(Scalar x, Scalar y, Scalar z, Scalar r) : - //point(x, y, z), - //radius(r) {} void init(const Vector& p, Scalar r) { @@ -59,9 +58,55 @@ struct Sphere : public Cullable, public Drawable, public Shape radius = (o - p).length(); } + //void encloseVertices(const Vector vertices[], unsigned count); + + //void draw(Scalar alpha = 0.0) const; + //bool isVisible(const Frustum& frustum) const; + + void encloseVertices(const Vector vertices[], unsigned count) + { + // TODO + } + + void draw(Scalar alpha = 0.0) const; + + bool isVisible(const Frustum& frustum) const + { + return true; + } + + + bool intersect(const Sphere& sphere, Contact& hit) const + { + Vector n = sphere.point - point; + Scalar distance = n.length(); + Scalar limit = radius + sphere.radius; + + if (distance > limit) return false; + + hit.normal = n.normalize(); + hit.distance = limit - distance; + hit.point = hit.normal * radius; + + return true; + } + + bool intersect(const Vector& point2, Contact& hit) const + { + Vector n = point2 - point; + Scalar distance = n.length(); + + if (distance > radius) return false; + + hit.normal = n.normalize(); + hit.distance = radius - distance; + hit.point = point2; + + return true; + } // a ray inside the sphere will not intersect on its way out - bool intersectRay(const Ray& ray, typename Ray::Contact& hit) + bool intersect(const Ray& ray, typename Ray::Contact& hit) const { Vector b = point - ray.point; Scalar z = cml::dot(b, ray.direction); @@ -83,37 +128,6 @@ struct Sphere : public Cullable, public Drawable, public Shape hit.normal = surfacePoint - point; return true; } - - - //void encloseVertices(const Vector vertices[], unsigned count); - - //void draw(Scalar alpha = 0.0) const; - //bool isVisible(const Frustum& frustum) const; - - void encloseVertices(const Vector vertices[], unsigned count) - { - // TODO - } - - void draw(Scalar alpha = 0.0) const; - //{ - //GLUquadricObj* sphereObj = gluNewQuadric(); - //gluQuadricDrawStyle(sphereObj, GLU_LINE); - - //glPushMatrix(); - - //glTranslate(point); - //gluSphere(sphereObj, GLdouble(radius), 16, 16); - - //glPopMatrix(); - - //gluDeleteQuadric(sphereObj); - //} - - bool isVisible(const Frustum& frustum) const - { - return true; - } }; diff --git a/src/Moof/Texture.cc b/src/Moof/Texture.cc index 48e6e1b..7d82e2d 100644 --- a/src/Moof/Texture.cc +++ b/src/Moof/Texture.cc @@ -121,12 +121,13 @@ public: mObject(0) { // make sure we have a video context - ASSERT(video && - "cannot load textures without a current video context"); + Video* video = Video::current(); + ASSERT(video && "should have a video context set"); // we want to know when the GL context is recreated - mDispatchHandler = core.addHandler("video.newcontext", - boost::bind(&Impl::contextRecreated, this)); + Dispatch& dispatch = Dispatch::global(); + mNewContextDispatch = dispatch.addTarget("video.newcontext", + boost::bind(&Impl::contextRecreated, this)); } ~Impl() @@ -388,7 +389,7 @@ public: GLuint mObject; ///< GL texture handle. static GLuint gObject; ///< Global GL texture handle. - Dispatch::Handler mDispatchHandler; + Dispatch::Handle mNewContextDispatch; }; GLuint Texture::Impl::gObject = 0; diff --git a/src/Moof/Transition.hh b/src/Moof/Transition.hh index d65d82d..194caf5 100644 --- a/src/Moof/Transition.hh +++ b/src/Moof/Transition.hh @@ -9,6 +9,7 @@ * **************************************************************************/ +#define _MOOF_TRANSITION_HH_ #ifndef _MOOF_TRANSITION_HH_ #define _MOOF_TRANSITION_HH_ @@ -49,17 +50,17 @@ public: } - void removedFromCore() + void removedFromCore(Core& core) { if (mTo) core.push(mTo); } - void update(Scalar t, Scalar dt) + void update(Core& core, Scalar t, Scalar dt) { mInterp.update(t, dt); - if (mFrom) mFrom->update(t, dt); - if (mTo) mTo->update(t, dt); + if (mFrom) mFrom->update(core, t, dt); + if (mTo) mTo->update(core, t, dt); if (mInterp.isDone()) { @@ -101,7 +102,7 @@ public: glPopMatrix(); } - void draw(Scalar alpha) const + void draw(Core& core, Scalar alpha) const { Scalar a = mInterp.getState(alpha); logInfo << "transition state: " << a << std::endl; @@ -113,7 +114,7 @@ public: glPushMatrix(); glLoadIdentity(); glRotate(180.0 * a, 0.0, 1.0, 0.0); - mFrom->draw(alpha); + mFrom->draw(core, alpha); glPopMatrix(); } //drawFade(a); @@ -123,21 +124,21 @@ public: glPushMatrix(); glLoadIdentity(); glRotate(180.0 * (1.0 - a), 0.0, 1.0, 0.0); - mTo->draw(alpha); + mTo->draw(core, alpha); glPopMatrix(); } //drawFade(1.0 - a); } - bool handleEvent(const Event& event) + bool handleEvent(Core& core, const Event& event) { if (mTo) { - return mTo->handleEvent(event); + return mTo->handleEvent(core, event); } else if (mFrom) { - return mFrom->handleEvent(event); + return mFrom->handleEvent(core, event); } return false; } diff --git a/src/Moof/Video.cc b/src/Moof/Video.cc index 9f62586..195f413 100644 --- a/src/Moof/Video.cc +++ b/src/Moof/Video.cc @@ -9,7 +9,6 @@ * **************************************************************************/ -#include "Dispatch.hh" #include "Error.hh" #include "Image.hh" #include "Log.hh" @@ -20,25 +19,19 @@ namespace Mf { -Video::Video() +Video::Video() : + mDispatch(Dispatch::global()) { init(); } Video::Video(const Attributes& attribs) : - mAttribs(attribs) + mAttribs(attribs), + mDispatch(Dispatch::global()) { init(); } -Video::Video(const std::string& caption, const std::string& icon) -{ - mAttribs.caption = caption; - mAttribs.icon = icon; - - init(); -} - void Video::init() { Error error = Backend::getError(); @@ -56,7 +49,7 @@ void Video::init() setCursorGrab(mAttribs.cursorGrab); setVideoMode(mAttribs.mode); - video = this; + if (!gCurrentVideo) makeCurrent(); } void Video::recreateContext() @@ -109,11 +102,11 @@ Video::~Video() { SDL_FreeSurface(mContext); - if (video == this) video = 0; + if (gCurrentVideo == this) gCurrentVideo = 0; } -void Video::setVideoMode(const long mode[3]) +void Video::setVideoMode(const int mode[3]) { if (mode != mAttribs.mode || !mContext) { @@ -130,7 +123,7 @@ void Video::setVideoMode(const long mode[3]) #if !defined(linux) && !defined(__linux) && !defined(__linux__) logInfo("video context recreated"); - core.dispatch("video.newcontext"); + mDispatch.dispatch("video.newcontext"); #endif } else Error(Error::SDL_VIDEOMODE).raise(); @@ -145,7 +138,7 @@ Video::Attributes Video::getAttributes() const void Video::resize(int width, int height) { - long mode[] = {width, height, mAttribs.mode[2]}; + int mode[] = {width, height, mAttribs.mode[2]}; setVideoMode(mode); } @@ -290,35 +283,28 @@ int Video::getHeight() const } +void Video::makeCurrent() const +{ + gCurrentVideo = const_cast(this); +} + + +void Video::setDispatch(Dispatch& dispatch) +{ + mDispatch = dispatch; +} + + Video::Attributes::Attributes() { - // set some sane GL and window defaults (see SDL_video.c:217) - colorBuffer[0] = 3; - colorBuffer[1] = 3; - colorBuffer[2] = 2; - colorBuffer[3] = 0; - frameBuffer = 0; - doubleBuffer = true; - depthBuffer = 16; - stencilBuffer = 0; - accumBuffer[0] = 0; - accumBuffer[1] = 0; - accumBuffer[2] = 0; - accumBuffer[3] = 0; - stereo = false; - multisampleBuffers = 0; - multisampleSamples = 0; - swapControl = false; - hardwareOnly = false; - mode[0] = 640; - mode[1] = 480; - mode[2] = 0; - fullscreen = false; - resizable = false; - cursorVisible = true; - cursorGrab = false; + init(); +} - std::vector colors; +Video::Attributes::Attributes(const Settings& settings) +{ + init(); + + std::vector colors; settings.get("colorbuffers", colors); if (colors.size() > 0) colorBuffer[0] = colors[0]; if (colors.size() > 1) colorBuffer[1] = colors[1]; @@ -330,7 +316,7 @@ Video::Attributes::Attributes() settings.get("depthbuffer", depthBuffer); settings.get("stencilbuffer", stencilBuffer); - std::vector accum; + std::vector accum; settings.get("accumbuffers", accum); if (accum.size() > 0) accumBuffer[0] = accum[0]; if (accum.size() > 1) accumBuffer[1] = accum[1]; @@ -354,7 +340,7 @@ Video::Attributes::Attributes() settings.get("showcursor", cursorVisible); settings.get("grab", cursorGrab); - std::vector dimensions; + std::vector dimensions; settings.get("videomode", dimensions); if (dimensions.size() > 1) { @@ -388,8 +374,37 @@ Video::Attributes::Attributes() if (dimensions.size() > 2) mode[2] = dimensions[2]; } +void Video::Attributes::init() +{ + // set some sane GL and window defaults (see SDL_video.c:217) + colorBuffer[0] = 3; + colorBuffer[1] = 3; + colorBuffer[2] = 2; + colorBuffer[3] = 0; + frameBuffer = 0; + doubleBuffer = true; + depthBuffer = 16; + stencilBuffer = 0; + accumBuffer[0] = 0; + accumBuffer[1] = 0; + accumBuffer[2] = 0; + accumBuffer[3] = 0; + stereo = false; + multisampleBuffers = 0; + multisampleSamples = 0; + swapControl = false; + hardwareOnly = false; + mode[0] = 640; + mode[1] = 480; + mode[2] = 0; + fullscreen = false; + resizable = false; + cursorVisible = true; + cursorGrab = false; +} + -Video* video = 0; // most recently instantiated instance +Video* Video::gCurrentVideo = 0; // most recently instantiated instance } // namespace Mf diff --git a/src/Moof/Video.hh b/src/Moof/Video.hh index 9b1a092..d20ce4e 100644 --- a/src/Moof/Video.hh +++ b/src/Moof/Video.hh @@ -17,11 +17,13 @@ #include #include -#include +#include +#include namespace Mf { +class Settings; class Video; typedef boost::shared_ptr