AC_SEARCH_LIBS([IMG_Load], [SDL_image],,
[AC_MSG_ERROR([libSDL_image is required])])
+AC_SEARCH_LIBS([Sound_Init], [SDL_sound],,
+ [AC_MSG_ERROR([libSDL_sound is required])])
+
AC_SEARCH_LIBS([glBegin], [GL],,
[AC_MSG_ERROR([libGL is required])])
AC_SEARCH_LIBS([gluPerspective], [GLU],,
[AC_MSG_ERROR([libGLU is required])])
+AC_SEARCH_LIBS([alGenBuffers], [openal],,
+ [AC_MSG_ERROR([libopenal is required])])
+
+AC_SEARCH_LIBS([alutInit], [alut],,
+ [AC_MSG_ERROR([libalut is required])])
+
AC_SEARCH_LIBS([clock_gettime], [rt],
[AC_DEFINE([HAVE_CLOCK_GETTIME], 1,
[Define to 1 if you have the 'clock_gettime' function.])])
# Print a friendly little message.
#
-echo "====================================="
+echo "======================================"
echo " Configuration complete!"
echo ""
echo " To finish the installation, execute:"
echo " make"
echo " make install"
-echo "====================================="
+echo "======================================"
{
"playfield_bounds": [0, 0, -100, 1280, 500, 100],
- "maximum_bounds": [-160, 0, -192, 1440, 512, 224],
+ "maximum_bounds": [-160, 0, -192, 1440, 480, 224],
"instructions":
[
"translate", [-0.3, -0.17, -900],
"scale", [3200, 1600, 1],
"texture", "BackgroundFar",
- "billboard",
- {
- "fog": false
- },
+ "billboard", null,
+
"translate", [0, 0, 300],
"texture", "BackgroundNear",
"billboard",
{
- "blend": true,
- "fog": false
+ "blend": true
},
/* Trees */
# $Header: $
EAPI=2
+
inherit autotools eutils games
DESCRIPTION="Alien-smashing action game"
HOMEPAGE="http://www.dogcows.com/"
-SRC_URI="http://www.dogcows.com/yoink/${P}.tar.bz2"
+SRC_URI="http://www.dogcows.com/yoink/${P}.tar.bz2
+ http://eng.utah.edu/~mcgarvey/yoink/${P}.tar.bz2"
LICENSE="BSD-2"
SLOT="0"
-KEYWORDS="~amd64 ~ppc ~x86"
+KEYWORDS="amd64 ~ppc x86"
IUSE="debug profile"
RDEPEND="media-libs/libsdl[opengl]
media-libs/sdl-image[png]
- virtual/opengl"
+ virtual/opengl
+ media-libs/sdl-sound[mikmod, vorbis]
+ media-libs/openal"
DEPEND="${RDEPEND}
+ dev-libs/boost
dev-util/pkgconfig"
+RESTRICT="mirror"
+
src_prepare() {
sed -i \
-e "s/-Werror//g" \
-e "/man/d" \
doc/Makefile.am \
|| die "sed failed"
+
eautoreconf
}
#include "Character.hh"
+#include <iostream>
Character::Character(const std::string& name) :
- tilemap(name),
- animation(name) {}
+ tilemap_(name),
+ animation_(name)
+{
+ current.mass = 1.0;
+ current.inverseMass = 1.0 / current.mass;
+
+ current.force = Mf::Vector2(0.0, -120.0);
+
+ current.position = Mf::Vector2(64.0, 64.0);
+ current.momentum = Mf::Vector2(0.0, 0.0);
+ current.recalculate();
+
+ previous = current;
+
+ updateContainers();
+}
Character::~Character()
{
}
-void Character::draw(Mf::Scalar alpha) const {}
+void Character::update(Mf::Scalar t, Mf::Scalar dt)
+{
+ previous = current;
+ Mf::integrate<State,Derivative>(current, t, dt);
+
+ animation_.update(t, dt);
+
+ updateContainers();
+}
+
+void Character::updateContainers()
+{
+ aabb_.init(Mf::Vector3(current.position[0]-16.0, current.position[1]-16.0, z),
+ Mf::Vector3(current.position[0]+16.0, current.position[1]+16.0, z));
+ sphere_.point = Mf::Vector3(current.position[0], current.position[1], z);
+ sphere_.radius = (aabb_.min - sphere_.point).length();
+}
+
+void Character::handleEvent(const Mf::Event& event)
+{
+ // really just for heroine...
+
+ Mf::Scalar force = 500.0;
+
+ Mf::Vector2 left = Mf::Vector2(-force, 0.0);
+ Mf::Vector2 right = Mf::Vector2(force, 0.0);
+ Mf::Vector2 down = Mf::Vector2(0.0, -force);
+ Mf::Vector2 up = Mf::Vector2(0.0, force);
+
+ switch (event.type)
+ {
+ case SDL_KEYDOWN:
+ if (event.key.keysym.sym == SDLK_a)
+ {
+ current.force += left;
+ }
+ else if (event.key.keysym.sym == SDLK_d)
+ {
+ current.force += right;
+ }
+ else if (event.key.keysym.sym == SDLK_s)
+ {
+ current.force += down;
+ }
+ else if (event.key.keysym.sym == SDLK_w)
+ {
+ current.force += up;
+ }
+ break;
+
+ case SDL_KEYUP:
+ if (event.key.keysym.sym == SDLK_a)
+ {
+ current.force -= left;
+ }
+ else if (event.key.keysym.sym == SDLK_d)
+ {
+ current.force -= right;
+ }
+ else if (event.key.keysym.sym == SDLK_s)
+ {
+ current.force -= down;
+ }
+ else if (event.key.keysym.sym == SDLK_w)
+ {
+ current.force -= up;
+ }
+ break;
+ }
+
+ std::cout << "current force: " << current.force << std::endl;
+}
+
+
+void Character::draw(Mf::Scalar alpha) const
+{
+ State state = cml::lerp(previous, current, alpha);
+
+ glColor3f(1.0f, 1.0f, 1.0f);
+ tilemap_.bind();
+
+ Mf::Tilemap::Index frame = animation_.getFrame();
+
+ Mf::Scalar coords[8];
+ tilemap_.getTileCoords(frame, coords);
+
+ Mf::Scalar s = 16.0;
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(coords[0], coords[1]);
+ glVertex3(state.position[0]-s, state.position[1]-s, z);
+ glTexCoord2f(coords[2], coords[3]);
+ glVertex3(state.position[0]+s, state.position[1]-s, z);
+ glTexCoord2f(coords[4], coords[5]);
+ glVertex3(state.position[0]+s, state.position[1]+s, z);
+ glTexCoord2f(coords[6], coords[7]);
+ glVertex3(state.position[0]-s, state.position[1]+s, z);
+ glEnd();
+}
+
Mf::Tilemap& Character::getTilemap()
{
- return tilemap;
+ return tilemap_;
}
Mf::Animation& Character::getAnimation()
{
- return animation;
+ return animation_;
}
#ifndef _CHARACTER_HH_
#define _CHARACTER_HH_
+#include <boost/shared_ptr.hpp>
+
#include <Moof/Animation.hh>
-#include <Moof/Drawable.hh>
-#include <Moof/Resource.hh>
+#include <Moof/Entity.hh>
+#include <Moof/Event.hh>
+#include <Moof/Math.hh>
+#include <Moof/Octree.hh>
+#include <Moof/Physics.hh>
#include <Moof/Tilemap.hh>
/**
- * Parent class of animate objects with "personalities."
+ * Parent class of animate objects with "personalities." This basically
+ * includes the heroine herself and the bad guys.
*/
-class Character : public Mf::Drawable
+class Character : public Mf::Entity
{
public:
+
+ struct Derivative
+ {
+ Mf::Vector2 velocity;
+ Mf::Vector2 force;
+
+ Derivative operator*(Mf::Scalar dt) const
+ {
+ Derivative derivative;
+ derivative.velocity = dt * velocity;
+ derivative.force = dt * force;
+ return derivative;
+ }
+
+ Derivative operator+(const Derivative& other) const
+ {
+ Derivative derivative;
+ derivative.velocity = velocity + other.velocity;
+ derivative.force = force + other.force;
+ return derivative;
+ }
+ };
+
+ struct State
+ {
+ // primary
+
+ Mf::Vector2 position;
+ Mf::Vector2 momentum;
+ Mf::Vector2 force;
+
+ // secondary
+
+ Mf::Vector2 velocity;
+
+ // constant
+
+ Mf::Scalar mass;
+ Mf::Scalar inverseMass;
+
+
+ void getDerivative(Derivative& derivative, Mf::Scalar t) const
+ {
+ //derivative.velocity = Mf::Vector2(0.0, 0.0);
+ //derivative.force = Mf::Vector2(0.0, 0.0);
+ derivative.velocity = velocity;
+ derivative.force = force;
+ }
+
+ void recalculate()
+ {
+ velocity = momentum * inverseMass;
+ }
+
+ void applyDerivative(const Derivative& derivative, Mf::Scalar dt)
+ {
+ position += dt * derivative.velocity;
+ momentum += dt * derivative.force;
+ recalculate();
+ }
+
+ State operator*(Mf::Scalar scalar) const
+ {
+ State state = *this;
+ state.position *= scalar;
+ state.momentum *= scalar;
+ state.recalculate();
+ return state;
+ }
+
+ State operator+(State state) const
+ {
+ State newState = *this;
+ newState.position += state.position;
+ newState.momentum += state.momentum;
+ newState.recalculate();
+ return newState;
+ }
+ };
+
+
Character(const std::string& name);
- ~Character();
+ virtual ~Character();
+ void update(Mf::Scalar t, Mf::Scalar dt);
+ void handleEvent(const Mf::Event& event);
void draw(Mf::Scalar alpha) const;
Mf::Tilemap& getTilemap();
Mf::Animation& getAnimation();
+ State previous;
+ State current;
+
+ stlplus::ntree<Mf::OctreeNode>::iterator treeNode;
+
private:
- Mf::Tilemap tilemap;
- Mf::Animation animation;
+
+ void updateContainers();
+
+ static const Mf::Scalar z = 96.0;
+
+ Mf::Tilemap tilemap_;
+ Mf::Animation animation_;
};
+typedef boost::shared_ptr<Character> CharacterPtr;
+
+
+inline Character::State operator*(Mf::Scalar scalar, const Character::State& state)
+{
+ Character::State newState = state;
+ newState.position *= scalar;
+ newState.momentum *= scalar;
+ newState.recalculate();
+ return newState;
+}
+
#endif // _CHARACTER_HH_
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <Moof/OpenGL.hh>
+
+#include "Hud.hh"
+
+#include <iostream>
+
+
+ProgressBar::ProgressBar(const Mf::Tilemap& tilemap, Mf::Tilemap::Index index) :
+ progress_(0.0),
+ tilemap_(tilemap)
+{
+ tilemap.getTileCoords(index, texCoords_);
+
+ Mf::Scalar half = (texCoords_[2] - texCoords_[0]) / 2.0 + texCoords_[0];
+ midCoords_[0] = half - 0.01;
+ midCoords_[1] = half + 0.01;
+}
+
+void ProgressBar::resize(const Mf::Rectangle& rect)
+{
+ Mf::Scalar height = rect.max[1] - rect.min[1];
+ Mf::Scalar halfHeight = height / 2.0;
+
+ width_ = rect.max[0] - rect.min[0] - height;
+ // assert width > 0
+
+ vertices_[0] = rect.min;
+ vertices_[1] = Mf::Vector2(rect.min[0] + halfHeight, rect.min[1]);
+ vertices_[2] = vertices_[1];
+ vertices_[3] = Mf::Vector2(rect.min[0] + height, rect.min[1]);
+ vertices_[4] = Mf::Vector2(rect.min[0] + height, rect.max[1]);
+ vertices_[5] = Mf::Vector2(rect.min[0] + halfHeight, rect.max[1]);
+ vertices_[6] = vertices_[5];
+ vertices_[7] = Mf::Vector2(rect.min[0], rect.max[1]);
+
+ setProgress(progress_);
+}
+
+void ProgressBar::setProgress(Mf::Scalar progress)
+{
+ Mf::Scalar halfHeight = (vertices_[7][1] - vertices_[0][1]) / 2.0;
+
+ vertices_[2][0] = vertices_[1][0] + progress * width_;
+ vertices_[3][0] = vertices_[1][0] + progress * width_ + halfHeight;
+ vertices_[4][0] = vertices_[1][0] + progress * width_ + halfHeight;
+ vertices_[5][0] = vertices_[1][0] + progress * width_;
+
+ progress_ = progress;
+}
+
+void ProgressBar::draw(Mf::Scalar alpha) const
+{
+ if (Mf::isEqual(progress_, 0.0))
+ {
+ // don't draw anything if the progress is 0%
+ return;
+ }
+
+ glColor4f(1.0f, 1.0f, 1.0f, 0.85f);
+ tilemap_.bind();
+
+ glBegin(GL_QUADS);
+ glTexCoord2(texCoords_[0], texCoords_[1]);
+ glVertex2v(vertices_[0].data());
+ glTexCoord2(midCoords_[0], texCoords_[3]);
+ glVertex2v(vertices_[1].data());
+ glTexCoord2(midCoords_[0], texCoords_[5]);
+ glVertex2v(vertices_[6].data());
+ glTexCoord2(texCoords_[6], texCoords_[7]);
+ glVertex2v(vertices_[7].data());
+
+ glTexCoord2(midCoords_[0], texCoords_[1]);
+ glVertex2v(vertices_[1].data());
+ glTexCoord2(midCoords_[1], texCoords_[3]);
+ glVertex2v(vertices_[2].data());
+ glTexCoord2(midCoords_[1], texCoords_[5]);
+ glVertex2v(vertices_[5].data());
+ glTexCoord2(midCoords_[0], texCoords_[7]);
+ glVertex2v(vertices_[6].data());
+
+ glTexCoord2(midCoords_[1], texCoords_[1]);
+ glVertex2v(vertices_[2].data());
+ glTexCoord2(texCoords_[2], texCoords_[3]);
+ glVertex2v(vertices_[3].data());
+ glTexCoord2(texCoords_[4], texCoords_[5]);
+ glVertex2v(vertices_[4].data());
+ glTexCoord2(midCoords_[1], texCoords_[7]);
+ glVertex2v(vertices_[5].data());
+ glEnd();
+}
+
+
+Hud::Hud() :
+ bar1_(Mf::Tilemap("StatusBars"), 0),
+ bar2_(Mf::Tilemap("StatusBars"), 2),
+ font_("Font")
+{
+ resize(800, 600);
+}
+
+
+void Hud::resize(int width, int height)
+{
+ cml::matrix_orthographic_RH( projection_,
+ 0.0,
+ Mf::Scalar(width), 0.0, Mf::Scalar(height),
+ 1.0, -1.0, cml::z_clip_neg_one);
+
+ // position the two progress bars at the top-left of the screen
+ bar1_.resize(Mf::Rectangle(20, height - 51,
+ 0.7 * width, height - 3));
+ bar2_.resize(Mf::Rectangle(20, height - 28,
+ 0.7 * width, height - 70));
+
+ setBar1Progress(0.05);
+ setBar2Progress(0.0);
+}
+
+
+void Hud::draw(Mf::Scalar alpha) const
+{
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadMatrix(projection_.data());
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+
+ bar1_.draw();
+ bar2_.draw();
+
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+}
+
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _HUD_HH_
+#define _HUD_HH_
+
+/**
+ * @file Hud.hh
+ * Heads-up Display
+ */
+
+#include <Moof/Drawable.hh>
+#include <Moof/Math.hh>
+#include <Moof/Rectangle.hh>
+#include <Moof/Tilemap.hh>
+
+
+class ProgressBar : public Mf::Drawable
+{
+public:
+
+ ProgressBar(const Mf::Tilemap& tilemap, Mf::Tilemap::Index index);
+
+ void resize(const Mf::Rectangle& rect);
+
+ void setProgress(Mf::Scalar progress);
+
+ void draw(Mf::Scalar alpha = 0.0) const;
+
+private:
+
+ Mf::Scalar progress_;
+
+ Mf::Vector2 vertices_[8];
+ Mf::Scalar width_;
+
+ Mf::Tilemap tilemap_;
+ Mf::Scalar texCoords_[8];
+ Mf::Scalar midCoords_[2];
+};
+
+
+class Hud : public Mf::Drawable
+{
+public:
+
+ Hud();
+
+ inline void setBar1Progress(Mf::Scalar progress)
+ {
+ // pass through
+ bar1_.setProgress(progress);
+ }
+
+ inline void setBar2Progress(Mf::Scalar progress)
+ {
+ // pass through
+ bar2_.setProgress(progress);
+ }
+
+ void setNumber(unsigned value);
+
+ void resize(int width, int height);
+
+ void draw(Mf::Scalar alpha = 0.0) const;
+
+private:
+
+ ProgressBar bar1_;
+ ProgressBar bar2_;
+
+ unsigned number_;
+ Mf::Tilemap font_;
+
+ Mf::Matrix4 projection_;
+};
+
+
+#endif // _HUD_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
Moof/Interpolator.hh \
Moof/Math.hh \
Moof/Mippleton.hh \
+ Moof/Octree.cc \
Moof/Octree.hh \
Moof/OpenGL.cc \
Moof/OpenGL.hh \
+ Moof/Physics.hh \
Moof/Plane.cc \
Moof/Plane.hh \
Moof/Random.cc \
Moof/Random.hh \
+ Moof/Rectangle.cc \
+ Moof/Rectangle.hh \
Moof/Resource.cc \
Moof/Resource.hh \
Moof/Scene.cc \
Moof/Settings.cc \
Moof/Settings.hh \
Moof/Singleton.hh \
+ Moof/Sound.cc \
+ Moof/Sound.hh \
Moof/Sphere.cc \
Moof/Sphere.hh \
Moof/StringTools.cc \
yoink_SOURCES = \
Character.cc \
Character.hh \
+ Hud.cc \
+ Hud.hh \
TilemapFont.cc \
TilemapFont.hh \
Typesetter.cc \
*******************************************************************************/
-#include <Moof/Aabb.hh>
-#include <Moof/Camera.hh>
-#include <Moof/OpenGL.hh>
-#include <Moof/Texture.hh>
+#include "Aabb.hh"
+#include "Camera.hh"
+#include "OpenGL.hh"
+#include "Texture.hh"
namespace Mf {
/**
* The collection of nested animation classes. The animation implementation
- * consists of an AnimationImpl classes which is allocated and initialized with
- * the interface object. This class contains the specific fields which are
- * required to run a single instance of an animation. The sequence data is
- * loaded in a difference class which can be shared amongst multiple animation
- * implementation instances.
+ * consists of an Impl class which is allocated and initialized with the
+ * interface object. This class contains the specific fields which are required
+ * to run a single instance of an animation. The sequence data is loaded in a
+ * different class which can be shared amongst multiple animation implementation
+ * instances.
*/
-struct Animation::AnimationImpl
+struct Animation::Impl
{
/**
* which wants to use these loaded sequences.
*/
- struct AnimationData : public Mippleton<AnimationData>
+ struct GlobalData : public Mippleton<GlobalData>
{
/**
* A frame of an animation sequence. A frame is merely an index which
void loadFromFile()
{
- std::string filePath = Animation::getPathToResource(getName());
+ std::string filePath = Animation::getPath(getName());
Deserializer deserializer(filePath);
* registers itself as a mippleton and then loads the animation data.
*/
- explicit AnimationData(const std::string& name) :
- Mippleton<AnimationData>(name)
+ explicit GlobalData(const std::string& name) :
+ Mippleton<GlobalData>(name)
{
loadFromFile();
}
* Construction is intialization.
*/
- AnimationImpl(const std::string& name) :
- data(AnimationData::retain(name), &AnimationData::release),
+ Impl(const std::string& name) :
+ data(GlobalData::retain(name), &GlobalData::release),
currentSequence(0),
frameCounter(0),
frameIndex(0),
void startSequence(const std::string& name)
{
- std::map<std::string,AnimationData::Sequence>::iterator it;
+ std::map<std::string,GlobalData::Sequence>::iterator it;
it = data->sequences.find(name);
}
}
- boost::shared_ptr<AnimationData> data; ///< Internal data.
+ boost::shared_ptr<GlobalData> data; ///< Internal data.
- AnimationData::Sequence* currentSequence; ///< Active sequence.
+ GlobalData::Sequence* currentSequence; ///< Active sequence.
unsigned frameCounter; ///< Current frame.
unsigned frameIndex; ///< Index of current frame.
Scalar timeAccum; ///< Time accumulation.
Animation::Animation(const std::string& name) :
// pass through
- impl_(new Animation::AnimationImpl(name)) {}
+ impl_(new Animation::Impl(name)) {}
void Animation::startSequence(const std::string& name)
* "animations" subdirectory of any of the searched directories.
*/
-std::string Animation::getPathToResource(const std::string& name)
+std::string Animation::getPath(const std::string& name)
{
- return Resource::getPathToResource("animations/" + name + ".json");
+ return Resource::getPath("animations/" + name + ".json");
}
void update(Scalar t, Scalar dt);
unsigned getFrame() const;
- static std::string getPathToResource(const std::string& name);
+ static std::string getPath(const std::string& name);
private:
- class AnimationImpl;
- boost::shared_ptr<AnimationImpl> impl_;
+ class Impl;
+ boost::shared_ptr<Impl> impl_;
};
void Camera::setPosition(const Vector3& point)
{
position_ = point;
+ calculateSecondary();
//Vector3 coeff[2] = {position_, point};
//pInterp_.init(coeff, 0.1);
}
void Camera::lookAt(const Vector3& point)
{
- quaternion_rotation_aim_at(rotation_, position_, point);
+ cml::quaternion_rotation_aim_at(rotation_, position_, point, Vector3(0.0, -1.0, 0.0));
+ calculateSecondary();
}
void Camera::adjustFromInput(const Event& event)
switch (event.type)
{
case SDL_KEYDOWN:
- if (event.key.keysym.sym == SDLK_RIGHT ||
- event.key.keysym.sym == SDLK_d)
+ if (event.key.keysym.sym == SDLK_RIGHT)
{
Vector3 vec = position_;
vec[0] -= 50.0;
setPosition(vec);
}
- else if (event.key.keysym.sym == SDLK_LEFT ||
- event.key.keysym.sym == SDLK_a)
+ else if (event.key.keysym.sym == SDLK_LEFT)
{
Vector3 vec = position_;
vec[0] += 50.0;
setPosition(vec);
}
- else if (event.key.keysym.sym == SDLK_UP ||
- event.key.keysym.sym == SDLK_w)
+ else if (event.key.keysym.sym == SDLK_UP)
{
Vector3 vec = position_;
vec[1] -= 50.0;
setPosition(vec);
}
- else if (event.key.keysym.sym == SDLK_DOWN ||
- event.key.keysym.sym == SDLK_s)
+ else if (event.key.keysym.sym == SDLK_DOWN)
{
Vector3 vec = position_;
vec[1] += 50.0;
}
else if (event.key.keysym.sym == SDLK_PAGEDOWN)
{
- //position_[2] -= 50.0;
Vector3 vec = position_;
vec[2] -= 50.0;
setPosition(vec);
Quaternion rotation = rotation_;
- quaternion_rotate_about_world_x(rotation, yrel);
+ cml::quaternion_rotate_about_world_x(rotation, yrel);
//rotation_.normalize();
- quaternion_rotate_about_world_y(rotation, xrel);
+ cml::quaternion_rotate_about_world_y(rotation, xrel);
rotation.normalize();
setRotation(rotation);
void Camera::calculateSecondary()
{
- matrix_rotation_quaternion(modelview_, rotation_);
+ cml::matrix_rotation_quaternion(modelview_, rotation_);
Matrix4 translate;
- matrix_translation(translate, position_);
+ cml::matrix_translation(translate, position_);
- //modelview_ = translate * modelview_;
+ //modelview_.transpose();
modelview_ *= translate;
+ //modelview_ = translate * modelview_;
frustum_.init(modelview_, projection_);
}
#include <SDL/SDL.h>
#include "fastevents.h"
+#include <SDL/SDL_sound.h>
+#include <AL/alut.h>
#include "Dispatcher.hh"
#include "Engine.hh"
namespace Mf {
-class Engine::EngineImpl
+class Engine::Impl
{
public:
- EngineImpl(int argc, char* argv[], const std::string& configFile,
+ Impl(int argc, char* argv[], const std::string& configFile,
const std::string& name, const std::string& iconFile,
Engine* outer) :
interface(outer),
{
throw Exception(FE_GetError());
}
+ if (Sound_Init() != 0)
+ {
+ //throw Exception(Sound_GetError());
+ std::cerr << Sound_GetError() << std::endl;
+ }
+ alutInit(&argc, argv);
settings.loadFromFile(configFile);
long randomSeed;
- if (settings.get("engine.rngseed", randomSeed))
- {
- setSeed(randomSeed);
- }
- else
- {
- setSeed();
- }
+ if (settings.get("engine.rngseed", randomSeed)) setSeed(randomSeed);
+ else setSeed();
double ts = 0.01;
settings.get("engine.timestep", ts);
video->makeActive();
}
- ~EngineImpl()
+ ~Impl()
{
// the video object must be destroyed before we can shutdown SDL
video.reset();
+ alutExit();
+ Sound_Quit();
FE_Quit();
SDL_Quit();
}
Engine::Engine(int argc, char* argv[], const std::string& configFile,
const std::string& name, const std::string& iconFile) :
- impl_(new Engine::EngineImpl(argc, argv, configFile, name, iconFile, this))
-{}
+ impl_(new Engine::Impl(argc, argv, configFile, name, iconFile, this)) {}
Engine::~Engine() {}
};
private:
- class EngineImpl;
- boost::shared_ptr<EngineImpl> impl_;
+ class Impl;
+ boost::shared_ptr<Impl> impl_;
};
return left;
}
-inline Vector4& promoteVector(Vector4& left, const Vector3& right)
+inline Vector2& demoteVector(Vector2& left, const Vector3& right)
+{
+ left[0] = right[0];
+ left[1] = right[1];
+ return left;
+}
+
+inline Vector4& promoteVector(Vector4& left, const Vector3& right, Scalar extra = 1.0)
{
left[0] = right[0];
left[1] = right[1];
left[2] = right[2];
- left[3] = 1.0;
+ left[3] = extra;
+ return left;
+}
+
+inline Vector3& promoteVector(Vector3& left, const Vector2& right, Scalar extra = 1.0)
+{
+ left[0] = right[0];
+ left[1] = right[1];
+ left[3] = extra;
return left;
}
* after the last interested code releases its hold on the object.
*/
-#include <Moof/Hash.hh>
#include <string>
+#include <Moof/Hash.hh>
+
+
namespace Mf {
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include "Camera.hh"
+#include "Octree.hh"
+
+
+namespace Mf {
+
+
+void Octree::sort()
+{
+ stlplus::ntree<OctreeNode>::prefix_iterator it;
+
+ for (it = tree_.prefix_begin(); it != tree_.prefix_end(); ++it)
+ {
+ it->sort();
+ }
+}
+
+
+stlplus::ntree<OctreeNode>::iterator Octree::insert(stlplus::ntree<OctreeNode>::iterator node,
+ EntityPtr entity)
+{
+ Plane::Halfspace halfspace;
+ int octantNum = -1;
+
+ if (!node.valid())
+ {
+ std::cerr << "cannot insert into invalid node" << std::endl;
+ return stlplus::ntree<OctreeNode>::iterator();
+ }
+
+ Plane xy = node->getAabb().getPlaneXY();
+ halfspace = xy.intersectsSphere(entity->getSphere());
+ if (halfspace == Plane::INTERSECT)
+ {
+ halfspace = xy.intersectsAabb(entity->getAabb());
+ }
+
+ if (halfspace == Plane::POSITIVE)
+ {
+ Plane xz = node->getAabb().getPlaneXZ();
+ halfspace = xz.intersectsSphere(entity->getSphere());
+ if (halfspace == Plane::INTERSECT)
+ {
+ halfspace = xz.intersectsAabb(entity->getAabb());
+ }
+
+ if (halfspace == Plane::POSITIVE)
+ {
+ Plane yz = node->getAabb().getPlaneYZ();
+ halfspace = yz.intersectsSphere(entity->getSphere());
+ if (halfspace == Plane::INTERSECT)
+ {
+ halfspace = yz.intersectsAabb(entity->getAabb());
+ }
+
+ if (halfspace == Plane::POSITIVE)
+ {
+ octantNum = 2;
+ }
+ else if (halfspace == Plane::NEGATIVE)
+ {
+ octantNum = 3;
+ }
+ }
+ else if (halfspace == Plane::NEGATIVE)
+ {
+ Plane yz = node->getAabb().getPlaneYZ();
+ halfspace = yz.intersectsSphere(entity->getSphere());
+ if (halfspace == Plane::INTERSECT)
+ {
+ halfspace = yz.intersectsAabb(entity->getAabb());
+ }
+
+ if (halfspace == Plane::POSITIVE)
+ {
+ octantNum = 1;
+ }
+ else if (halfspace == Plane::NEGATIVE)
+ {
+ octantNum = 0;
+ }
+ }
+ }
+ else if (halfspace == Plane::NEGATIVE)
+ {
+ Plane xz = node->getAabb().getPlaneXZ();
+ halfspace = xz.intersectsSphere(entity->getSphere());
+ if (halfspace == Plane::INTERSECT)
+ {
+ halfspace = xz.intersectsAabb(entity->getAabb());
+ }
+
+ if (halfspace == Plane::POSITIVE)
+ {
+ Plane yz = node->getAabb().getPlaneYZ();
+ halfspace = yz.intersectsSphere(entity->getSphere());
+ if (halfspace == Plane::INTERSECT)
+ {
+ halfspace = yz.intersectsAabb(entity->getAabb());
+ }
+
+ if (halfspace == Plane::POSITIVE)
+ {
+ octantNum = 6;
+ }
+ else if (halfspace == Plane::NEGATIVE)
+ {
+ octantNum = 7;
+ }
+ }
+ else if (halfspace == Plane::NEGATIVE)
+ {
+ Plane yz = node->getAabb().getPlaneYZ();
+ halfspace = yz.intersectsSphere(entity->getSphere());
+ if (halfspace == Plane::INTERSECT)
+ {
+ halfspace = yz.intersectsAabb(entity->getAabb());
+ }
+
+ if (halfspace == Plane::POSITIVE)
+ {
+ octantNum = 5;
+ }
+ else if (halfspace == Plane::NEGATIVE)
+ {
+ octantNum = 4;
+ }
+ }
+ }
+
+ if (octantNum == -1)
+ {
+ node->objects.push_front(entity);
+ return node;
+ }
+ else
+ {
+ if ((int)tree_.children(node) <= octantNum)
+ {
+ addChild(node, octantNum);
+ }
+
+ stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, octantNum);
+
+ if (child.valid())
+ {
+ return insert(child, entity);
+ }
+ else
+ {
+ std::cerr << "expected but found no child at index " << octantNum << std::endl;
+ return stlplus::ntree<OctreeNode>::iterator();
+ }
+ }
+}
+
+stlplus::ntree<OctreeNode>::iterator Octree::reinsert(EntityPtr entity,
+ stlplus::ntree<OctreeNode>::iterator node)
+{
+ if (!node.valid())
+ {
+ std::cerr << "cannot move entity from invalid node" << std::endl;
+ return stlplus::ntree<OctreeNode>::iterator();
+ }
+
+ std::list<EntityPtr>::iterator it;
+ it = std::find(node->objects.begin(), node->objects.end(), entity);
+
+ if (it != node->objects.end())
+ {
+ node->objects.erase(it);
+ }
+
+ return insert(entity);
+}
+
+
+void Octree::addChild(stlplus::ntree<OctreeNode>::iterator node, int index)
+{
+ Aabb octant;
+
+ if (!node.valid())
+ {
+ std::cerr << "cannot add children to invalid node" << std::endl;
+ return;
+ }
+
+ for (int i = tree_.children(node); i <= index; ++i)
+ {
+ node->getAabb().getOctant(octant, i);
+ tree_.append(node, octant);
+ }
+}
+
+
+void Octree::draw(stlplus::ntree<OctreeNode>::iterator node, Scalar alpha)
+{
+ if (!node.valid())
+ {
+ std::cerr << "cannot draw null child node :-(" << std::endl;
+ return;
+ }
+
+ node->draw(alpha);
+
+ for (unsigned i = 0; i < tree_.children(node); ++i)
+ {
+ stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, i);
+
+ if (child.valid())
+ {
+ draw(child, alpha);
+ }
+ else
+ {
+ std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
+ }
+
+ }
+}
+
+void Octree::drawIfVisible(stlplus::ntree<OctreeNode>::iterator node,
+ Scalar alpha, const Camera& cam)
+{
+ //node.drawIfVisible(alpha, cam);
+
+ if (!node.valid())
+ {
+ std::cerr << "invalid child while drawing :-(" << std::endl;
+ return;
+ }
+
+ Frustum::Collision collision =
+ cam.getFrustum().containsSphere(node->getSphere());
+ if (collision == Frustum::OUTSIDE) return;
+
+ collision = cam.getFrustum().containsAabb(node->getAabb());
+ if (collision == Frustum::OUTSIDE) return;
+
+
+ if (collision == Frustum::INSIDE)
+ {
+ node->draw(alpha);
+ }
+ else // collision == Frustum::INTERSECT
+ {
+ node->drawIfVisible(alpha, cam);
+ }
+
+ if (tree_.children(node) > 0)
+ {
+ if (collision == Frustum::INSIDE)
+ {
+ for (unsigned i = 0; i < tree_.children(node); ++i)
+ {
+ stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, i);
+
+ if (child.valid())
+ {
+ draw(child, alpha);
+ }
+ else
+ {
+ std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
+ }
+
+ }
+ }
+ else // collision == Frustum::INTERSECT
+ {
+ for (unsigned i = 0; i < tree_.children(node); ++i)
+ {
+ stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, i);
+
+ if (child.valid())
+ {
+ drawIfVisible(child, alpha, cam);
+ }
+ else
+ {
+ std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
+ }
+ }
+ }
+ }
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
#ifndef _MOOF_OCTREE_HH_
#define _MOOF_OCTREE_HH_
+#include <algorithm>
#include <list>
#include <boost/shared_ptr.hpp>
namespace Mf {
+class Camera;
+
+
struct OctreeNode : public Entity
{
std::list<EntityPtr> objects;
{
(*it)->draw(alpha);
}
- if (!objects.empty())
- aabb_.draw(); // temporary
+
+ //if (!objects.empty())
+ //aabb_.draw(); // temporary
}
void drawIfVisible(Scalar alpha, const Camera& cam) const
{
(*it)->drawIfVisible(alpha, cam);
}
- if (!objects.empty())
- aabb_.draw();
+
+ //if (!objects.empty())
+ //aabb_.draw();
}
return false;
}
-};
-class Octree;
-typedef boost::shared_ptr<Octree> OctreePtr;
+ static bool compareZOrder(EntityPtr a, EntityPtr b)
+ {
+ return a->getSphere().point[2] < b->getSphere().point[2];
+ }
-class Octree
-{
+ void sort()
+ {
+ //std::sort(objects.begin(), objects.end(), compareZOrder);
+ objects.sort(compareZOrder);
+ }
+};
- stlplus::ntree<OctreeNode> root_;
+class Octree
+{
public:
explicit Octree(const OctreeNode& rootNode)
{
- root_.insert(rootNode);
+ tree_.insert(rootNode);
}
- void insert(EntityPtr entity)
+ stlplus::ntree<OctreeNode>::iterator insert(EntityPtr entity)
{
- insert(root_.root(), entity);
+ return insert(tree_.root(), entity);
}
- void insert(stlplus::ntree<OctreeNode>::iterator node, EntityPtr entity)
- {
- Plane::Halfspace halfspace;
- int octantNum = -1;
+ stlplus::ntree<OctreeNode>::iterator reinsert(EntityPtr entity,
+ stlplus::ntree<OctreeNode>::iterator node);
- if (!node.valid())
- {
- std::cerr << "cannot insert into invalid node" << std::endl;
- return;
- }
-
- Plane xy = node->getAabb().getPlaneXY();
- halfspace = xy.intersectsSphere(entity->getSphere());
-
- if (halfspace == Plane::POSITIVE)
- {
- Plane xz = node->getAabb().getPlaneXZ();
- halfspace = xz.intersectsSphere(entity->getSphere());
-
- if (halfspace == Plane::POSITIVE)
- {
- Plane yz = node->getAabb().getPlaneYZ();
- halfspace = yz.intersectsSphere(entity->getSphere());
-
- if (halfspace == Plane::POSITIVE)
- {
- octantNum = 2;
- }
- else if (halfspace == Plane::NEGATIVE)
- {
- octantNum = 3;
- }
- }
- else if (halfspace == Plane::NEGATIVE)
- {
- Plane yz = node->getAabb().getPlaneYZ();
- halfspace = yz.intersectsSphere(entity->getSphere());
-
- if (halfspace == Plane::POSITIVE)
- {
- octantNum = 1;
- }
- else if (halfspace == Plane::NEGATIVE)
- {
- octantNum = 0;
- }
- }
- }
- else if (halfspace == Plane::NEGATIVE)
- {
- Plane xz = node->getAabb().getPlaneXZ();
- halfspace = xz.intersectsSphere(entity->getSphere());
-
- if (halfspace == Plane::POSITIVE)
- {
- Plane yz = node->getAabb().getPlaneYZ();
- halfspace = yz.intersectsSphere(entity->getSphere());
-
- if (halfspace == Plane::POSITIVE)
- {
- octantNum = 6;
- }
- else if (halfspace == Plane::NEGATIVE)
- {
- octantNum = 7;
- }
- }
- else if (halfspace == Plane::NEGATIVE)
- {
- Plane yz = node->getAabb().getPlaneYZ();
- halfspace = yz.intersectsSphere(entity->getSphere());
-
- if (halfspace == Plane::POSITIVE)
- {
- octantNum = 5;
- }
- else if (halfspace == Plane::NEGATIVE)
- {
- octantNum = 4;
- }
- }
- }
-
- if (octantNum == -1)
- {
- node->objects.push_front(entity);
- //return node;
- }
- else
- {
- if (root_.children(node) == 0)
- {
- addChildren(node);
- }
-
- stlplus::ntree<OctreeNode>::iterator child = root_.child(node, octantNum);
-
- if (child.valid())
- {
- return insert(child, entity);
- }
- else
- {
- std::cerr << "expected but found no child at index " << octantNum << std::endl;
- //return stlplus::ntree<OctreeNode>::iterator();
- }
- //return WeakPtr();
- }
- }
-
- void addChildren(stlplus::ntree<OctreeNode>::iterator node)
+ void drawIfVisible(Scalar alpha, const Camera& cam)
{
- Aabb octant;
-
- if (!node.valid())
- {
- std::cerr << "cannot add children to invalid node" << std::endl;
- return;
- }
-
- for (int i = 0; i < 8; ++i)
- {
- node->getAabb().getOctant(octant, i);
- //OctreeNode octantNode(octant);
-
- root_.append(node, octant);
- }
+ drawIfVisible(tree_.root(), alpha, cam);
}
- void draw(stlplus::ntree<OctreeNode>::iterator node, Scalar alpha)
- {
- if (!node.valid())
- {
- std::cerr << "cannot draw null child node :-(" << std::endl;
- return;
- }
+ void sort();
- node->draw(alpha);
-
- for (unsigned i = 0; i < root_.children(node); ++i)
- {
- stlplus::ntree<OctreeNode>::iterator child = root_.child(node, i);
-
- if (child.valid())
- {
- draw(child, alpha);
- }
- else
- {
- std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
- }
-
- }
- }
+private:
+ stlplus::ntree<OctreeNode>::iterator insert(stlplus::ntree<OctreeNode>::iterator node, EntityPtr entity);
+
+ void addChild(stlplus::ntree<OctreeNode>::iterator node, int index);
+ void draw(stlplus::ntree<OctreeNode>::iterator node, Scalar alpha);
void drawIfVisible(stlplus::ntree<OctreeNode>::iterator node,
- Scalar alpha, const Camera& cam)
- {
- //node.drawIfVisible(alpha, cam);
-
- if (!node.valid())
- {
- std::cerr << "invalid child while drawing :-(" << std::endl;
- return;
- }
-
- Frustum::Collision collision =
- cam.getFrustum().containsSphere(node->getSphere());
- if (collision == Frustum::OUTSIDE) return;
-
- collision = cam.getFrustum().containsAabb(node->getAabb());
- if (collision == Frustum::OUTSIDE) return;
-
-
- if (collision == Frustum::INSIDE)
- {
- node->draw(alpha);
- }
- else // collision == Frustum::INTERSECT
- {
- node->drawIfVisible(alpha, cam);
- }
-
- if (root_.children(node) > 0)
- {
- if (collision == Frustum::INSIDE)
- {
- for (unsigned i = 0; i < root_.children(node); ++i)
- {
- stlplus::ntree<OctreeNode>::iterator child = root_.child(node, i);
-
- if (child.valid())
- {
- draw(child, alpha);
- }
- else
- {
- std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
- }
-
- }
- }
- else // collision == Frustum::INTERSECT
- {
- for (unsigned i = 0; i < root_.children(node); ++i)
- {
- stlplus::ntree<OctreeNode>::iterator child = root_.child(node, i);
-
- if (child.valid())
- {
- drawIfVisible(child, alpha, cam);
- }
- else
- {
- std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
- }
- }
- }
- }
- }
-
- void drawIfVisible(Scalar alpha, const Camera& cam)
- {
- drawIfVisible(root_.root(), alpha, cam);
- }
+ Scalar alpha, const Camera& cam);
+ stlplus::ntree<OctreeNode> tree_;
};
+typedef boost::shared_ptr<Octree> OctreePtr;
} // namespace Mf
void (*glVertex3v)(const GLscalar*)(glVertex3dv);
void (*glVertex4v)(const GLscalar*)(glVertex4dv);
+void (*glTexCoord2)(GLscalar, GLscalar)(glTexCoord2d);
+void (*glTexCoord3)(GLscalar, GLscalar, GLscalar)(glTexCoord3d);
+void (*glTexCoord4)(GLscalar, GLscalar, GLscalar, GLscalar)(glTexCoord4d);
+void (*glTexCoord2v)(const GLscalar*)(glTexCoord2dv);
+void (*glTexCoord3v)(const GLscalar*)(glTexCoord3dv);
+void (*glTexCoord4v)(const GLscalar*)(glTexCoord4dv);
+
#else
void (*glGetScalarv(GLenum, GLscalar*)(glGetFloatv);
void (*glRotate)(GLscalar, GLscalar, GLscalar, GLscalar)(glRotatef);
void (*glTranslate)(GLscalar, GLscalar, GLscalar)(glTranslatef);
+void (*glColor3)(GLscalar, GLscalar, GLscalar)(glColor3f);
+void (*glColor4)(GLscalar, GLscalar, GLscalar, GLscalar)(glColor4f);
+void (*glColor3v)(const GLscalar*)(glColor3fv);
+void (*glColor4v)(const GLscalar*)(glColor4fv);
+
void (*glVertex2)(GLscalar, GLscalar)(glVertex2f);
void (*glVertex3)(GLscalar, GLscalar, GLscalar)(glVertex3f);
void (*glVertex4)(GLscalar, GLscalar, GLscalar, GLscalar)(glVertex4f);
void (*glVertex3v)(const GLscalar*)(glVertex3fv);
void (*glVertex4v)(const GLscalar*)(glVertex4fv);
-void (*glColor3)(GLscalar, GLscalar, GLscalar)(glColor3f);
-void (*glColor4)(GLscalar, GLscalar, GLscalar, GLscalar)(glColor4f);
-void (*glColor3v)(const GLscalar*)(glColor3fv);
-void (*glColor4v)(const GLscalar*)(glColor4fv);
+void (*glTexCoord2)(GLscalar, GLscalar)(glTexCoord2f);
+void (*glTexCoord3)(GLscalar, GLscalar, GLscalar)(glTexCoord3f);
+void (*glTexCoord4)(GLscalar, GLscalar, GLscalar, GLscalar)(glTexCoord4f);
+void (*glTexCoord2v)(const GLscalar*)(glTexCoord2df);
+void (*glTexCoord3v)(const GLscalar*)(glTexCoord3df);
+void (*glTexCoord4v)(const GLscalar*)(glTexCoord4df);
#endif
extern void (*glVertex3v)(const GLscalar*);
extern void (*glVertex4v)(const GLscalar*);
+extern void (*glTexCoord2)(GLscalar, GLscalar);
+extern void (*glTexCoord3)(GLscalar, GLscalar, GLscalar);
+extern void (*glTexCoord4)(GLscalar, GLscalar, GLscalar, GLscalar);
+extern void (*glTexCoord2v)(const GLscalar*);
+extern void (*glTexCoord3v)(const GLscalar*);
+extern void (*glTexCoord4v)(const GLscalar*);
+
+
#endif // _MOOF_OPENGL_HH_
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _MOOF_PHYSICS_HH_
+#define _MOOF_PHYSICS_HH_
+
+#include <Moof/Math.hh>
+
+
+namespace Mf {
+
+// Generic implementation of the RK4 integrator. To use, you need one type
+// representing the state and another containing the derivatives of the state.
+
+template<typename S, typename D>
+inline D evaluate(const S& state, Scalar t)
+{
+ D derivative;
+ state.getDerivative(derivative, t);
+ return derivative;
+}
+
+template<typename S, typename D>
+inline D evaluate(const S& state, Scalar t, Scalar dt, const D& derivative)
+{
+ S temp = state;
+ temp.applyDerivative(derivative, dt);
+ return evaluate<S,D>(temp, t + dt);
+}
+
+
+template<typename S, typename D>
+inline void integrate(S& state, Scalar t, Scalar dt)
+{
+ D a = evaluate<S,D>(state, t);
+ D b = evaluate<S,D>(state, t, dt * 0.5, a);
+ D c = evaluate<S,D>(state, t, dt * 0.5, b);
+ D d = evaluate<S,D>(state, t, dt, c);
+
+ //state += (a + (b + c) * 2.0 + d) * (1.0/6.0) * dt;
+ state.applyDerivative((a + (b + c) * 2.0 + d) * (1.0/6.0), dt);
+}
+
+
+} // namespace Mf
+
+#endif // _MOOF_PHYSICS_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include "Rectangle.hh"
+
+
+namespace Mf {
+
+
+void Rectangle::getCorners(Vector2 corners[4]) const
+{
+ corners[0][0] = min[0]; corners[0][1] = min[1];
+ corners[1][0] = max[0]; corners[1][1] = min[1];
+ corners[2][0] = max[0]; corners[2][1] = max[1];
+ corners[3][0] = min[0]; corners[3][1] = max[1];
+ corners[4][0] = min[0]; corners[4][1] = min[1];
+ corners[5][0] = max[0]; corners[5][1] = min[1];
+ corners[6][0] = max[0]; corners[6][1] = max[1];
+ corners[7][0] = min[0]; corners[7][1] = max[1];
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _MOOF_RECTANGLE_HH_
+#define _MOOF_RECTANGLE_HH_
+
+#include <Moof/Math.hh>
+
+
+namespace Mf {
+
+
+/**
+ * Axis-aligned Bounding Box
+ */
+
+struct Rectangle
+{
+ Vector2 min;
+ Vector2 max;
+
+
+ Rectangle() {}
+
+ Rectangle(const Vector2& a, const Vector2& b)
+ {
+ init(a, b);
+ }
+
+ Rectangle(Scalar ax, Scalar ay, Scalar bx, Scalar by)
+ {
+ Vector2 a(ax, ay);
+ Vector2 b(bx, by);
+
+ init(a, b);
+ }
+
+ inline void init(const Vector2& a, const Vector2& b)
+ {
+ if (a[0] < b[0])
+ {
+ min[0] = a[0];
+ max[0] = b[0];
+ }
+ else
+ {
+ min[0] = b[0];
+ max[0] = a[0];
+ }
+ if (a[1] < b[1])
+ {
+ min[1] = a[1];
+ max[1] = b[1];
+ }
+ else
+ {
+ min[1] = b[1];
+ max[1] = a[1];
+ }
+ }
+
+ inline Vector2 getCenter() const
+ {
+ return Vector2((min[0] + max[0]) / 2.0,
+ (min[1] + max[1]) / 2.0);
+ }
+
+ void getCorners(Vector2 corners[4]) const;
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_RECTANGLE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
}
}
-std::string Resource::getPathToResource(const std::string& name)
+std::string Resource::getPath(const std::string& name)
{
std::vector<std::string>::iterator it;
* @return The first path found which resolves to a file.
*/
- static std::string getPathToResource(const std::string& name);
+ static std::string getPath(const std::string& name);
private:
static std::vector<std::string> searchPaths_;
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _MOOF_RIGIDBODY_HH_
+#define _MOOF_RIGIDBODY_HH_
+
+#include <Moof/Math.hh>
+#include <Moof/State.hh>
+
+
+namespace Mf {
+
+
+/**
+ * Interface for physical things with mass, momentum, yada yada yada.
+ */
+
+template <typename T>
+class RigidBody
+{
+public:
+ inline virtual ~RigidBody() {}
+
+ virtual void update(Scalar t, Scalar dt)
+ {
+ prevState_ = currentState_;
+ currentState_.integrate(t, dt);
+ }
+
+ inline T getInterpolatedState(Scalar alpha) const
+ {
+ return currentState_.interpolate(alpha, prevState_);
+ }
+
+protected:
+ T prevState_;
+ T currentState_;
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_RIGIDBODY_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
+
#include "Entity.hh"
#include "Math.hh"
#include "Mippleton.hh"
-#include "Octree.hh"
#include "OpenGL.hh"
#include "Scene.hh"
#include "Serializable.hh"
namespace Mf {
-class Scene::SceneImpl : public Mippleton<SceneImpl>
+class Scene::Impl : public Mippleton<Impl>
{
class Quad : public Entity
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
+ if (fog_)
+ {
+ glEnable(GL_FOG);
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ }
+
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
tilemap_.bind();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisable(GL_BLEND);
+ glDisable(GL_FOG);
}
bool isVisible(const Camera& cam) const
}
public:
- SceneImpl(const std::string& name) :
- Mippleton<SceneImpl>(name)
+ Impl(const std::string& name) :
+ Mippleton<Impl>(name)
{
loadFromFile();
}
Quad* quad = new Quad(quadVertices, texture, indices[h][w]);
boost::shared_ptr<Quad> quadPtr(quad);
- //objects.push_back(quadPtr);
octree->insert(quadPtr);
}
}
std::map<std::string,SerializablePtr> rootObj;
std::map<std::string,SerializablePtr>::iterator it;
- if (!root->get(rootObj))
- {
- std::cerr << "error loading scene billboard object" << std::endl;
- return;
- }
-
Tilemap::Index index = 0;
long width = 1;
bool blending = false;
bool fog = false;
- if ((it = rootObj.find("tile")) != rootObj.end())
+ if (root->get(rootObj))
{
- long value;
- if ((*it).second->get(value))
+ if ((it = rootObj.find("tile")) != rootObj.end())
{
- index = Tilemap::Index(value);
+ long value;
+ if ((*it).second->get(value))
+ {
+ index = Tilemap::Index(value);
+ }
}
- }
- if ((it = rootObj.find("u_scale")) != rootObj.end())
- {
- (*it).second->get(width);
- }
+ if ((it = rootObj.find("u_scale")) != rootObj.end())
+ {
+ (*it).second->get(width);
+ }
- if ((it = rootObj.find("blend")) != rootObj.end())
- {
- (*it).second->get(blending);
- }
+ if ((it = rootObj.find("blend")) != rootObj.end())
+ {
+ (*it).second->get(blending);
+ }
- if ((it = rootObj.find("fog")) != rootObj.end())
- {
- (*it).second->get(fog);
+ if ((it = rootObj.find("fog")) != rootObj.end())
+ {
+ (*it).second->get(fog);
+ }
}
boost::shared_ptr<Quad> quadPtr(quad);
- //objects.push_back(quad_Ptr);
octree->insert(quadPtr);
}
}
void loadFromFile()
{
- std::string filePath = Scene::getPathToResource(getName());
+ std::string filePath = Scene::getPath(getName());
Deserializer deserializer(filePath, true);
SerializablePtr root = deserializer.deserialize();
return;
}
- //OctreeNode rootNode(maximumBounds);
+ // create the tree to store the quads
octree = OctreePtr(new Octree(maximumBounds));
if ((it = rootObj.find("instructions")) != rootObj.end())
{
loadInstructions((*it).second);
}
+
+ octree->sort();
}
void draw(Scalar alpha, const Camera& cam) const
{
- //QuadVector::const_iterator it;
-
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
octree->drawIfVisible(alpha, cam);
- //int objectsDrawn = 0;
+ //glDisableClientState(GL_VERTEX_ARRAY);
+ //glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- //for (it = objects.begin(); it != objects.end(); ++it)
- //{
- //if ((*it)->isVisible(cam))
- //{
- ////std::cout << "draw object";
- //(*it)->draw();
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- //objectsDrawn++;
- //}
- //}
+ //Texture::resetBind();
+ //glColor3f(0.0f, 1.0f, 0.0f);
+ //playfieldBounds.draw();
+ //glColor3f(0.0f, 0.0f, 1.0f);
+ //maximumBounds.draw();
- //std::cout << objectsDrawn << std::endl;
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- Texture::resetBind();
- glColor3f(0.0f, 1.0f, 0.0f);
- playfieldBounds.draw();
- glColor3f(0.0f, 0.0f, 1.0f);
- maximumBounds.draw();
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
Aabb playfieldBounds;
Aabb maximumBounds;
- //typedef std::vector< boost::shared_ptr<Quad> > QuadVector;
- //QuadVector objects;
OctreePtr octree;
};
Scene::Scene(const std::string& name) :
// pass through
- impl_(Scene::SceneImpl::retain(name), &Scene::SceneImpl::release) {}
+ impl_(Scene::Impl::retain(name), &Scene::Impl::release) {}
void Scene::draw(Scalar alpha, const Camera& cam) const
}
+OctreePtr Scene::getOctree() const
+{
+ // pass through
+ return impl_->octree;
+}
+
/**
* Specialized search location for scene files. They can be found in the
* "scenes" subdirectory of any of the searched directories.
*/
-std::string Scene::getPathToResource(const std::string& name)
+std::string Scene::getPath(const std::string& name)
{
- return Resource::getPathToResource("scenes/" + name + ".json");
+ return Resource::getPath("scenes/" + name + ".json");
}
#include <boost/shared_ptr.hpp>
#include <Moof/Drawable.hh>
+#include <Moof/Octree.hh>
#include <Moof/Resource.hh>
void draw(Scalar alpha, const Camera& cam) const;
void refresh();
- static std::string getPathToResource(const std::string& name);
+ OctreePtr getOctree() const;
+
+ static std::string getPath(const std::string& name);
private:
- class SceneImpl;
- boost::shared_ptr<SceneImpl> impl_;
+ class Impl;
+ boost::shared_ptr<Impl> impl_;
};
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <iostream>
+#include <string>
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_sound.h>
+#include <AL/al.h>
+
+#include "Mippleton.hh"
+#include "Sound.hh"
+
+
+namespace Mf {
+
+
+struct Sound::Impl
+{
+
+ static ALenum getAudioFormat(const Sound_AudioInfo& audioInfo)
+ {
+ if (audioInfo.format == AUDIO_U8 || audioInfo.format == AUDIO_S8)
+ {
+ if (audioInfo.channels == 1) return AL_FORMAT_MONO8;
+ else return AL_FORMAT_STEREO8;
+ }
+ else
+ {
+ if (audioInfo.channels == 1) return AL_FORMAT_MONO16;
+ else return AL_FORMAT_STEREO16;
+ }
+ }
+
+ struct Buffer : public Mippleton<Buffer>
+ {
+ Buffer(const std::string& name) :
+ Mippleton<Buffer>(name),
+ object(0)
+ {}
+
+ ~Buffer()
+ {
+ alDeleteBuffers(1, &object);
+ }
+ void loadFromFile(const std::string& filePath, bool stream)
+ {
+ if (object != 0) return;
+
+ Sound_Sample* sound = Sound_NewSampleFromFile(filePath.c_str(),
+ NULL, 8096);
+
+ if (!sound)
+ {
+ std::cerr << "could not load sound from file" << std::endl;
+ exit(1);
+ }
+
+ unsigned decoded = Sound_DecodeAll(sound);
+ if (decoded == 0)
+ {
+ std::cout << "decoded no bytes" << std::endl;
+ exit(1);
+ }
+ std::cerr << "buffer size: " << sound->buffer_size << std::endl;
+ std::cerr << "channels: " << (int)sound->actual.channels << std::endl;
+ std::cerr << "format: " << sound->actual.format << std::endl;
+ std::cerr << "frequency: " << sound->actual.rate << std::endl;
+
+ alGenBuffers(1, &object);
+ alBufferData(object, getAudioFormat(sound->actual), sound->buffer,
+ sound->buffer_size, sound->actual.rate);
+
+ Sound_FreeSample(sound);
+ }
+
+ ALuint object;
+
+ //ALfloat location[] = {0.0f, 0.0f, 0.0f};
+ //ALfloat location2[] = {0.0f, 0.0f, 0.0f};
+ //ALfloat orient[] = {0.0f, 0.0f, -1.0f, 0.0, 1.0, 0.0};
+
+
+ //alListenerfv(AL_POSITION, location);
+ //alListenerfv(AL_VELOCITY, location);
+ //alListenerfv(AL_VELOCITY, orient);
+ };
+
+ Impl(const std::string& name, bool stream = false) :
+ buffer_(Buffer::retain(name), Buffer::release)
+ {
+ if (!stream) buffer_->loadFromFile(Sound::getPath(name), stream);
+ else buffer_->loadFromFile(SoundStream::getPath(name), stream);
+
+ ALfloat location[] = {0.0f, 0.0f, 0.0f};
+
+ alGenSources(1, &source_);
+ alSourcei(source_, AL_BUFFER, buffer_->object);
+ alSourcef(source_, AL_PITCH, 1.0f);
+ alSourcef(source_, AL_GAIN, 1.0f);
+ alSourcefv(source_, AL_POSITION, location);
+ alSourcefv(source_, AL_VELOCITY, location);
+ alSourcei(source_, AL_LOOPING, AL_FALSE);
+ }
+
+ ~Impl()
+ {
+ alDeleteSources(1, &source_);
+ }
+
+
+ void update()
+ {
+ }
+
+
+ boost::shared_ptr<Buffer> buffer_;
+ ALuint source_;
+};
+
+
+Sound::Sound(const std::string& name) :
+ // pass through
+ impl_(new Sound::Impl(name)) {}
+
+
+void Sound::play()
+{
+ alSourceRewind(impl_->source_);
+ alSourcePlay(impl_->source_);
+}
+
+
+std::string Sound::getPath(const std::string& name)
+{
+ std::string path = Resource::getPath("sounds/" + name + ".ogg");
+ return path;
+}
+
+
+//##############################################################################
+
+
+SoundStream::SoundStream(const std::string& name)
+ // pass through
+ //impl_(name, true) {}
+{
+ impl_ = boost::shared_ptr<Sound::Impl>(new Sound::Impl(name, true));
+}
+
+
+void SoundStream::update(Scalar t, Scalar dt)
+{
+ // pass through
+ impl_->update();
+}
+
+
+std::string SoundStream::getPath(const std::string& name)
+{
+ std::string path = Resource::getPath("sounds/" + name + ".xm");
+ return path;
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _MOOF_SOUND_HH_
+#define _MOOF_SOUND_HH_
+
+/**
+ * @file Sound.hh
+ * Image-loading and OpenGL texture loading.
+ */
+
+#include <stdexcept>
+
+#include <boost/shared_ptr.hpp>
+
+#include <Moof/Math.hh>
+#include <Moof/Resource.hh>
+
+
+namespace Mf {
+
+
+class Sound : public Resource
+{
+public:
+ Sound(const std::string& name);
+
+ void play();
+
+ static std::string getPath(const std::string& name);
+
+ struct Exception : std::runtime_error
+ {
+ explicit Exception(const std::string& what_arg) :
+ std::runtime_error(what_arg) {}
+ };
+
+protected:
+ Sound() {}
+ class Impl;
+ boost::shared_ptr<Impl> impl_;
+};
+
+
+class SoundStream : public Sound
+{
+public:
+ SoundStream(const std::string& name);
+
+ void update(Scalar t, Scalar dt);
+
+ static std::string getPath(const std::string& name);
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_SOUND_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _MOOF_STATE_HH_
+#define _MOOF_STATE_HH_
+
+#include <Moof/Math.hh>
+
+
+namespace Mf {
+
+
+template <typename T>
+struct Derivative
+{
+ inline virtual ~Derivative() {}
+
+ virtual T operator*(Scalar dt) const = 0;
+ virtual T operator+(const T& other) const = 0;
+};
+
+
+/**
+ * Structure containing any information needed to place and orient an animate
+ * object in 3-space as well as predict future locations and orientations.
+ */
+
+template <typename T, typename D>
+struct State
+{
+ inline virtual ~State() {}
+
+ inline D evaluate(Scalar t)
+ {
+ D derivative;
+ calculateDerivatives(derivative, t);
+ return derivative;
+ }
+
+ inline D evaluate(Scalar t, Scalar dt, const D& derivative)
+ {
+ T state = *this;
+ state += derivative * dt;
+ state.recalculate();
+
+ D newDerivative;
+ calculateDerivatives(newDerivative, t);
+ return newDerivative;
+ }
+
+ inline void integrate(Scalar t, Scalar dt)
+ {
+ D a = evaluate(t);
+ D b = evaluate(t, dt * 0.5, a);
+ D c = evaluate(t, dt * 0.5, b);
+ D d = evaluate(t, dt, c);
+
+ *this += (a + (b + c) * 2.0 + d) * (1.0/6.0) * dt;
+ }
+
+ virtual void recalculate() {}
+
+ virtual void calculateDerivatives(D& derivative, Scalar t) = 0;
+ virtual T interpolate(Scalar alpha, const T& prevState) const = 0;
+
+ virtual T& operator+=(const D& derivative) = 0;
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_STATE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
* objects and avoid having duplicate textures loaded to GL.
*/
-class Texture::TextureImpl : public Mippleton<TextureImpl>
+class Texture::Impl : public Mippleton<Impl>
{
/**
* Construction is initialization.
*/
- explicit TextureImpl(const std::string& name) :
- Mippleton<TextureImpl>(name),
+ explicit Impl(const std::string& name) :
+ Mippleton<Impl>(name),
surface_(0),
width_(0),
height_(0),
// we want to know when the GL context is recreated
Dispatcher::instance().addHandler("video.context_recreated",
- boost::bind(&TextureImpl::contextRecreated, this, _1), this);
+ boost::bind(&Impl::contextRecreated, this, _1), this);
}
- ~TextureImpl()
+ ~Impl()
{
if (surface_)
{
{
SDL_Surface* surface;
- surface = IMG_Load(Texture::getPathToResource(getName()).c_str());
+ surface = IMG_Load(Texture::getPath(getName()).c_str());
if (!surface)
{
static GLuint globalObject_; ///< Global GL texture handle.
};
-GLuint Texture::TextureImpl::globalObject_ = 0;
+GLuint Texture::Impl::globalObject_ = 0;
Texture::Texture(const std::string& name) :
// pass through
- impl_(Texture::TextureImpl::retain(name), &Texture::TextureImpl::release)
-{}
+ impl_(Texture::Impl::retain(name), &Texture::Impl::release) {}
/**
void Texture::resetBind()
{
glBindTexture(GL_TEXTURE_2D, 0);
- TextureImpl::globalObject_ = 0;
+ Impl::globalObject_ = 0;
}
}
-std::string Texture::getPathToResource(const std::string& name)
+std::string Texture::getPath(const std::string& name)
{
- // TODO named texture resources must be png for now
- return Resource::getPathToResource("textures/" + name + ".png");
+ std::string path = Resource::getPath("textures/" + name + ".png");
+ return path;
}
void setWrapS(GLuint wrap);
void setWrapT(GLuint wrap);
- static std::string getPathToResource(const std::string& name);
+ static std::string getPath(const std::string& name);
struct Exception : std::runtime_error
{
};
private:
- class TextureImpl;
- boost::shared_ptr<TextureImpl> impl_;
+ class Impl;
+ boost::shared_ptr<Impl> impl_;
};
namespace Mf {
-class Tilemap::TilemapImpl : public Mippleton<TilemapImpl>
+class Tilemap::Impl : public Mippleton<Impl>
{
static GLint filterFromString(const std::string& filter)
{
}
public:
- TilemapImpl(const std::string& name) :
- Mippleton<TilemapImpl>(name),
+ Impl(const std::string& name) :
+ Mippleton<Impl>(name),
magFilter_(GL_NEAREST),
minFilter_(GL_NEAREST),
nTilesS_(1),
void loadFromFile()
{
- Deserializer deserializer(Tilemap::getPathToResource(getName()));
+ Deserializer deserializer(Tilemap::getPath(getName()));
SerializablePtr root = deserializer.deserialize();
Tilemap::Tilemap(const std::string& name) :
Texture(name),
- impl_(Tilemap::TilemapImpl::retain(name), &Tilemap::TilemapImpl::release)
+ impl_(Tilemap::Impl::retain(name), &Tilemap::Impl::release)
{
- bind();
-
setMinFilter(impl_->minFilter_);
setMagFilter(impl_->magFilter_);
setWrapS(impl_->wrapS_);
}
-std::string Tilemap::getPathToResource(const std::string& name)
+std::string Tilemap::getPath(const std::string& name)
{
- return Resource::getPathToResource("tilemaps/" + name + ".json");
+ return Resource::getPath("tilemaps/" + name + ".json");
}
bool getTileCoords(Index index, Scalar coords[8], Orientation what) const;
- static std::string getPathToResource(const std::string& name);
+ static std::string getPath(const std::string& name);
private:
- class TilemapImpl;
- boost::shared_ptr<TilemapImpl> impl_;
+ class Impl;
+ boost::shared_ptr<Impl> impl_;
};
#include "YoinkApp.hh"
+#include <SDL/SDL_sound.h>
+#include <AL/al.h>
+#include <AL/alut.h>
+
#if HAVE_CONFIG_H
#include "config.h"
#endif
// then look in the configured data directory
Mf::Resource::addSearchPath(YOINK_DATADIR);
- return Mf::Resource::getPathToResource("yoink.png");
+ return Mf::Resource::getPath("yoink.png");
}
YoinkApp::YoinkApp(int argc, char* argv[]) :
- Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile())
+ Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile()),
+ music("NightFusion"),
+ punchSound("RobotPunch")
{
Mf::Dispatcher::instance().addHandler("video.context_recreated",
boost::bind(&YoinkApp::contextRecreated, this, _1), this);
setupGL();
+ music.play();
+
state = 0.0;
- someChar = new Character("RobotTrooper");
- someChar->getAnimation().startSequence("Run");
+ heroine = CharacterPtr(new Character("RobotTrooper"));
+ heroine->getAnimation().startSequence("Run");
font = new TilemapFont;
- Mf::Vector2 coeffs[4];
- coeffs[0] = Mf::Vector2(0.0, 0.0);
- coeffs[1] = Mf::Vector2(0.5, 0.0);
- coeffs[2] = Mf::Vector2(0.5, 0.0);
- coeffs[3] = Mf::Vector2(1.0, 0.0);
+ Mf::Scalar coeffs[4];
+ coeffs[0] = 0.0;
+ coeffs[1] = 1.5;
+ coeffs[2] = -0.5;
+ coeffs[3] = 1.0;
interp.init(coeffs, 1.0, Mf::Interpolator::OSCILLATE);
Mf::Scalar coeff[2] = {1.0, 0.0};
- fadeIn.init(coeff, 0.5f);
+ fadeIn.init(coeff, 0.1);
testScene = new Mf::Scene("Test");
-
- x = y = z = 0.0;
+ heroine->treeNode = testScene->getOctree()->insert(heroine);
}
YoinkApp::~YoinkApp()
{
- delete someChar;
+ //delete heroine;
delete font;
delete testScene;
camera.update(t, dt);
- someChar->getAnimation().update(t, dt);
+ heroine->update(t, dt);
+ heroine->treeNode = testScene->getOctree()->reinsert(heroine, heroine->treeNode);
+
+ //camera.lookAt(heroine->getSphere().point);
+ camera.setPosition(Mf::Vector3(-heroine->current.position[0], -heroine->current.position[1], -256));
+
interp.update(dt);
+ hud.setBar1Progress(interp.getValue());
+ hud.setBar2Progress(1.0 - interp.getValue());
prevstate = state;
state += dt;
//Mf::Scalar cosstate = std::cos(drawstate);
-
glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
- glBindTexture(GL_TEXTURE_2D, 0);
//glRotatef(drawstate*15.0f, 0.0, 1.0, 0.0);
//glTranslatef(x, y, z);
glLoadMatrix(camera.getModelviewMatrix().data());
// DRAW THE SCENE
+ Mf::Texture::resetBind();
testScene->draw(alpha, camera);
+
+ //heroine->draw(alpha);
+
+
+ hud.draw();
+
+
+ glEnable(GL_BLEND);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
+ Mf::Texture::resetBind();
+
+ //glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
+ glBegin(GL_QUADS);
+ glVertex3f(-1.0, -1.0, -0.1);
+ glVertex3f(1.0, -1.0, -0.1);
+ glVertex3f(1.0, 1.0, -0.1);
+ glVertex3f(-1.0, 1.0, -0.1);
+ glEnd();
+
+ glDisable(GL_BLEND);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
/*
glLoadIdentity();
{
getVideo().toggleFull();
}
- else if (event.key.keysym.sym == SDLK_a)
+ else if (event.key.keysym.sym == SDLK_SPACE)
{
- someChar->getAnimation().startSequence("Punch");
+ heroine->getAnimation().startSequence("Punch");
+ punchSound.play();
}
else if (event.key.keysym.sym == SDLK_r)
{
getVideo().toggleCursorGrab();
getVideo().toggleCursorVisible();
}
- //else if (event.key.keysym.sym == SDLK_RIGHT)
- //{
- //x -= 50.0;
- //}
- //else if (event.key.keysym.sym == SDLK_LEFT)
- //{
- //x += 50.0;
- //}
- //else if (event.key.keysym.sym == SDLK_UP)
- //{
- //y -= 50.0;
- //}
- //else if (event.key.keysym.sym == SDLK_DOWN)
- //{
- //y += 50.0;
- //}
- //else if (event.key.keysym.sym == SDLK_PAGEUP)
- //{
- //z += 50.0;
- //}
- //else if (event.key.keysym.sym == SDLK_PAGEDOWN)
- //{
- //z -= 50.0;
- //}
+
+ case SDL_KEYUP:
+ heroine->handleEvent(event);
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN:
case SDL_VIDEORESIZE:
glViewport(0, 0, event.resize.w, event.resize.h);
+ hud.resize(event.resize.w, event.resize.h);
camera.setProjection(cml::rad(60.0), double(event.resize.w / event.resize.h), 32.0, 2500.0);
camera.uploadProjectionToGL();
break;
{
std::cout << PACKAGE_STRING << std::endl
<< "Compiled " << __TIME__ " " __DATE__ << std::endl
- << "Send requests, patches, and bug reports to <"
+ << "Send patches and bug reports to <"
PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
int status = 0;
#include "Character.hh"
#include "TilemapFont.hh"
+#include <Moof/Sound.hh>
+
+#include "Hud.hh"
+
class YoinkApp : public Mf::Engine
{
void setupGL();
void contextRecreated(const Mf::Notification& note);
- Character* someChar;
+ Mf::SoundStream music;
+
+ CharacterPtr heroine;
+ Mf::Sound punchSound;
TilemapFont *font;
- Mf::Cerpv2 interp;
+ Mf::Cerps interp;
Mf::Lerps fadeIn;
Mf::Camera camera;
Mf::Scene* testScene;
- Mf::Scalar x, y, z;
-
Mf::Scalar state;
Mf::Scalar prevstate;
+
+ Hud hud;
};