Copyright: (c) 2002 Bob Pendleton
License: LGPL-2.1
- Portion: libpng12-0.dll
+ Portion: libpng-3.dll
Source: http://www.libpng.org/pub/png/libpng.html
Copyright: (c) 2004, 2006-2009 Glenn Randers-Pehrson
License: libpng
Copyright: (c) 2003 Neil Carter
License: zlib-libpng
- Portion: SDL.dll, SDL_image.dll
+ Portion: SDL.dll
Source: http://www.libsdl.org/
Copyright: (c) 2009 Sam Lantinga et al.
License: LGPL-2.1
b) Requirements
boost headers
+libpng
libvorbis
Lua
OpenAL
OpenGL
SDL
-SDL_image (with libpng support)
c) License
AC_CANONICAL_TARGET
-AC_CONFIG_SRCDIR([src/GameLayer.cc])
+AC_CONFIG_SRCDIR([src/version.c])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
#
if test x$threads = xyes
then
AC_DEFINE([USE_THREADS], 1,
- [Define to 1 if you want to use threads for parallel tasks.])
+ [Define to 1 if you want to use threads when applicable.])
fi
if test x$gtk = xyes
elif test x$qt4 = xyes
then
AC_DEFINE([USE_QT4], 1,
- [Define to 1 if you want to use QT info/error dialogs.])
+ [Define to 1 if you want to use QT4 info/error dialogs.])
fi
AC_DEFINE_UNQUOTED([YOINK_LOGLEVEL], [$log_level],
[missing=yes
echo "***** Missing libopenal ($website) *****"])
-##### SDL_image #####
-website="http://www.libsdl.org/projects/SDL_image/"
-AC_CHECK_HEADERS([SDL/SDL_image.h],,
+##### libpng #####
+website="http://www.libpng.org/pub/png/libpng.html"
+AC_CHECK_HEADERS([png.h],,
[missing=yes
- echo "***** Missing SDL_image header ($website) *****"])
-AC_SEARCH_LIBS([IMG_Load], [SDL_image],,
+ echo "***** Missing libpng header ($website) *****"])
+AC_SEARCH_LIBS([png_sig_cmp], [png],,
[missing=yes
- echo "***** Missing libSDL_image ($website) *****"])
+ echo "***** Missing libpng ($website) *****"])
##### libvorbis #####
website="http://www.xiph.org/downloads/"
#
-# Find the data files to install.
+# Find the game resources to install.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-DATA_FILES=$(echo $(cd data; \
- find . -name "*.lua" \
- -o -name "*.ogg" \
- -o -name "*.png" \
- -o -name "yoinkrc"))
+DATA_FILES=$(echo $(cd data && find . -name "*.lua" \
+ -o -name "*.ogg" \
+ -o -name "*.png" \
+ -o -name "yoinkrc"))
AC_SUBST([DATA_FILES])
if test x$WIN32 = xyes
then
- AC_CONFIG_FILES([win32/Makefile win32/mkpackage.sh])
+ AC_CONFIG_FILES([win32/Makefile win32/mkpackage.sh win32/yoink.nsi])
fi
-- created by Neil Carter
-- converted to Lua by Charles McGarvey
+LogInfo("-----", "Scene: Classic", "Created by Neil Carter",
+ "Converted to Lua by Charles McGarvey", "-----")
+
-- Scene API:
--
-- Functions:
-- Front
ResetTransform()
-Translate(-5, 0, 5)
+Translate(-5, 0, 2)
SetTexture("TowerBlock1")
DrawTilemap({
width = 5,
ResetTransform()
Rotate(Y, 90)
-Translate(0, 0, 5)
+Translate(0, 0, 2)
DrawTilemap({
width = 5,
surface = RIGHT,
ResetTransform()
Rotate(X, 90)
-Translate(-5, 15, 0)
+Translate(-5, 15, -3)
DrawTilemap({
width = 5,
surface = TOP,
if detail > LOW then
ResetTransform()
+ Translate(0, 0, -3)
DrawTilemap({
width = 7,
2, 2, 2, 2, 2, 2, 2,
ResetTransform()
Rotate(Y, 90)
- Translate(7, 0, 0)
+ Translate(7, 0, -3)
DrawTilemap({
width = 6,
2, 2, 2, 2, 2, 2,
ResetTransform()
Rotate(X, 90)
- Translate(-2, 8, -6)
+ Translate(-2, 8, -9)
DrawTilemap({
width = 9,
3, 3, 3, 3, 3, 3, 3, 3, 3,
ResetTransform()
Rotate(Y, -90)
-Translate(10, 0, 1)
+Translate(10, 0, -2)
SetTexture("Building")
DrawTilemap({
width = 4,
ResetTransform()
Rotate(Y, -90)
-Translate(13, 0, 1)
+Translate(13, 0, -2)
DrawTilemap({
width = 4,
surface = RIGHT,
-- Front wall
ResetTransform()
-Translate(10, 0, 5)
+Translate(10, 0, 2)
DrawTilemap({
width = 3,
15, 7, 16,
ResetTransform()
Rotate(X, 135)
Scale(1, 1.5, 1.5)
-Translate(10, 5, 3)
+Translate(10, 5, 0)
DrawTilemap({
width = 3,
13, 13, 13,
-- Finial
ResetTransform()
-Translate(10, 5, 3)
+Translate(10, 5, -0.00001)
DrawTilemap({
width = 3,
18, 18, 18})
ResetTransform()
Rotate(X, 90)
-Translate(-3, 0, 0)
+Translate(-3, 0, -3)
SetTexture("Scenery")
DrawTilemap({
width = 13,
if detail > MEDIUM then
ResetTransform()
Scale(8, 1, 1)
- Translate(1, -0.5, 5)
+ Translate(1, -0.5, 2)
DrawTile({
2,
u_scale = 8})
ResetTransform()
Scale(8, 1, 1)
- Translate(1, -0.5, 1)
+ Translate(1, -0.5, -2)
DrawTile({
2,
u_scale = 8
ResetTransform()
Scale(4, 1, 1)
Rotate(Y, -90)
- Translate(1, -0.5, 1)
+ Translate(1, -0.5, -2)
DrawTile({
2,
u_scale = 4
ResetTransform()
Scale(4, 1, 1)
Rotate(Y, -90)
- Translate(9, -0.5, 1)
+ Translate(9, -0.5, -2)
DrawTile({
2,
u_scale = 4
ResetTransform()
Scale(11, 1, 1)
- Translate(7, 0, 0)
+ Translate(7, 0, -3)
DrawTile({
4,
u_scale = 11
if detail > LOW then
ResetTransform()
- Translate(19, 0, 0)
+ Translate(19, 0, -3)
SetTexture("Building")
DrawTilemap({
width = 4,
ResetTransform()
Rotate(Y, -90)
- Translate(19, 0, -3)
+ Translate(19, 0, -6)
DrawTilemap({
width = 3,
15, 1, 16,
ResetTransform()
Rotate(Y, -90)
- Translate(23, 0, -3)
+ Translate(23, 0, -6)
DrawTilemap({
width = 3,
15, 0, 16,
Rotate(X, 135)
Scale(1, 1.5, 1.5)
Rotate(Y, -90)
- Translate(21, 6, -3)
+ Translate(21, 6, -6)
DrawTilemap({
width = 3,
13, 13, 13,
Rotate(X, -135)
Scale(1, 1.5, 1.5)
Rotate(Y, -90)
- Translate(21, 6, -3)
+ Translate(21, 6, -6)
DrawTilemap({
width = 3,
13, 13, 13,
ResetTransform()
Rotate(Y, -90)
- Translate(21, 6, -3)
+ Translate(21, 6, -6)
DrawTilemap({
width = 3,
18, 18, 18})
ResetTransform()
Rotate(X, 90)
-Translate(10, 0, 0)
+Translate(10, 0, -3)
SetTexture("Scenery")
DrawTilemap({
width = 3,
ResetTransform()
Rotate(X, 90)
-Translate(13, 0, 0)
+Translate(13, 0, -3)
DrawTilemap({
width = 8,
surface = TOP,
if detail > MEDIUM then
ResetTransform()
Scale(12, 1, 1)
- Translate(14, -0.5, 5)
+ Translate(14, -0.5, 2)
DrawTile({
2,
u_scale = 12
ResetTransform()
Scale(4, 1, 1)
- Translate(14, -0.5, 1)
+ Translate(14, -0.5, -2)
DrawTile({
2,
u_scale = 4
-- Front grass next to door
ResetTransform()
- Translate(13, -0.5, 3)
+ Translate(13, -0.5, 0)
DrawTile({
2,
u_scale = 1
-- Back grass next to door
ResetTransform()
- Translate(13, -0.5, 2)
+ Translate(13, -0.5, -1)
DrawTile({
2,
u_scale = 1
ResetTransform()
Rotate(Y, -90)
- Translate(14, -0.5, 1)
+ Translate(14, -0.5, -2)
DrawTilemap({
width = 4,
2, -1, 2, 2})
ResetTransform()
Rotate(Y, -90)
- Translate(18, -0.5, 0)
+ Translate(18, -0.5, -3)
DrawTile({
2,
u_scale = 1
ResetTransform()
Rotate(Y, -90)
- Translate(24, -0.5, 0)
+ Translate(24, -0.5, -3)
DrawTile({
2,
u_scale = 1
ResetTransform()
Scale(4, 1, 1)
- Translate(19, -0.5, 4)
+ Translate(19, -0.5, 1)
DrawTile({
2,
u_scale = 4
ResetTransform()
Scale(4, 1, 1)
- Translate(19, -0.5, 2)
+ Translate(19, -0.5, -1)
DrawTile({
2,
u_scale = 4
ResetTransform()
Scale(2, 1, 1)
Rotate(Y, -90)
- Translate(19, -0.5, 2)
+ Translate(19, -0.5, -1)
DrawTile({
2,
u_scale = 2
ResetTransform()
Scale(2, 1, 1)
Rotate(Y, -90)
- Translate(23, -0.5, 2)
+ Translate(23, -0.5, -1)
DrawTile({
2,
u_scale = 2
ResetTransform()
Rotate(X, 90)
-Translate(21, 0, 0)
+Translate(21, 0, -3)
DrawTilemap({
width = 7,
surface = TOP,
if detail > MEDIUM then
ResetTransform()
Scale(4, 1, 1)
- Translate(24, 0, 0)
+ Translate(24, 0, -3)
DrawTile({
4,
u_scale = 4
ResetTransform()
Scale(4, 1, 1)
- Translate(24, -0.5, 1)
+ Translate(24, -0.5, -2)
DrawTile({
2,
u_scale = 4
ResetTransform()
Scale(2, 1, 1)
Rotate(Y, -90)
- Translate(26, -0.5, 5)
+ Translate(26, -0.5, 2)
DrawTile({
2,
u_scale = 2
ResetTransform()
Scale(2, 1, 1)
Rotate(Y, -90)
- Translate(35, -0.5, 5)
+ Translate(35, -0.5, 2)
DrawTile({
2,
u_scale = 2
ResetTransform()
Scale(5, 1, 1)
- Translate(35, -0.5, 5)
+ Translate(35, -0.5, 2)
DrawTile({
2,
u_scale = 5
ResetTransform()
Scale(6, 1, 1)
- Translate(34, -0.5, 1)
+ Translate(34, -0.5, -2)
DrawTile({
2,
u_scale = 6
ResetTransform()
Rotate(Y, -90)
- Translate(34, -0.5, 0)
+ Translate(34, -0.5, -3)
DrawTile({
2,
u_scale = 1
ResetTransform()
Rotate(X, 90)
-Translate(28, 0, 4)
+Translate(28, 0, 1)
DrawTilemap({
width = 5,
surface = TOP,
ResetTransform()
Rotate(X, 90)
-Translate(33, 0, 0)
+Translate(33, 0, -3)
DrawTilemap({
width = 10,
surface = TOP,
-- Front
ResetTransform()
-Translate(28, 0, 4)
+Translate(28, 0, 1)
SetTexture("TowerBlock1")
DrawTilemap({
width = 5,
ResetTransform()
Rotate(Y, 90)
-Translate(33, 0, 4)
+Translate(33, 0, 1)
DrawTilemap({
width = 6,
surface = RIGHT,
ResetTransform()
Rotate(Y, 90)
-Translate(28, 0, 4)
+Translate(28, 0, 1)
DrawTilemap({
width = 6,
surface = LEFT,
ResetTransform()
Rotate(X, 90)
-Translate(28, 7, -2)
+Translate(28, 7, -5)
DrawTilemap({
width = 5,
surface = TOP,
-- Front
ResetTransform()
-Translate(40, 0, 5)
+Translate(40, 0, 2)
DrawTilemap({
width = 5,
2, 2, 2, 2, 2,
ResetTransform()
Rotate(Y, 90)
-Translate(40, 0, 5)
+Translate(40, 0, 2)
DrawTilemap({
width = 5,
surface = LEFT,
ResetTransform()
Rotate(X, 90)
-Translate(40, 15, 0)
+Translate(40, 15, -3)
DrawTilemap({
width = 5,
surface = TOP,
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ResetTransform()
-Translate(-0.32, -0.28, -24)
+Translate(-0.32, -0.28, -27)
Scale(105, 52, 1)
SetTexture("BackgroundFar")
DrawTile()
if detail > LOW then
ResetTransform()
Scale(3)
- Translate(7.75, -0.1, 0.5)
+ Translate(7.75, -0.1, -2.5)
DrawTile(1)
end
-- Center courtyard
ResetTransform()
---Translate(610, -2.5, 85)
Scale(3)
-Translate(19, -0.1, 2.5)
+Translate(19, -0.1, -0.5)
DrawTile(0)
ResetTransform()
Scale(3)
-Translate(20.25, -0.1, 3.5)
+Translate(20.25, -0.1, 0.5)
DrawTile(1)
-- Right courtyard
if detail > LOW then
ResetTransform()
Scale(3)
- Translate(34, -0.1, 0.25)
+ Translate(34, -0.1, -2.75)
DrawTile(1)
ResetTransform()
Scale(3)
- Translate(36, -0.1, -0.5)
+ Translate(36, -0.1, -3.5)
DrawTile(0)
ResetTransform()
Scale(3)
- Translate(37, -0.1, 0.75)
+ Translate(37, -0.1, -2.25)
DrawTile(1)
end
-function GetZCoord(x, y)
- return 3.00001
-end
-
-
-- Functions:
-- DisplayText(text, seconds)
-- Yield(seconds)
-- BeginNewWave()
-- Events:
+-- Think() is called periodically
-- BadGuyDied(enemy)
--- PlayedDied(player)
--- SceneLoaded()
+-- HeroineDied(player)
-- Globals:
-- numberOfBadGuys
+--do
+ --SpawnHeroine({5, 5})
+ --local waveNum = BeginNewWave()
+ --PopulateScene(waveNum)
+--end
+
+
-- Events
---------
Event = {}
-function Event:SceneLoaded()
- SpawnHeroine({500, 500})
- local waveNum = BeginNewWave()
- PopulateScene(waveNum)
+function Event:Think()
end
function Event:BadGuyDied(enemy)
end
function RandomSpawnPlace()
- return {500, 500}
+ return {5, 5}
end
function RandomSkillLevel()
end
--- vim: tw=80 ts=4
+-- vim: ts=4 sw=4 tw=80
-- that make up the video mode. A typical value is 800,600 for a size of
-- 800x600 pixels with millions of colors (the third number is optional).
-videomode = {1024, 786}
+videomode = {800, 600}
-- Set whether or not the cursor will be visible when you mouse over the
-- display of the game.
-showcursor = false
+showcursor = true
-- Set whether or not the drawing should use two buffers. This results in
-- a higher quality animation. You should usually leave this as true.
Copyright (c) <year> <copyright holders>
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
IUSE="debug double-precision gtk qt4 threads"
RDEPEND="dev-lang/lua
+ media-libs/libpng
media-libs/libsdl[opengl]
media-libs/libvorbis
media-libs/openal
- media-libs/sdl-image[png]
+ virtual/glu
virtual/opengl"
DEPEND="${RDEPEND}
dev-libs/boost
std::string filePath = Animation::getPath(getName());
script.importBaseLibrary();
- importLogPrintFunction(script);
+ importLogFunctions(script);
importAnimationBindings(script);
if (script.doFile(filePath) != Mf::Script::SUCCESS)
Character::Character(const std::string& name) :
- tilemap(name),
+ tilemap("Particles"),
animation(name)
{
mState.init();
animation.update(t, dt);
- Mf::Vector3 center(mState.position[0], mState.position[1], mZCoord);
- Mf::Vector3 a(mState.position[0] - 0.5, mState.position[1] - 0.5, mZCoord);
- Mf::Vector3 b(mState.position[0] + 0.5, mState.position[1] + 0.5, mZCoord);
+ Mf::Vector3 center(mState.position[0], mState.position[1], 0.0);
+ Mf::Vector3 a(mState.position[0] - 0.5, mState.position[1] - 0.5, 0.0);
+ Mf::Vector3 b(mState.position[0] + 0.5, mState.position[1] + 0.5, 0.0);
mAabb.init(a, b);
mSphere.init(center, a);
glBegin(GL_TRIANGLE_FAN);
glTexCoord(coords[0], coords[1]);
- glVertex(position[0]-s, position[1]-s, mZCoord);
+ glVertex(position[0]-s, position[1]-s);
glTexCoord(coords[2], coords[3]);
- glVertex(position[0]+s, position[1]-s, mZCoord);
+ glVertex(position[0]+s, position[1]-s);
glTexCoord(coords[4], coords[5]);
- glVertex(position[0]+s, position[1]+s, mZCoord);
+ glVertex(position[0]+s, position[1]+s);
glTexCoord(coords[6], coords[7]);
- glVertex(position[0]-s, position[1]+s, mZCoord);
+ glVertex(position[0]-s, position[1]+s);
glEnd();
}
-void Character::setZCoord(Mf::Scalar z)
-{
- mZCoord = z;
-}
-
-int Character::getOctant(const Mf::Aabb<3>& aabb) const
+/*int Character::getOctant(const Mf::Aabb<3>& aabb) const
{
int octantNum = -1;
return octantNum;
}
+*/
void Character::addImpulse(Mf::Vector2 impulse)
#include <Moof/Aabb.hh>
#include <Moof/Entity.hh>
#include <Moof/Math.hh>
-#include <Moof/Octree.hh>
#include <Moof/RigidBody.hh>
#include <Moof/Sphere.hh>
* includes the heroine herself and the bad guys.
*/
-class Character : public Mf::RigidBody2, public Mf::OctreeInsertable
+class Character : public Mf::RigidBody2
{
public:
virtual void update(Mf::Scalar t, Mf::Scalar dt);
virtual void draw(Mf::Scalar alpha) const;
- void setZCoord(Mf::Scalar z);
-
void addImpulse(Mf::Vector2 impulse);
void addForce(Mf::Vector2 force);
void setPosition(Mf::Vector2 position);
- virtual int getOctant(const Mf::Aabb<3>& aabb) const;
+ //virtual int getOctant(const Mf::Aabb<3>& aabb) const;
Tilemap tilemap;
Animation animation;
-
-private:
-
- mutable Mf::Scalar mZCoord;
};
#endif
-
-Mf::Scalar GameLayer::getZCoord(const Mf::Vector2& position) const
-{
- Mf::Scalar z;
-
- mState.script.getGlobalTable().pushField("GetZCoord");
- mState.script.push(position[0]);
- mState.script.push(position[1]);
- mState.script.call(2, 1);
- mState.script.getTop().get(z);
- mState.script.pop();
-
- return z;
-}
-
void GameLayer::loadSceneLoader()
{
mState.script.importStandardLibraries();
- importLogPrintFunction(mState.script);
+ importLogFunctions(mState.script);
std::string loaderPath = Scene::getPath("loader");
if (loaderPath == "")
throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str);
}
+
+ mState.script.getGlobalTable().pushField("Event");
+ if (mState.script[-1].isTable())
+ {
+ mState.script[-1].pushField("Think");
+ mState.script.set("Think", Mf::Script::REGISTRY);
+ mState.script.pop(2);
+ }
+ else
+ {
+ mState.script.pop();
+ }
}
}
loadSceneLoader();
advanceScene(); // load the first scene
+ mThinkTimer.init(boost::bind(&GameLayer::thinkTimer, this),
+ 0.1, Mf::Timer::REPEAT);
+
mState.heroine = Heroine::alloc();
- mState.heroine->animation.startSequence("FlyDiagonallyUp");
+ mState.heroine->animation.startSequence("GreenDiamond");
Mf::Scalar a[6] = {0.0, 1.5, -0.5, 3.0, -2.0, 1.0};
- mState.interp.init(a, 2.0, Mf::Interpolator::OSCILLATE);
+ mState.interp.init(a, 5.0, Mf::Interpolator::OSCILLATE);
setProjection();
}
mState.scene->checkForCollision(*mState.heroine);
mState.camera.setPosition(Mf::Vector3(-mState.heroine->getState().position[0],
- -mState.heroine->getState().position[1], -9));
+ -mState.heroine->getState().position[1], -6));
//mState.camera.lookAt(Mf::promote(mState.heroine->getState().position));
mRay.point = mState.heroine->getState().position;
}
+void GameLayer::thinkTimer()
+{
+ mState.script.getRegistryTable().pushField("Think");
+ if (mState.script[-1].isFunction()) mState.script.call();
+ else mState.script.pop();
+}
+
void GameLayer::rayTimer()
{
{
hits.front().normal.normalize();
mRay.solve(point, hits.front().distance);
- Mf::logDebug << "scene: d = " << hits.front().distance << std::endl;
- Mf::logDebug << " P = " << point << std::endl;
- Mf::logDebug << " n = " << hits.front().normal << std::endl;
+ Mf::logInfo << "scene: d = " << hits.front().distance << std::endl;
+ Mf::logInfo << " P = " << point << std::endl;
+ Mf::logInfo << " n = " << hits.front().normal << std::endl;
}
}
mState.scene->drawIfVisible(alpha, mState.camera.getFrustum());
- mState.heroine->setZCoord(getZCoord(mState.heroine->getState().position));
mState.heroine->draw(alpha);
mRay.draw();
cml::rad(-10.0));
return true;
}
+ else if (event.key.keysym.sym == SDLK_r)
+ {
+ loadSceneLoader();
+ advanceScene();
+ return true;
+ }
return mState.heroine->handleEvent(event);
case SDL_KEYUP:
struct State
{
- // the script object must be mutable because some script functions must be
- // called during draw
- mutable Mf::Script script;
+ Mf::Script script;
std::vector<std::string> sceneList;
HeroineP heroine;
void loadSceneLoader();
void advanceScene();
- Mf::Scalar getZCoord(const Mf::Vector2& position) const;
+ void thinkTimer();
void setProjection();
void setProjection(Mf::Scalar width, Mf::Scalar height);
State mState;
+ Mf::Timer mThinkTimer;
+
Mf::SoundStream mMusic;
Mf::Sound mPunchSound;
Heroine::Heroine() :
- Character("Heroine") {}
+ Character("Effects") {}
void Heroine::update(Mf::Scalar t, Mf::Scalar dt)
{
// this is the only layer left on the stack
//engine.push(TitleLayer::alloc());
+ engine.clear();
}
}
atexit(goodbye);
-#if YOINK_LOGLEVEL >= 4
- Mf::Log::setLevel(Mf::Log::DEBUGG);
-#elif YOINK_LOGLEVEL >= 3
+#if YOINK_LOGLEVEL >= 3
Mf::Log::setLevel(Mf::Log::INFO);
#elif YOINK_LOGLEVEL >= 2
- Mf::Log::setLevel(Mf::Log::SCRIPT);
+ Mf::Log::setLevel(Mf::Log::WARNING);
#elif YOINK_LOGLEVEL >= 1
Mf::Log::setLevel(Mf::Log::ERROR);
#elif YOINK_LOGLEVEL
Moof/Frustum.hh \
Moof/Hash.cc \
Moof/Hash.hh \
+ Moof/Image.cc \
+ Moof/Image.hh \
Moof/Interpolator.hh \
Moof/Layer.hh \
Moof/Library.hh \
{
char vdName[128];
SDL_VideoDriverName(vdName, sizeof(vdName));
- logDebug << "initialized SDL; using video driver `"
+ logInfo << "initialized SDL; using video driver `"
<< vdName << "'" << std::endl;
}
else
{
alcMakeContextCurrent(mAlContext);
- logDebug << "opened sound device `"
+ logInfo << "opened sound device `"
<< alcGetString(mAlDevice, ALC_DEFAULT_DEVICE_SPECIFIER)
<< "'" << std::endl;
}
{
ASSERT(layer && "cannot push null layer");
mStack.push_front(layer);
- logDebug << "stack: " << mStack.size()
+ logInfo << "stack: " << mStack.size()
<< " [pushed " << layer.get() << "]" << std::endl;
layer->pushed(mInterface);
}
LayerP layer = mStack.front();
mStack.pop_front();
- logDebug << "stack: " << mStack.size()
+ logInfo << "stack: " << mStack.size()
<< " [popped " << layer.get() << "]" << std::endl;
layer->popped(mInterface);
for (it = layers.begin(); it != layers.end(); ++it)
{
(*it)->popped(mInterface);
- logDebug << "stack: " << mStack.size()
+ logInfo << "stack: " << mStack.size()
<< " [popped " << (*it).get() << "]" << std::endl;
}
{
mStack.clear();
mStackIt = mStack.begin();
- logDebug("stack: 0 [cleared]");
+ logInfo("stack: 0 [cleared]");
}
--- /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 <cstdio> // FILE
+#include <cstring> // strncmp
+
+#include <SDL/SDL.h>
+#include <png.h>
+
+#include "Image.hh"
+#include "Library.hh"
+#include "Log.hh"
+
+
+namespace Mf {
+
+
+class Image::Impl : public Library<Impl>
+{
+public:
+
+ explicit Impl(const std::string& name, bool flipped = false) :
+ Library<Impl>(name),
+ mContext(0),
+ mPixels(0)
+ {
+ init(getName(), flipped);
+ }
+
+ ~Impl()
+ {
+ SDL_FreeSurface(mContext);
+ delete[] mPixels;
+ }
+
+
+ void flip()
+ {
+ unsigned char* pixels = (Uint8*)(mContext->pixels);
+
+ unsigned pitch = mContext->pitch;
+ unsigned char line[pitch];
+
+ int yBegin = 0;
+ int yEnd = mContext->h - 1;
+
+ if (SDL_MUSTLOCK(mContext)) SDL_LockSurface(mContext);
+ while (yBegin < yEnd)
+ {
+ memcpy(line, pixels + pitch * yBegin, pitch);
+ memcpy(pixels + pitch * yBegin, pixels + pitch * yEnd, pitch);
+ memcpy(pixels + pitch * yEnd, line, pitch);
+ yBegin++;
+ yEnd--;
+ }
+ if (SDL_MUSTLOCK(mContext)) SDL_UnlockSurface(mContext);
+ }
+
+ void setAsIcon() const
+ {
+ SDL_WM_SetIcon(mContext, 0);
+ }
+
+
+ SDL_Surface* mContext;
+ char* mPixels;
+
+ unsigned mDepth;
+ GLuint mColorMode;
+
+ std::string mComment;
+
+
+private:
+
+ bool init(const std::string& filePath, bool flipped)
+ {
+ logInfo("opening image file...");
+ FILE* fp = fopen(filePath.c_str(), "rb");
+ if (!fp) return false;
+
+ png_byte signature[8];
+ size_t bytesRead;
+
+ png_infop pngInfo = 0;
+ png_infop pngInfoEnd = 0;
+ png_structp pngObj = 0;
+
+ int width;
+ int height;
+ int pitch;
+ int bpp;
+ int channels;
+
+ png_byte colors;
+ png_bytepp rows = 0;
+
+ png_textp texts = 0;
+ int numTexts;
+
+ logInfo("checking signature...");
+ bytesRead = fread(signature, 1, sizeof(signature), fp);
+ logInfo << "reading " << bytesRead << " bytes of signature" << std::endl;
+ if (bytesRead < sizeof(signature) ||
+ png_sig_cmp(signature, 0, sizeof(signature)) != 0) goto cleanup;
+
+ logInfo("creating png structures...");
+ pngObj = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!pngObj) goto cleanup;
+
+ pngInfo = png_create_info_struct(pngObj);
+ if (!pngInfo) goto cleanup;
+
+ pngInfoEnd = png_create_info_struct(pngObj);
+ if (!pngInfoEnd) goto cleanup;
+
+ logInfo("setting up long jump...");
+ if (setjmp(png_jmpbuf(pngObj))) goto cleanup;
+
+ png_init_io(pngObj, fp);
+ png_set_sig_bytes(pngObj, sizeof(signature));
+ png_read_info(pngObj, pngInfo);
+
+ bpp = png_get_bit_depth(pngObj, pngInfo);
+ logInfo << "texture bpp: " << bpp << std::endl;
+ colors = png_get_color_type(pngObj, pngInfo);
+ switch (colors)
+ {
+ case PNG_COLOR_TYPE_PALETTE:
+ png_set_palette_to_rgb(pngObj);
+ break;
+
+ case PNG_COLOR_TYPE_GRAY:
+ if (bpp < 8) png_set_gray_1_2_4_to_8(pngObj);
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_set_gray_to_rgb(pngObj);
+ break;
+ }
+
+ if (bpp == 16) png_set_strip_16(pngObj);
+
+ png_read_update_info(pngObj, pngInfo);
+
+ bpp = png_get_bit_depth(pngObj, pngInfo);
+ channels = png_get_channels(pngObj, pngInfo);
+ mDepth = bpp * channels;
+
+ logInfo << "texture channels: " << channels << std::endl;
+ if (channels == 3) mColorMode = GL_RGB;
+ else mColorMode = GL_RGBA;
+
+ // read comments
+ png_get_text(pngObj, pngInfo, &texts, &numTexts);
+ logInfo << "num texts: " << numTexts << std::endl;
+ for (int i = 0; i < numTexts; ++i)
+ {
+ if (strncmp(texts[i].key, "Comment", 7) == 0)
+ {
+ mComment = texts[i].text;
+ break;
+ }
+ }
+
+ width = png_get_image_width(pngObj, pngInfo);
+ height = png_get_image_height(pngObj, pngInfo);
+
+ pitch = png_get_rowbytes(pngObj, pngInfo);
+ mPixels = new char[width * pitch];
+
+ rows = new png_bytep[height];
+ if (flipped)
+ {
+ for (int i = 0; i < height; ++i)
+ {
+ rows[height - 1 - i] = (png_bytep)(mPixels + i * channels * width);
+ }
+ }
+ else
+ {
+ for (int i = 0; i < height; ++i)
+ {
+ rows[i] = (png_bytep)(mPixels + i * channels * width);
+ }
+ }
+
+ png_read_image(pngObj, rows);
+ png_read_end(pngObj, 0);
+
+ mContext = SDL_CreateRGBSurfaceFrom
+ (
+ mPixels,
+ width,
+ height,
+ bpp * channels,
+ pitch,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000,
+ 0xFF000000
+#else
+ 0xFF000000,
+ 0x00FF0000,
+ 0x0000FF00,
+ 0x000000FF
+#endif
+ );
+
+ cleanup:
+
+ logInfo("cleaning up...");
+ delete[] rows;
+ png_destroy_read_struct(pngObj ? &pngObj : 0,
+ pngInfo ? &pngInfo : 0,
+ pngInfoEnd ? &pngInfoEnd : 0);
+ fclose(fp);
+
+ return mContext;
+ }
+};
+
+
+Image::Image(const std::string& name) :
+ // pass through
+ mImpl(Image::Impl::getInstance(name)) {}
+
+
+bool Image::isValid() const
+{
+ return mImpl->mContext;
+}
+
+int Image::getWidth() const
+{
+ return mImpl->mContext->w;
+}
+
+int Image::getHeight() const
+{
+ return mImpl->mContext->h;
+}
+
+unsigned Image::getDepth() const
+{
+ return mImpl->mDepth;
+}
+
+unsigned Image::getPitch() const
+{
+ return mImpl->mContext->pitch;
+}
+
+GLuint Image::getColorMode() const
+{
+ return mImpl->mColorMode;
+}
+
+std::string Image::getComment() const
+{
+ return mImpl->mComment;
+}
+
+const char* Image::getPixels() const
+{
+ return mImpl->mPixels;
+}
+
+char* Image::getPixels()
+{
+ return mImpl->mPixels;
+}
+
+
+void Image::flip()
+{
+ // pass through
+ mImpl->flip();
+}
+
+void Image::setAsIcon() const
+{
+ // pass through
+ mImpl->setAsIcon();
+}
+
+
+
+std::string Image::getPath(const std::string& name)
+{
+ std::string path = Resource::getPath("images/" + name + ".png");
+ 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_IMAGE_HH_
+#define _MOOF_IMAGE_HH_
+
+#include <boost/shared_ptr.hpp>
+
+#include <Moof/OpenGL.hh>
+#include <Moof/Resource.hh>
+
+
+namespace Mf {
+
+
+class Image : public Resource
+{
+public:
+
+ explicit Image(const std::string& name);
+
+ bool isValid() const;
+
+ int getWidth() const;
+ int getHeight() const;
+
+ unsigned getDepth() const;
+ unsigned getPitch() const;
+ GLuint getColorMode() const;
+
+ std::string getComment() const;
+
+ const char* getPixels() const;
+ char* getPixels();
+
+ void flip();
+
+ void setAsIcon() const;
+
+ static std::string getPath(const std::string& name);
+
+private:
+
+ class Impl;
+ boost::shared_ptr<Impl> mImpl;
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_IMAGE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
Log logError(Log::ERRORR, " error: ");
Log logWarning(Log::WARNING, "warning: ");
Log logInfo(Log::INFO, " info: ");
-Log logDebug(Log::DEBUGG, " debug: ");
-static int logScript_(Script& script)
+static int logScript_(Script& script, Log::Level level)
{
- static Log logScript(Log::SCRIPT, " script: ");
+ static Log* logs[] = {0, &logError, &logWarning, &logInfo};
Script::Slot param = script[1];
while (!param.isNone())
{
- logScript(param);
+ (*logs[level])(param);
++param.index;
}
}
-void importLogPrintFunction(Script& script)
+void importLogFunctions(Script& script)
{
- script.importFunction("print", logScript_);
+ script.importFunction("LogError", boost::bind(logScript_, _1, Log::ERRORR));
+ script.importFunction("LogWarning", boost::bind(logScript_, _1, Log::WARNING));
+ script.importFunction("LogInfo", boost::bind(logScript_, _1, Log::INFO));
+ script.importFunction("print", boost::bind(logScript_, _1, Log::INFO));
}
enum Level
{
- NONE = -1, ///< Disable all logging.
- ERRORR = 1, ///< Log only errors.
- WARNING = 2, ///< Log warnings and errors.
- SCRIPT = 3, ///< Log messages from Lua, too.
- INFO = 4, ///< Log info, warnings, errors.
- DEBUGG = 5, ///< Log all messages.
+ NONE = 0, ///< Disable all logging.
+ ERRORR = 1, ///< Log only errors.
+ WARNING = 2, ///< Log warnings and errors.
+ INFO = 3, ///< Log everything.
};
static void setLevel(Level level);
extern Log logError;
extern Log logWarning;
extern Log logInfo;
-extern Log logDebug;
template <typename T>
class Script;
-void importLogPrintFunction(Script& script);
+void importLogFunctions(Script& script);
} // namespace Mf
}
+template <typename R, typename P>
+inline R convert(const P& p)
+{
+ return R(p);
+}
+
+template <>
+inline Vector3 convert<Vector3,Vector4>(const Vector4& vec)
+{
+ return Vector3(vec[0], vec[1], vec[2]);
+}
+
+template <>
+inline Vector2 convert<Vector2,Vector3>(const Vector3& vec)
+{
+ return Vector2(vec[0], vec[1]);
+}
+
+template <>
+inline Vector4 convert<Vector4,Vector3>(const Vector3& vec)
+{
+ return Vector4(vec[0], vec[1], vec[2], SCALAR(0.0));
+}
+
+template <>
+inline Vector3 convert<Vector3,Vector2>(const Vector2& vec)
+{
+ return Vector3(vec[0], vec[1], SCALAR(0.0));
+}
+
+template <typename P>
+struct cast
+{
+ cast(const P& p) : param(p) {}
+ template <typename R>
+ operator R() { return convert<R,P>(param); }
+private:
+ const P& param;
+};
+
+
const Scalar EPSILON = SCALAR(0.000001);
break;
}
-#if USE_GTK
+#if defined(_WIN32) || defined(__WIN32__)
+
+ int iconType;
+ switch (type)
+ {
+ case WARNING:
+ iconType = MB_ICONWARNING;
+ break;
+ case CRITICAL:
+ iconType = MB_ICONERROR;
+ break;
+ default:
+ iconType = MB_ICONINFORMATION;
+ break;
+ }
+
+ MessageBox(0, (text1 + "\n" + text2).c_str(), title.c_str(),
+ MB_OK | iconType);
+
+#elif USE_GTK
int argc = 0;
char** argv;
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
// FIXME - this doesn't seem to actually remove the window from the
- // screen when it closes, not sure why...
+ // screen when it closes
#elif USE_QT4
void printSize()
{
- logDebug << "size of node " << objects.size() << std::endl;
+ logInfo << "size of node " << objects.size() << std::endl;
}
void getAll(std::list<InsertableP>& insertables) const
}
else
{
- logDebug("getting all the rest...");
+ logInfo("getting all the rest...");
getAll(insertables, node);
}
}
void getNearbyObjects(std::list<InsertableP>& insertables,
const OctreeInsertable& entity) const
{
- logDebug("--- GETTING NEARBY");
+ logInfo("--- GETTING NEARBY");
getNearbyObjects(insertables, entity, mTree.root());
- logDebug("---");
+ logInfo("---");
savedObj = &entity;
}
};
void draw(Scalar alpha = 0.0) const
{
Vector end = point + 1000.0 * direction;
+ // TODO this is kinda cheesy
Mf::Texture::resetBind();
glBegin(GL_LINES);
* is any number of return values, depending on the callee).
*/
- Result call(int nargs, int nresults = LUA_MULTRET)
+ Result call(int nargs = 0, int nresults = LUA_MULTRET)
{
return (Result)lua_pcall(mState, nargs, nresults, 0);
}
}
else
{
- stream << slot.getTypeName()
- << " (" << slot.getIdentifier() << ")" << std::endl;
+ stream << slot.getTypeName() << " (" << slot.getIdentifier() << ")";
}
return stream;
{
std::string str;
mScript[-1].get(str);
- logInfo(str);
+ logWarning(str);
mScript.clear();
}
}
{
public:
- Settings() :
- mGlobals(mScript.getGlobalTable()),
- mTop(mScript[-1])
+ Settings()
{
mScript.importBaseLibrary();
- importLogPrintFunction(mScript);
+ importLogFunctions(mScript);
}
~Settings();
private:
Script mScript;
- Script::Slot mGlobals, mTop;
std::string mUserFile;
};
template <typename T>
bool Settings::get(const std::string& key, T& value)
{
+ Script::Slot top = mScript[-1];
+ Script::Slot globals = mScript.getGlobalTable();
+
std::vector<std::string> fields;
boost::split(fields, key, boost::is_any_of("."));
- mGlobals.pushCopy();
+ globals.pushCopy();
std::vector<std::string>::iterator it;
for (it = fields.begin(); it != fields.end(); ++it)
{
- if (mTop.isTable())
+ if (top.isTable())
{
- mTop.pushField(*it);
+ top.pushField(*it);
}
else
{
}
}
- bool got = mTop.get(value);
+ bool got = top.get(value);
mScript.clear();
return got;
}
*******************************************************************************/
-#include <cstring> // memcpy
+#include <cstdio> // FILE
+#include <cstring> // strncmp
#include <boost/bind.hpp>
-#include <SDL/SDL.h>
-#include <SDL/SDL_image.h>
-
#include "Dispatch.hh"
#include "Engine.hh"
#include "Exception.hh"
+#include "Image.hh"
#include "Library.hh"
#include "Log.hh"
#include "OpenGL.hh"
* which is worth having in memory. The image data itself is not worth keeping
* in memory if the texture has been loaded to GL, but the name of the resource
* is retained so that it can be reloaded if necessary. The implementation is a
- * mippleton so that multiple texture objects can share the same internal
- * objects and avoid having duplicate textures loaded to GL.
+ * library so that multiple texture objects can share the same internal objects
+ * and avoid having duplicate textures loaded to GL.
*/
class Texture::Impl : public Library<Impl>
return value;
}
-
- static void flipSurface(SDL_Surface* image)
- {
- unsigned char* pixels = (Uint8*)(image->pixels);
-
- unsigned pitch = image->pitch;
- unsigned char line[pitch];
-
- int yBegin = 0;
- int yEnd = image->h - 1;
-
- if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
- while (yBegin < yEnd)
- {
- memcpy(line, pixels + pitch * yBegin, pitch);
- memcpy(pixels + pitch * yBegin, pixels + pitch * yEnd, pitch);
- memcpy(pixels + pitch * yEnd, line, pitch);
- yBegin++;
- yEnd--;
- }
- if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
- }
-
public:
/**
explicit Impl(const std::string& name) :
Library<Impl>(name),
- mContext(0),
+ //mContext(0),
+ mImage(Texture::getPath(getName())),
mWidth(0),
mHeight(0),
mMode(0),
~Impl()
{
- if (mContext)
- {
- SDL_FreeSurface(mContext);
- }
-
unloadFromGL();
}
* method makes them ready.
*/
+ /*
static SDL_Surface* prepareImageForGL(SDL_Surface* surface)
{
int w = powerOfTwo(surface->w);
return image;
}
+ */
/**
* Use SDL_image to load images from file. A surface with the image data is
void loadFromFile()
{
- SDL_Surface* surface;
-
- surface = IMG_Load(Texture::getPath(getName()).c_str());
-
- if (!surface)
+ if (!mImage.isValid())
{
logWarning << "texture not found: " << getName() << std::endl;
- throw Exception(ErrorCode::FILE_NOT_FOUND, getName());
- }
-
- SDL_Surface* temp = prepareImageForGL(surface);
- SDL_FreeSurface(surface);
-
- if (!temp)
- {
- throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT, getName());
- }
-
- if (temp->format->BytesPerPixel == 3)
- {
- mMode = GL_RGB;
- }
- else if (temp->format->BytesPerPixel == 4)
- {
- mMode = GL_RGBA;
- }
- else
- {
- SDL_FreeSurface(temp);
- throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT, getName());
+ throw Exception(ErrorCode::RESOURCE_NOT_FOUND, getName());
}
- mWidth = temp->w;
- mHeight = temp->h;
+ mImage.flip();
- mContext = temp;
+ mWidth = mImage.getWidth();
+ mHeight = mImage.getHeight();
+ mMode = mImage.getColorMode();
}
return;
}
- if (!mContext) loadFromFile();
+ //if (!mContext) loadFromFile();
glGenTextures(1, &mObject);
glBindTexture(GL_TEXTURE_2D, mObject);
0,
mMode,
//3,
- mContext->w,
- mContext->h,
+ mWidth,
+ mHeight,
0,
mMode,
GL_UNSIGNED_BYTE,
- mContext->pixels
+ mImage.getPixels()
);
setProperties();
- SDL_FreeSurface(mContext);
- mContext = 0;
+ //SDL_FreeSurface(mContext);
+ //mContext = 0;
}
}
- SDL_Surface* mContext;
+ Image mImage;
unsigned mWidth; ///< Horizontal dimension of the image.
unsigned mHeight; ///< Vertical dimension.
void draw(Engine& engine, Scalar alpha) const
{
Scalar a = mInterp.getState(alpha);
- logDebug << "transition state: " << a << std::endl;
+ logInfo << "transition state: " << a << std::endl;
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
*******************************************************************************/
-#include <SDL/SDL_image.h>
-
#include "Dispatch.hh"
#include "Engine.hh"
#include "Exception.hh"
+#include "Image.hh"
#include "Log.hh"
#include "Settings.hh"
#include "Video.hh"
{
if (mAttribs.icon != "")
{
- SDL_Surface* icon = IMG_Load(mAttribs.icon.c_str());
- if (icon)
- {
- SDL_WM_SetIcon(icon, 0);
- SDL_FreeSurface(icon);
- }
+ Image icon(mAttribs.icon);
+ icon.setAsIcon();
}
}
Mf::Vector2 tr = Mf::demote(vertices[height][width]);
mLines.push_back(Mf::Line<2>(bl, tr));
- Mf::logDebug("new line");
+ Mf::logInfo("new line");
}
return 0;
std::string filePath = Tilemap::getPath(getName());
script.importStandardLibraries();
- importLogPrintFunction(script);
+ importLogFunctions(script);
bindScriptConstants(script);
if (script.doFile(filePath) != Mf::Script::SUCCESS)
sed 's/\r*$/\r/' "$1" >$TMPFILE
if [ ! "$2" ];
then
- cp -f "$TMPFILE" "$1"
+ mv -f "$TMPFILE" "$1"
else
- cp -f "$TMPFILE" "$2"
+ mv -f "$TMPFILE" "$2"
fi
rm -f "$TMPFILE"
else
# This was blatantly yoinked and adapted from the Wormux Project.
#
+# Paths
+SCRIPT="$PWD/yoink.nsi"
+BUILD_DIR="$PWD/build"
+ROOT_DIR="$PWD/.."
+
# Programs
MAKENSIS="@MAKENSIS@"
STRIP="@STRIP@"
-
-# Anchor paths
-ROOT_DIR="$PWD/.."
-
-# Stuff
-COMPRESSION="/solid lzma"
-DEST="tmp-yoink-win32"
-SCRIPT="$DEST/yoink.nsi"
-OUT_FILE=${1:-yoinksetup-@VERSION@.exe}
+UNIX2DOS="$ROOT_DIR/tools/unix2dos"
# DLL dependencies
-DLLS="SDL SDL_image zlib1 libpng12-0 OpenAL32 libvorbis-0 libogg-0"
-DLLS="$DLLS libvorbisfile-3 lua51"
+DLLS="libogg-0 libpng-3 libvorbis-0 libvorbisfile-3 lua51 OpenAL32 SDL zlib1"
# Prepare
-${STRIP:-strip} "$ROOT_DIR/src/yoink.exe"
-rm -rf "$DEST"
-mkdir -p "$DEST"
-
-
-#
-# Set installer definitions and strings.
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-HKLM_PATH='SOFTWARE\Games\Yoink'
-UNINSTALL_KEY='SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Yoink'
-APP_PATHS_KEY='SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\yoink.exe'
-START_RUN_KEY='SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
-
-
-PROMPT1="Not enough rights to install, aborting. :-("
-PROMPT2="Unable to uninstall the currently installed version of Yoink. The new version will be installed without removing the currently installed version."
-
-SEC_INSTALL="Install Yoink!"
-SEC_INSTALL_DESC="Installs Yoink to your computer."
-SEC_UNINSTALL="Uninstall previous version."
-SEC_SHORTCUTS="Install Shortcuts."
-SEC_SHORTCUTS_DESC="Install shortcuts at various locations."
-SEC_SHORTCUT1="Place a shortcut on the desktop."
-SEC_SHORTCUT2="Place a shortcut in the start menu."
-SEC_SHORTCUT3="Place an uninstall shortcut in the start menu."
-
-WEBSITE_LINK="Visit the Yoink website"
-
-
-#
-# Begin output of installer script.
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-cat > "$SCRIPT" <<EOF
-; based on MUI Welcome/Finish Page Example Script written by Joost Verburg
-!include "MUI2.nsh"
-!include "Sections.nsh"
-!include "LogicLib.nsh"
-!include "FileFunc.nsh"
-
-!insertmacro GetParent
-
-Name "Yoink"
-VIProductVersion "@PVERSION@"
-VIAddVersionKey "FileDescription" "Yoink Setup"
-VIAddVersionKey "ProductName" "Yoink"
-VIAddVersionKey "FileVersion" "@VERSION@"
-VIAddVersionKey "ProductVersion" "@VERSION@"
-VIAddVersionKey "LegalCopyright" "Copyright 2009 Charles McGarvey et al."
-
-;General
-OutFile "$ROOT_DIR/$OUT_FILE"
-SetCompressor $COMPRESSION
-ShowInstDetails show
-ShowUninstDetails show
-SetDateSave on
-RequestExecutionLevel highest
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Modern UI Configuration ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-!define MUI_ICON "$ROOT_DIR/src/setup.ico"
-!define MUI_UNICON "$ROOT_DIR/src/uninstall.ico"
-; Language
-!define MUI_LANGDLL_ALWAYSSHOW
-!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
-!define MUI_LANGDLL_REGISTRY_KEY "$HKLM_PATH"
-!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
-; Misc stuff
-!define MUI_COMPONENTSPAGE_SMALLDESC
-!define MUI_ABORTWARNING
-; Do not close dialogs, allow to check installation result
-!define MUI_FINISHPAGE_NOAUTOCLOSE
-!define MUI_UNFINISHPAGE_NOAUTOCLOSE
-;Finish Page config
-!define MUI_FINISHPAGE_RUN "\$INSTDIR\\yoink.exe"
-!define MUI_FINISHPAGE_RUN_NOTCHECKED
-!define MUI_FINISHPAGE_LINK "$WEBSITE_LINK"
-!define MUI_FINISHPAGE_LINK_LOCATION "http://www.dogcows.com/"
-
-;--------------------------------
-;Pages
-; Install
-!insertmacro MUI_PAGE_WELCOME
-!insertmacro MUI_PAGE_COMPONENTS
-!insertmacro MUI_PAGE_DIRECTORY
-!insertmacro MUI_PAGE_INSTFILES
-!insertmacro MUI_PAGE_FINISH
-; Uninstall
-!insertmacro MUI_UNPAGE_WELCOME
-!insertmacro MUI_UNPAGE_CONFIRM
-!insertmacro MUI_UNPAGE_INSTFILES
-!insertmacro MUI_UNPAGE_FINISH
-
-;--------------------------------
-;Languages
-!insertmacro MUI_LANGUAGE "English"
-
-;--------------------------------
-;Reserve Files
-;If you are using solid compression, files that are required before
-;the actual installation should be stored first in the data block,
-;because this will make your installer start faster.
-
-!insertmacro MUI_RESERVEFILE_LANGDLL
-
-;--------------------------------
-;Folder-selection page
-InstallDir "\$PROGRAMFILES\\Yoink"
-; Registry key to check for directory (so if you install again, it will
-; overwrite the old one automatically)
-InstallDirRegKey HKLM "$HKLM_PATH" "Path"
-AutoCloseWindow false
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Start Install Sections ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;-----------------------------------------
-;Create folder only if it doesnt exist yet
-!macro CreateDirectoryOnce FOLDER
- IfFileExists "\${FOLDER}\\*.*" +1
- CreateDirectory "\${FOLDER}"
-!macroend
-
-;--------------------------------
-;Check (un)install rights
-!macro CheckUserInstallRightsMacro UN
-Function \${UN}CheckUserInstallRights
- Push \$0
- Push \$1
- ClearErrors
- UserInfo::GetName
- IfErrors Win9x
- Pop \$0
- UserInfo::GetAccountType
- Pop \$1
-
- StrCmp \$1 "Admin" 0 +3
- StrCpy \$1 "HKLM"
- Goto done
- StrCmp \$1 "Power" 0 +3
- StrCpy \$1 "HKLM"
- Goto done
- StrCmp \$1 "User" 0 +3
- StrCpy \$1 "HKCU"
- Goto done
- StrCmp \$1 "Guest" 0 +3
- StrCpy \$1 "NONE"
- Goto done
- ; Unknown error
- StrCpy \$1 "NONE"
- Goto done
-
- Win9x:
- StrCpy \$1 "HKLM"
-
- done:
- Exch \$1
- Exch
- Pop \$0
-FunctionEnd
-!macroend
-!insertmacro CheckUserInstallRightsMacro ""
-!insertmacro CheckUserInstallRightsMacro "un."
-
-;--------------------------------
-; Uninstall any old version of Yoink
-
-; Section hidden because automatically selected by the installer
-Section "$SEC_UNINSTALL" SecUninstallOldYoink
- ; Check install rights..
- StrCpy \$R3 $HKLM_PATH
- StrCpy \$R4 $UNINSTALL_KEY
- StrCpy \$R5 "uninstall.exe"
- Call CheckUserInstallRights
- Pop \$R0
- ; "NONE" case already handled at start
- StrCmp \$R0 "HKCU" _hkcu
- ReadRegStr \$R1 HKLM \$R3 ""
- ReadRegStr \$R2 HKLM "\$R4" "UninstallString"
- Goto try_uninstall
-
- _hkcu:
- ReadRegStr \$R1 HKCU \$R3 ""
- ReadRegStr \$R2 HKCU "\$R4" "UninstallString"
-
- ; If a previous version exists, remove it
- try_uninstall:
- ; If first string is unavailable, Yoink was probably not installed
- StrCmp \$R1 "" done
- ; Check if we have uninstall string..
- IfFileExists \$R2 0 no_file
- ; Have uninstall string, go ahead and uninstall.
- SetOverwrite on
- ; Need to copy uninstaller outside of the install dir
- ClearErrors
- CopyFiles /SILENT \$R2 "\$TEMP\\\$R5"
- SetOverwrite off
- IfErrors uninstall_problem
- ; Ready to uninstall..
- ClearErrors
- ExecWait '"\$TEMP\\\$R5" /S _?=\$R1'
- IfErrors exec_error
- Delete "\$TEMP\\\$R5"
- Goto done
-
- exec_error:
- Delete "\$TEMP\\\$R5"
- Goto uninstall_problem
+rm -rf "$BUILD_DIR"
+mkdir -p "$BUILD_DIR"
- no_file:
- MessageBox MB_OK "No uninstaller exe found" /SD IDOK IDOK done
-
- uninstall_problem:
- ; We cant uninstall. Either the user must manually uninstall or
- ; we ignore and reinstall over it.
- MessageBox MB_OKCANCEL "$PROMPT2" /SD IDOK IDCANCEL done
- Quit
-
- done:
-SectionEnd
-
-;--------------------------------
-; Installer Sections
-
-Section "$SEC_INSTALL" SecInstallYoink
- ; Create install and config folders
- CreateDirectory "\$INSTDIR"
- ; Set output path to the installation directory.
- SetOutPath "\$INSTDIR"
- File "$ROOT_DIR/src/yoink.ico"
- ; Executing in tmpdir, looking for file in folder below
- File "$ROOT_DIR/src/yoink.exe"
- ; data
- File /r /x Makefile* /x *.desktop "$ROOT_DIR/data"
- ; documentation
- File "$ROOT_DIR/AUTHORS" "$ROOT_DIR/ChangeLog" "$ROOT_DIR/COPYING"
- File "$ROOT_DIR/README" "$ROOT_DIR/TODO" "$ROOT_DIR/doc/screenshot.jpg"
- File /r "$ROOT_DIR/doc/licenses"
- ; uninstall
- WriteUninstaller "uninstall.exe"
-EOF
-
-
-#
-# Add DLL's to installer
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cp -f "$ROOT_DIR/src/yoink.exe" "$BUILD_DIR"
+"${STRIP:-strip}" "$BUILD_DIR/yoink.exe"
for dll in $DLLS
do
- cat >> "$SCRIPT" <<EOF
-File "@prefix@/bin/$dll.dll"
-EOF
+ cp -f "@prefix@/bin/$dll.dll" "$BUILD_DIR"
+ "${STRIP:-strip}" "BUILD_DIR/$dll.dll"
done
+cd "$ROOT_DIR"
+for asset in @DATA_FILES@
+do
+ cp -f --parents "data/$asset" "$BUILD_DIR"
+done
-#
-# Continue writing the installer
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-cat >> "$SCRIPT" <<EOF
- Call CheckUserInstallRights
- Pop \$R0
- ; "NONE" case already handled at start
- StrCmp \$R0 "HKCU" _hkcu
- WriteRegStr HKLM "$APP_PATHS_KEY" "" "\$INSTDIR\\yoink.exe"
- WriteRegStr HKLM "$HKLM_PATH" "" "\$INSTDIR"
- WriteRegStr HKLM "$HKLM_PATH" "Version" "@VERSION@"
- WriteRegStr HKLM "$UNINSTALL_KEY" "DisplayName" "Yoink"
- WriteRegStr HKLM "$UNINSTALL_KEY" "DisplayVersion" "@VERSION@"
- WriteRegStr HKLM "$UNINSTALL_KEY" "UninstallString" "\$INSTDIR\\uninstall.exe"
- ;Write language to the registry (for the uninstaller)
- WriteRegStr HKLM "$HKLM_PATH" "Installer Language" \$LANGUAGE
- ; Sets scope of the desktop and Start Menu entries for all users.
- SetShellVarContext "all"
- Goto _next
-
- _hkcu:
- WriteRegStr HKCU "$HKLM_PATH" "" "\$INSTDIR"
- WriteRegStr HKCU "$HKLM_PATH" "Version" "@VERSION@"
- WriteRegStr HKCU "$UNINSTALL_KEY" "DisplayName" "Yoink"
- WriteRegStr HKCU "$UNINSTALL_KEY" "DisplayVersion" "@VERSION@"
- WriteRegStr HKCU "$UNINSTALL_KEY" "UninstallString" "\$INSTDIR\\uninstall.exe"
- ;Write language to the registry (for the uninstaller)
- WriteRegStr HKCU "$HKLM_PATH" "Installer Language" \$LANGUAGE
- ;SetShellVarContext "current"
-
- _next:
-SectionEnd ; Installer section
-
-;--------------------------------
-;Shortcuts
-SectionGroup /e "$SEC_SHORTCUTS" SecShortcuts
-
- ; Desktop shortcut
-Section /o "$SEC_SHORTCUT1" SecDesktopShortcut
-SetOverwrite on
-CreateShortCut "\$DESKTOP\\Yoink.lnk" "\$INSTDIR\\yoink.exe" \
- "" "\$INSTDIR\\yoink.exe" 0
-SetOverwrite off
-SectionEnd
-
- ; Yoink uninstall shortcut in start menu
- ; Might be forced if user has no install rights,
- ; because it would be complex otherwise:
- ; - No uninstall available in Windows "Program uninstall"
- ; - Folder lost in APPDATA, which can be hidden, etc
-Section "$SEC_SHORTCUT3" SecUninstallShortcut
-SetOverwrite on
-!insertmacro CreateDirectoryOnce "\$SMPROGRAMS\\Yoink"
-CreateShortCut "\$SMPROGRAMS\\Yoink\\Uninstall.lnk" \
- "\$INSTDIR\\uninstall.exe" "" "\$INSTDIR\\uninstall.exe" 0
-SetOverwrite off
-SectionEnd
-
- ; Yoink shortcut in start menu
-Section "$SEC_SHORTCUT2" SecStartMenuShortcut
-SetOverwrite on
-!insertmacro CreateDirectoryOnce "\$SMPROGRAMS\\Yoink"
-CreateShortCut "\$SMPROGRAMS\\Yoink\\Play Yoink!.lnk" \
- "\$INSTDIR\\yoink.exe" "" "\$INSTDIR\\yoink.exe" 0
-SetOverwrite off
-SectionEnd
-
-SectionGroupEnd
-
-
-;--------------------------------
-;Descriptions
-
-!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
-!insertmacro MUI_DESCRIPTION_TEXT \${SecInstallYoink} "$SEC_INSTALL_DESC"
-!insertmacro MUI_DESCRIPTION_TEXT \${SecShortcuts} "$SEC_SHORTCUTS_DESC"
-!insertmacro MUI_DESCRIPTION_TEXT \${SecDesktopShortcut} "$SEC_SHORTCUT1"
-!insertmacro MUI_DESCRIPTION_TEXT \${SecStartMenuShortcut} "$SEC_SHORTCUT2"
-!insertmacro MUI_DESCRIPTION_TEXT \${SecUninstallShortcut} "$SEC_SHORTCUT3"
-!insertmacro MUI_FUNCTION_DESCRIPTION_END
-
-
-;--------------------------------
-;Uninstaller Section
-
-Section "Uninstall"
- ; Set install path according to user rights
- Call un.CheckUserInstallRights
- Pop \$R0
- StrCmp \$R0 "HKLM" _hklm
-
- ; Also used as fallback by HKLM case
- _hkcu:
- ReadRegStr \$R0 HKCU "$HKLM_PATH" ""
- StrCmp \$R0 "\$INSTDIR" 0 _next
- ; HKCU install path matches our INSTDIR so uninstall
- DeleteRegKey HKCU "$HKLM_PATH"
- DeleteRegKey HKCU "$UNINSTALL_KEY"
- Goto _next
-
- _hklm:
- ReadRegStr \$R0 HKLM "$HKLM_PATH" ""
- StrCmp \$R0 \$INSTDIR 0 _hkcu
- ; HKLM install path matches our INSTDIR so uninstall
- DeleteRegKey HKLM "$APP_PATHS_KEY"
- DeleteRegKey HKLM "$HKLM_PATH"
- DeleteRegKey HKLM "$UNINSTALL_KEY"
- SetShellVarContext all
-
- _next:
- ; Remove Language preference info
- DeleteRegValue HKCU "$HKLM_PATH" "Installer Language"
- ; remove shortcuts, if any.
- Delete "\$SMPROGRAMS\\Yoink\\*.*"
- RMDir "\$SMPROGRAMS\\Yoink"
- Delete "\$SMPROGRAMS\\Yoink.lnk"
- Delete "\$DESKTOP\\Yoink.lnk"
- ; remove files
- RMDir /r "\$INSTDIR"
-SectionEnd
-
-Function .onInit
- ;Language selection
- !insertmacro MUI_LANGDLL_DISPLAY
-
- IntOp \$R0 \${SF_RO} | \${SF_SELECTED}
- SectionSetFlags \${SecInstallYoink} \$R0
- SectionSetFlags \${SecUninstallOldYoink} \$R0
-
- ; Set install path according to user rights
- Call CheckUserInstallRights
- Pop \$R0
- StrCmp \$R0 "NONE" _none
- StrCmp \$R0 "HKLM" 0 _hkcu
- StrCpy \$INSTDIR "\$PROGRAMFILES\\Yoink"
- Goto _done
-
- _hkcu:
- Push \$SMPROGRAMS
- \${GetParent} \$SMPROGRAMS \$R2
- \${GetParent} \$R2 \$R2
- StrCpy \$INSTDIR "\$R2\\Yoink"
- ; In this case uninstall shortcut *must* be available because
- ; the alternative are complex for the user
- IntOp \$R0 \${SF_RO} | \${SF_SELECTED}
- SectionSetFlags \${SecUninstallShortcut} \$R0
- Goto _done
-
- _none:
- ; Not going to bother
- MessageBox MB_OK "$PROMPT1" /SD IDOK
- Quit
-
- _done:
-FunctionEnd
-
-; INSTDIR will be determined by reading a registry key
-Function un.onInit
- !insertmacro MUI_UNGETLANGUAGE
- ; Set install path according to user rights
- Call un.CheckUserInstallRights
- Pop \$R0
- StrCmp \$R0 "NONE" _none
- Goto _end
+cd "$ROOT_DIR"
+for doc in AUTHORS ChangeLog COPYING README TODO
+do
+ "$UNIX2DOS" "$doc" "$BUILD_DIR/$doc.txt"
+done
- _none:
- ; Not going to bother
- MessageBox MB_OK "$PROMPT1" /SD IDOK
- Quit
+cd "$ROOT_DIR/doc"
+cp -rf licenses "$BUILD_DIR"
- _end:
-FunctionEnd
-EOF
+cd "$BUILD_DIR/licenses"
+for license in $(ls)
+do
+ mv "$license" "$license.txt"
+ "$UNIX2DOS" "$license.txt"
+done
#
exit 1
fi
-rm -rf "$DEST"
+rm -rf "$BUILD_DIR"
--- /dev/null
+;NSIS Modern User Interface
+;Start Menu Folder Selection Example Script
+;Written by Joost Verburg
+
+;--------------------------------
+;Include Modern UI
+
+ !include "MUI2.nsh"
+
+;--------------------------------
+;General
+
+ ;Name and file
+ Name "Yoink"
+ OutFile "../yoinksetup-@VERSION@.exe"
+ SetCompressor /SOLID lzma
+
+ ;Default installation folder
+ InstallDir "$PROGRAMFILES\Yoink"
+
+ ;Get installation folder from registry if available
+ InstallDirRegKey HKCU "Software\Yoink" ""
+
+ ;Request application privileges for Windows Vista
+ RequestExecutionLevel user
+
+;--------------------------------
+;Interface Settings
+
+ !define MUI_ICON "../src/setup.ico"
+ !define MUI_UNICON "../src/uninstall.ico"
+
+ !define MUI_COMPONENTSPAGE_SMALLDESC
+
+ !define MUI_FINISHPAGE_RUN "$INSTDIR\yoink.exe"
+ !define MUI_FINISHPAGE_RUN_NOTCHECKED
+ !define MUI_FINISHPAGE_LINK "Visit the Yoink website"
+ !define MUI_FINISHPAGE_LINK_LOCATION "http://www.dogcows.com/"
+
+ !define MUI_ABORTWARNING
+
+;--------------------------------
+;Pages
+
+ !insertmacro MUI_PAGE_WELCOME
+ !insertmacro MUI_PAGE_COMPONENTS
+ !insertmacro MUI_PAGE_DIRECTORY
+ !insertmacro MUI_PAGE_INSTFILES
+ !insertmacro MUI_PAGE_FINISH
+
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+
+;--------------------------------
+;Languages
+
+ !insertmacro MUI_LANGUAGE "English"
+
+;--------------------------------
+;Installer Sections
+
+Section "Install Yoink!" SecInstallYoink
+
+ SetOutPath "$INSTDIR"
+
+ ;ADD YOUR OWN FILES HERE...
+ File /r "build/*"
+
+ ;Store installation folder
+ WriteRegStr HKCU "Software\Yoink" "" $INSTDIR
+
+ ;Create uninstaller
+ WriteUninstaller "uninstall.exe"
+
+ ;Create shortcuts
+ CreateDirectory "$SMPROGRAMS\Yoink"
+ CreateShortCut "$SMPROGRAMS\Yoink\Play Yoink!.lnk" "$INSTDIR\yoink.exe"
+ CreateShortCut "$SMPROGRAMS\Yoink\Uninstall.lnk" "$INSTDIR\uninstall.exe"
+
+ WriteRegStr HKCU "Software\Games\Yoink" "" "$INSTDIR"
+ WriteRegStr HKCU "Software\Games\Yoink" "Version" "@VERSION@"
+ WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Yoink" "DisplayName" "Yoink"
+ WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Yoink" "DisplayVersion" "@VERSION@"
+ WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Yoink" "UninstallString" "$INSTDIR\uninstall.exe"
+
+SectionEnd
+
+Section "Install desktop shortcut." SecInstallShortcut
+
+ ;Desktop shortcut
+ SetOverwrite on
+ CreateShortCut "$DESKTOP\Yoink.lnk" "$INSTDIR\yoink.exe"
+ SetOverwrite off
+
+SectionEnd
+
+;--------------------------------
+;Descriptions
+
+ ;Language strings
+ LangString DESC_SecInstallYoink ${LANG_ENGLISH} "Install the game executable and data files."
+ LangString DESC_SecInstallShortcut ${LANG_ENGLISH} "Install a shortcut to the executable on the desktop."
+
+ ;Assign language strings to sections
+ !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecInstallYoink} $(DESC_SecInstallYoink)
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecInstallShortcut} $(DESC_SecInstallShortcut)
+ !insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+;--------------------------------
+;Uninstaller
+
+Section "Uninstall"
+
+ Delete "$SMPROGRAMS\Yoink\*.*"
+ RMDir "$SMPROGRAMS\Yoink"
+ Delete "$DESKTOP\Yoink.lnk"
+
+ DeleteRegKey /ifempty HKCU "Software\Games\Yoink"
+ DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Yoink"
+
+ RMDir /r "$INSTDIR"
+
+SectionEnd
+
+;--------------------------------
+;Functions
+
+Function .onInit
+
+;Run the uninstaller if Yoink is already installed.
+ ReadRegStr $R0 HKCU \
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Yoink" \
+ "UninstallString"
+ StrCmp $R0 "" done
+
+ MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
+ "Yoink is already installed. $\n$\nClick `OK` to remove the \
+ previous version or `Cancel` to cancel the installation." \
+ IDOK uninst
+ Abort
+
+;Run the uninstaller
+uninst:
+ ClearErrors
+ ExecWait $INSTDIR\uninstall.exe
+
+done:
+
+FunctionEnd
+