simplified win32 installer build script
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Tue, 12 Jan 2010 00:12:51 +0000 (17:12 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Tue, 12 Jan 2010 00:12:51 +0000 (17:12 -0700)
36 files changed:
COPYING
README
configure.ac
data/scenes/Classic.lua
data/textures/Particles.png
data/yoinkrc
doc/licenses/MIT
extra/yoink.ebuild
src/Animation.cc
src/Character.cc
src/Character.hh
src/GameLayer.cc
src/GameLayer.hh
src/Heroine.cc
src/MainLayer.cc
src/Makefile.am
src/Moof/Engine.cc
src/Moof/Image.cc [new file with mode: 0644]
src/Moof/Image.hh [new file with mode: 0644]
src/Moof/Log.cc
src/Moof/Log.hh
src/Moof/Math.hh
src/Moof/ModalDialog.hh
src/Moof/Octree.hh
src/Moof/Ray.hh
src/Moof/Script.hh
src/Moof/Settings.cc
src/Moof/Settings.hh
src/Moof/Texture.cc
src/Moof/Transition.hh
src/Moof/Video.cc
src/Scene.cc
src/Tilemap.cc
tools/unix2dos
win32/mkpackage.sh.in
win32/yoink.nsi.in [new file with mode: 0644]

diff --git a/COPYING b/COPYING
index d0975dcf8783a01046f13c02639709ea3d88668d..1948e77123790d58a0335ca3f5d683c903759188 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -55,7 +55,7 @@ Copyright: (c) 2000-2004 Unicode, Inc.
 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
@@ -85,7 +85,7 @@ Copyright: (c) 2009 Chris Robinson
 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
diff --git a/README b/README
index 529d3d695ba5e3700c2ed1af450b6564a14efa8a..6f5e024bb5758cb494d04c0b8a85c26884e22a53 100644 (file)
--- a/README
+++ b/README
@@ -31,12 +31,12 @@ this simple, fast-moving action game to a wider audience.
 b) Requirements
 
 boost headers
+libpng
 libvorbis
 Lua
 OpenAL
 OpenGL
 SDL
-SDL_image (with libpng support)
 
 c) License
 
index 7ee82d3b12433836ee906a3576f9c39a76b5d284..054c4acf0e2b5b961a9f8566bbe85568239db0c2 100644 (file)
@@ -10,11 +10,10 @@ AC_INIT([Yoink], [0.1], [chaz@dogcows.com], [yoink])
 
 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])])
 
 
 #
@@ -139,7 +138,7 @@ fi
 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
@@ -149,7 +148,7 @@ then
 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],
@@ -267,14 +266,14 @@ AC_SEARCH_LIBS([alEnable], [openal OpenAL32],,
                           [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/"
@@ -331,14 +330,13 @@ fi
 
 
 #
-# 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])
 
 
@@ -354,7 +352,7 @@ AC_CONFIG_FILES([Makefile
 
 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
 
 
index e8ba272faac8d7c8ad12808f8559d03440fc3aa1..5709632fc54dfb3b2280375b34204429c299fccf 100644 (file)
@@ -3,6 +3,9 @@
 -- 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:
@@ -28,7 +31,7 @@ SetBounds({-5, 0, -6}, {45, 15, 7})
 -- Front
 
 ResetTransform()
-Translate(-5, 0, 5)
+Translate(-5, 0, 2)
 SetTexture("TowerBlock1")
 DrawTilemap({
        width = 5,
@@ -52,7 +55,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(Y, 90)
-Translate(0, 0, 5)
+Translate(0, 0, 2)
 DrawTilemap({
        width = 5,
        surface = RIGHT,
@@ -76,7 +79,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(X, 90)
-Translate(-5, 15, 0)
+Translate(-5, 15, -3)
 DrawTilemap({
        width = 5,
        surface = TOP,
@@ -93,6 +96,7 @@ DrawTilemap({
 
 if detail > LOW then
        ResetTransform()
+       Translate(0, 0, -3)
        DrawTilemap({
                width = 7,
                2,      2,      2,      2,      2,      2,      2,
@@ -108,7 +112,7 @@ if detail > LOW then
 
        ResetTransform()
        Rotate(Y, 90)
-       Translate(7, 0, 0)
+       Translate(7, 0, -3)
        DrawTilemap({
                width = 6,
                2,      2,      2,      2,      2,      2,
@@ -124,7 +128,7 @@ if detail > LOW then
 
        ResetTransform()
        Rotate(X, 90)
-       Translate(-2, 8, -6)
+       Translate(-2, 8, -9)
        DrawTilemap({
                width = 9,
                3,      3,      3,      3,      3,      3,      3,      3,      3,
@@ -142,7 +146,7 @@ end
 
 ResetTransform()
 Rotate(Y, -90)
-Translate(10, 0, 1)
+Translate(10, 0, -2)
 SetTexture("Building")
 DrawTilemap({
        width = 4,
@@ -157,7 +161,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(Y, -90)
-Translate(13, 0, 1)
+Translate(13, 0, -2)
 DrawTilemap({
        width = 4,
        surface = RIGHT,
@@ -170,7 +174,7 @@ DrawTilemap({
 -- Front wall
 
 ResetTransform()
-Translate(10, 0, 5)
+Translate(10, 0, 2)
 DrawTilemap({
        width = 3,
        15,     7,      16,
@@ -182,7 +186,7 @@ DrawTilemap({
 ResetTransform()
 Rotate(X, 135)
 Scale(1, 1.5, 1.5)
-Translate(10, 5, 3)
+Translate(10, 5, 0)
 DrawTilemap({
        width = 3,
        13,     13,     13,
@@ -191,7 +195,7 @@ DrawTilemap({
 -- Finial
 
 ResetTransform()
-Translate(10, 5, 3)
+Translate(10, 5, -0.00001)
 DrawTilemap({
        width = 3,
        18,     18,     18})
@@ -214,7 +218,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(X, 90)
-Translate(-3, 0, 0)
+Translate(-3, 0, -3)
 SetTexture("Scenery")
 DrawTilemap({
        width = 13,
@@ -232,7 +236,7 @@ DrawTilemap({
 if detail > MEDIUM then
        ResetTransform()
        Scale(8, 1, 1)
-       Translate(1, -0.5, 5)
+       Translate(1, -0.5, 2)
        DrawTile({
                2,
                u_scale = 8})
@@ -241,7 +245,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(8, 1, 1)
-       Translate(1, -0.5, 1)
+       Translate(1, -0.5, -2)
        DrawTile({
                2,
                u_scale = 8
@@ -252,7 +256,7 @@ if detail > MEDIUM then
        ResetTransform()
        Scale(4, 1, 1)
        Rotate(Y, -90)
-       Translate(1, -0.5, 1)
+       Translate(1, -0.5, -2)
        DrawTile({
                2,
                u_scale = 4
@@ -263,7 +267,7 @@ if detail > MEDIUM then
        ResetTransform()
        Scale(4, 1, 1)
        Rotate(Y, -90)
-       Translate(9, -0.5, 1)
+       Translate(9, -0.5, -2)
        DrawTile({
                2,
                u_scale = 4
@@ -273,7 +277,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(11, 1, 1)
-       Translate(7, 0, 0)
+       Translate(7, 0, -3)
        DrawTile({
                4,
                u_scale = 11
@@ -287,7 +291,7 @@ end
 
 if detail > LOW then
        ResetTransform()
-       Translate(19, 0, 0)
+       Translate(19, 0, -3)
        SetTexture("Building")
        DrawTilemap({
                width = 4,
@@ -302,7 +306,7 @@ if detail > LOW then
 
        ResetTransform()
        Rotate(Y, -90)
-       Translate(19, 0, -3)
+       Translate(19, 0, -6)
        DrawTilemap({
                width = 3,
                15,     1,      16,
@@ -314,7 +318,7 @@ if detail > LOW then
 
        ResetTransform()
        Rotate(Y, -90)
-       Translate(23, 0, -3)
+       Translate(23, 0, -6)
        DrawTilemap({
                width = 3,
                15,     0,      16,
@@ -328,7 +332,7 @@ if detail > LOW then
        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,
@@ -340,7 +344,7 @@ if detail > LOW then
        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,
@@ -350,7 +354,7 @@ if detail > LOW then
 
        ResetTransform()
        Rotate(Y, -90)
-       Translate(21, 6, -3)
+       Translate(21, 6, -6)
        DrawTilemap({
                width = 3,
                18,     18,     18})
@@ -363,7 +367,7 @@ end
 
 ResetTransform()
 Rotate(X, 90)
-Translate(10, 0, 0)
+Translate(10, 0, -3)
 SetTexture("Scenery")
 DrawTilemap({
        width = 3,
@@ -380,7 +384,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(X, 90)
-Translate(13, 0, 0)
+Translate(13, 0, -3)
 DrawTilemap({
        width = 8,
        surface = TOP,
@@ -397,7 +401,7 @@ DrawTilemap({
 if detail > MEDIUM then
        ResetTransform()
        Scale(12, 1, 1)
-       Translate(14, -0.5, 5)
+       Translate(14, -0.5, 2)
        DrawTile({
                2,
                u_scale = 12
@@ -407,7 +411,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(4, 1, 1)
-       Translate(14, -0.5, 1)
+       Translate(14, -0.5, -2)
        DrawTile({
                2,
                u_scale = 4
@@ -416,7 +420,7 @@ if detail > MEDIUM then
        -- Front grass next to door
 
        ResetTransform()
-       Translate(13, -0.5, 3)
+       Translate(13, -0.5, 0)
        DrawTile({
                2,
                u_scale = 1
@@ -425,7 +429,7 @@ if detail > MEDIUM then
        -- Back grass next to door
 
        ResetTransform()
-       Translate(13, -0.5, 2)
+       Translate(13, -0.5, -1)
        DrawTile({
                2,
                u_scale = 1
@@ -435,7 +439,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Rotate(Y, -90)
-       Translate(14, -0.5, 1)
+       Translate(14, -0.5, -2)
        DrawTilemap({
                width = 4,
                2,      -1,     2,      2})
@@ -444,7 +448,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Rotate(Y, -90)
-       Translate(18, -0.5, 0)
+       Translate(18, -0.5, -3)
        DrawTile({
                2,
                u_scale = 1
@@ -454,7 +458,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Rotate(Y, -90)
-       Translate(24, -0.5, 0)
+       Translate(24, -0.5, -3)
        DrawTile({
                2,
                u_scale = 1
@@ -464,7 +468,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(4, 1, 1)
-       Translate(19, -0.5, 4)
+       Translate(19, -0.5, 1)
        DrawTile({
                2,
                u_scale = 4
@@ -474,7 +478,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(4, 1, 1)
-       Translate(19, -0.5, 2)
+       Translate(19, -0.5, -1)
        DrawTile({
                2,
                u_scale = 4
@@ -485,7 +489,7 @@ if detail > MEDIUM then
        ResetTransform()
        Scale(2, 1, 1)
        Rotate(Y, -90)
-       Translate(19, -0.5, 2)
+       Translate(19, -0.5, -1)
        DrawTile({
                2,
                u_scale = 2
@@ -496,7 +500,7 @@ if detail > MEDIUM then
        ResetTransform()
        Scale(2, 1, 1)
        Rotate(Y, -90)
-       Translate(23, -0.5, 2)
+       Translate(23, -0.5, -1)
        DrawTile({
                2,
                u_scale = 2
@@ -507,7 +511,7 @@ end
 
 ResetTransform()
 Rotate(X, 90)
-Translate(21, 0, 0)
+Translate(21, 0, -3)
 DrawTilemap({
        width = 7,
        surface = TOP,
@@ -524,7 +528,7 @@ DrawTilemap({
 if detail > MEDIUM then
        ResetTransform()
        Scale(4, 1, 1)
-       Translate(24, 0, 0)
+       Translate(24, 0, -3)
        DrawTile({
                4,
                u_scale = 4
@@ -534,7 +538,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(4, 1, 1)
-       Translate(24, -0.5, 1)
+       Translate(24, -0.5, -2)
        DrawTile({
                2,
                u_scale = 4
@@ -545,7 +549,7 @@ if detail > MEDIUM then
        ResetTransform()
        Scale(2, 1, 1)
        Rotate(Y, -90)
-       Translate(26, -0.5, 5)
+       Translate(26, -0.5, 2)
        DrawTile({
                2,
                u_scale = 2
@@ -556,7 +560,7 @@ if detail > MEDIUM then
        ResetTransform()
        Scale(2, 1, 1)
        Rotate(Y, -90)
-       Translate(35, -0.5, 5)
+       Translate(35, -0.5, 2)
        DrawTile({
                2,
                u_scale = 2
@@ -566,7 +570,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(5, 1, 1)
-       Translate(35, -0.5, 5)
+       Translate(35, -0.5, 2)
        DrawTile({
                2,
                u_scale = 5
@@ -576,7 +580,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Scale(6, 1, 1)
-       Translate(34, -0.5, 1)
+       Translate(34, -0.5, -2)
        DrawTile({
                2,
                u_scale = 6
@@ -586,7 +590,7 @@ if detail > MEDIUM then
 
        ResetTransform()
        Rotate(Y, -90)
-       Translate(34, -0.5, 0)
+       Translate(34, -0.5, -3)
        DrawTile({
                2,
                u_scale = 1
@@ -597,7 +601,7 @@ end
 
 ResetTransform()
 Rotate(X, 90)
-Translate(28, 0, 4)
+Translate(28, 0, 1)
 DrawTilemap({
        width = 5,
        surface = TOP,
@@ -609,7 +613,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(X, 90)
-Translate(33, 0, 0)
+Translate(33, 0, -3)
 DrawTilemap({
        width = 10,
        surface = TOP,
@@ -627,7 +631,7 @@ DrawTilemap({
 -- Front
 
 ResetTransform()
-Translate(28, 0, 4)
+Translate(28, 0, 1)
 SetTexture("TowerBlock1")
 DrawTilemap({
        width = 5,
@@ -643,7 +647,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(Y, 90)
-Translate(33, 0, 4)
+Translate(33, 0, 1)
 DrawTilemap({
        width = 6,
        surface = RIGHT,
@@ -659,7 +663,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(Y, 90)
-Translate(28, 0, 4)
+Translate(28, 0, 1)
 DrawTilemap({
        width = 6,
        surface = LEFT,
@@ -675,7 +679,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(X, 90)
-Translate(28, 7, -2)
+Translate(28, 7, -5)
 DrawTilemap({
        width = 5,
        surface = TOP,
@@ -692,7 +696,7 @@ DrawTilemap({
 -- Front
 
 ResetTransform()
-Translate(40, 0, 5)
+Translate(40, 0, 2)
 DrawTilemap({
        width = 5,
        2,      2,      2,      2,      2,
@@ -715,7 +719,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(Y, 90)
-Translate(40, 0, 5)
+Translate(40, 0, 2)
 DrawTilemap({
        width = 5,
        surface = LEFT,
@@ -739,7 +743,7 @@ DrawTilemap({
 
 ResetTransform()
 Rotate(X, 90)
-Translate(40, 15, 0)
+Translate(40, 15, -3)
 DrawTilemap({
        width = 5,
        surface = TOP,
@@ -753,7 +757,7 @@ DrawTilemap({
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ResetTransform()
-Translate(-0.32, -0.28, -24)
+Translate(-0.32, -0.28, -27)
 Scale(105, 52, 1)
 SetTexture("BackgroundFar")
 DrawTile()
@@ -774,21 +778,20 @@ SetTexture("Trees")
 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
@@ -796,27 +799,22 @@ DrawTile(1)
 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)
@@ -829,23 +827,27 @@ end
 -- 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)
@@ -887,7 +889,7 @@ function PopulateScene(waveNum)
 end
 
 function RandomSpawnPlace()
-       return {500, 500}
+       return {5, 5}
 end
 
 function RandomSkillLevel()
@@ -895,5 +897,5 @@ function RandomSkillLevel()
 end
 
 
--- vim: tw=80 ts=4
+-- vim: ts=4 sw=4 tw=80
 
index 3d8695f66733f9003a6d3d96560e30e208f516c9..659fae5758fa1007dfc89f3df7996b6c3bda18e7 100644 (file)
Binary files a/data/textures/Particles.png and b/data/textures/Particles.png differ
index 5660ffa894c196aac70e0843c466ab089a373d29..79fa707511a9571832dd0e12865063e555504a0a 100644 (file)
@@ -50,12 +50,12 @@ resizable           = true
 -- 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.
index 0ee603d463c71a09783219d4df6bccf5bfe2ab87..4110670fd39850857adfcb4bb5226ff6074127cf 100644 (file)
@@ -1,14 +1,20 @@
 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.
index ce20adb3d8d755185e01e7147870a874b5635fcd..3646f823cfb38ca5fc3517ab5e72adcc9c8b47e9 100644 (file)
@@ -17,10 +17,11 @@ KEYWORDS="amd64 ~ppc x86"
 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
index 593f44e1aff3df4a492ed2c277bfa91cd46704ff..598361bf97143c28cb1ca2d78d495692d50f6d31 100644 (file)
@@ -167,7 +167,7 @@ class Animation::Impl
                        std::string filePath = Animation::getPath(getName());
 
                        script.importBaseLibrary();
-                       importLogPrintFunction(script);
+                       importLogFunctions(script);
                        importAnimationBindings(script);
 
                        if (script.doFile(filePath) != Mf::Script::SUCCESS)
index 3022c31acc7f1f9d2d060c10dc917ae7a0327924..52a13e63ec38d78178c9f6e9ec259d91b366e47a 100644 (file)
@@ -79,7 +79,7 @@ private:
 
 
 Character::Character(const std::string& name) :
-       tilemap(name),
+       tilemap("Particles"),
        animation(name)
 {
        mState.init();
@@ -108,9 +108,9 @@ void Character::update(Mf::Scalar t, Mf::Scalar dt)
 
        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);
@@ -139,23 +139,18 @@ void Character::draw(Mf::Scalar alpha) const
 
        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;
 
@@ -263,6 +258,7 @@ int Character::getOctant(const Mf::Aabb<3>& aabb) const
 
        return octantNum;
 }
+*/
 
 
 void Character::addImpulse(Mf::Vector2 impulse)
index 21734228b3ab005698cba8f5e20b059e8d7c38d0..6507906d067cf9c3d78162dd6a32916fafa9b76e 100644 (file)
@@ -34,7 +34,6 @@
 #include <Moof/Aabb.hh>
 #include <Moof/Entity.hh>
 #include <Moof/Math.hh>
-#include <Moof/Octree.hh>
 #include <Moof/RigidBody.hh>
 #include <Moof/Sphere.hh>
 
@@ -52,7 +51,7 @@ typedef boost::shared_ptr<Character> CharacterP;
  * includes the heroine herself and the bad guys.
  */
 
-class Character : public Mf::RigidBody2, public Mf::OctreeInsertable
+class Character : public Mf::RigidBody2
 {
 public:
 
@@ -62,20 +61,14 @@ 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;
 };
 
 
index 3f5a7a869fb2dd8d13e6da4671d82f78d474f47d..0ed249c8af964ffffd1bd009c21592350459280e 100644 (file)
 #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 == "")
@@ -101,6 +86,18 @@ void GameLayer::advanceScene()
 
                        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();
+               }
        }
 }
 
@@ -121,11 +118,14 @@ GameLayer::GameLayer() :
        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();
 }
@@ -155,12 +155,19 @@ void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
        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()
 {
@@ -186,9 +193,9 @@ 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;
        }
 }
 
@@ -205,7 +212,6 @@ void GameLayer::draw(Mf::Engine& engine, Mf::Scalar alpha) const
 
        mState.scene->drawIfVisible(alpha, mState.camera.getFrustum());
 
-       mState.heroine->setZCoord(getZCoord(mState.heroine->getState().position));
        mState.heroine->draw(alpha);
 
        mRay.draw();
@@ -242,6 +248,12 @@ bool GameLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event)
                                                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:
index 4e0a84f07752c4742417930073cf5e1f53f0a71d..73b6a23e6a141ec2315cb9f5f2a5f34e91e90dc8 100644 (file)
@@ -80,9 +80,7 @@ public:
 
        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;
@@ -98,12 +96,14 @@ private:
        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;
 
index a70b798e92071e6b34fd495f6b2c2219d6543b3b..5df10319d282bb56fe293500359425ecda98ad76 100644 (file)
@@ -33,7 +33,7 @@
 
        
 Heroine::Heroine() :
-       Character("Heroine") {}
+       Character("Effects") {}
 
 
 void Heroine::update(Mf::Scalar t, Mf::Scalar dt)
index 0b2ef3699f0576f1f70d87da7bbe8a59a8e12972..40377365d18149cf02c7ec8fec0ae4cbd1e4e899 100644 (file)
@@ -77,6 +77,7 @@ void MainLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
        {
                // this is the only layer left on the stack
                //engine.push(TitleLayer::alloc());
+               engine.clear();
        }
 }
 
@@ -270,12 +271,10 @@ int main(int argc, char* argv[])
        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
index 766d4ce1480b0d00da9b4b63eb5d6d813dc569db..ee59088fc6c2f8f3e36b5a1246e330e5c5f14190 100644 (file)
@@ -31,6 +31,8 @@ libmoof_a_SOURCES = \
                                        Moof/Frustum.hh \
                                        Moof/Hash.cc \
                                        Moof/Hash.hh \
+                                       Moof/Image.cc \
+                                       Moof/Image.hh \
                                        Moof/Interpolator.hh \
                                        Moof/Layer.hh \
                                        Moof/Library.hh \
index ccfaf81e6d77b0b0b195f4c279a0d183563ac323..56e98b926bf6fed2f6fe7edadfd8c742b4339659 100644 (file)
@@ -73,7 +73,7 @@ public:
                {
                        char vdName[128];
                        SDL_VideoDriverName(vdName, sizeof(vdName));
-                       logDebug << "initialized SDL; using video driver `"
+                       logInfo << "initialized SDL; using video driver `"
                                         << vdName << "'" << std::endl;
                }
 
@@ -94,7 +94,7 @@ public:
                else
                {
                        alcMakeContextCurrent(mAlContext);
-                       logDebug << "opened sound device `"
+                       logInfo << "opened sound device `"
                                         << alcGetString(mAlDevice, ALC_DEFAULT_DEVICE_SPECIFIER)
                                         << "'" << std::endl;
                }
@@ -282,7 +282,7 @@ public:
        {
                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);
        }
@@ -294,7 +294,7 @@ public:
 
                LayerP layer = mStack.front();
                mStack.pop_front();
-               logDebug << "stack: " << mStack.size()
+               logInfo << "stack: " << mStack.size()
                                 << " [popped " << layer.get() << "]" << std::endl;
                layer->popped(mInterface);
 
@@ -324,7 +324,7 @@ public:
                                for (it = layers.begin(); it != layers.end(); ++it)
                                {
                                        (*it)->popped(mInterface);
-                                       logDebug << "stack: " << mStack.size()
+                                       logInfo << "stack: " << mStack.size()
                                                         << " [popped " << (*it).get() << "]" << std::endl;
                                }
 
@@ -341,7 +341,7 @@ public:
        {
                mStack.clear();
                mStackIt = mStack.begin();
-               logDebug("stack: 0 [cleared]");
+               logInfo("stack: 0 [cleared]");
        }
 
 
diff --git a/src/Moof/Image.cc b/src/Moof/Image.cc
new file mode 100644 (file)
index 0000000..31d6b02
--- /dev/null
@@ -0,0 +1,325 @@
+
+/*******************************************************************************
+
+ 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: *************************************************/
+
diff --git a/src/Moof/Image.hh b/src/Moof/Image.hh
new file mode 100644 (file)
index 0000000..5f7c5a3
--- /dev/null
@@ -0,0 +1,79 @@
+
+/*******************************************************************************
+
+ 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: *************************************************/
+
index 2ea6c57533875b808c58c01e97e3a6205fd12737..980977185e7fdf6b8e9bab0390b2beab19aa3c31 100644 (file)
@@ -57,18 +57,17 @@ std::ostream& nullLog(nullLog_);
 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;
        }
 
@@ -76,9 +75,12 @@ static int logScript_(Script& script)
 }
 
 
-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));
 }
 
 
index c7ee50726b68e35ea914b81afa9c95fc4c347687..96585a1d5dc0041c7deea6b4027dd69eff9eb056 100644 (file)
@@ -64,12 +64,10 @@ public:
 
        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);
@@ -104,7 +102,6 @@ extern std::ostream&        nullLog;
 extern Log logError;
 extern Log logWarning;
 extern Log logInfo;
-extern Log logDebug;
 
 
 template <typename T>
@@ -116,7 +113,7 @@ inline std::ostream& operator << (Log& logObj, const T& item)
 
 
 class Script;
-void importLogPrintFunction(Script& script);
+void importLogFunctions(Script& script);
 
 
 } // namespace Mf
index 05aa9ecf6504d55c0d33f1e3042612480d22df8f..45c6e90b7ee02543df9bed379ac519291529aaaa 100644 (file)
@@ -102,6 +102,47 @@ inline Vector3 promote(const Vector2& vec, Scalar extra = 0.0)
 }
 
 
+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);
 
index 9b3820a210867f51b7cc626c07daef938efdfaef..f630cb6a21c64c5cab567a46e8880a10f376813a 100644 (file)
@@ -92,7 +92,26 @@ struct ModalDialog
                                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;
@@ -126,7 +145,7 @@ struct ModalDialog
                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
 
index 4657aecf3680d6db4a61b92d17921fe30080329e..301b420852a4262486cf561449ce64bbe259cc79 100644 (file)
@@ -79,7 +79,7 @@ class Octree : public Entity
 
                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
@@ -194,7 +194,7 @@ private:
                }
                else
                {
-                       logDebug("getting all the rest...");
+                       logInfo("getting all the rest...");
                        getAll(insertables, node);
                }
        }
@@ -357,9 +357,9 @@ public:
        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;
        }
 };
index 23ebd7655924ea9a6819fecd1ca3354f51e56c33..5a693d29be996da95d2065b3e617ad971971a6cc 100644 (file)
@@ -70,6 +70,7 @@ struct Ray : public Drawable
        void draw(Scalar alpha = 0.0) const
        {
                Vector end = point + 1000.0 * direction;
+               // TODO this is kinda cheesy
 
                Mf::Texture::resetBind();
                glBegin(GL_LINES);
index 05b9da972829b28b3cd378ad092914a809974b9c..9e8827abc78d5c3fb254a379b5540b64626cee21 100644 (file)
@@ -789,7 +789,7 @@ public:
         * 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);
        }
@@ -916,8 +916,7 @@ inline std::ostream& operator << (std::ostream& stream,
        }
        else
        {
-               stream << slot.getTypeName()
-                          << " (" << slot.getIdentifier() << ")" << std::endl;
+               stream << slot.getTypeName() << " (" << slot.getIdentifier() << ")";
        }
 
        return stream;
index c5c3734189fc159f63bfd10fb2a702e5fb5a86d5..9f0538b3b827c56e4d6037a79edd2f659e62eaba 100644 (file)
@@ -88,7 +88,7 @@ void Settings::loadFromFiles(const std::vector<std::string>& filePaths)
                {
                        std::string str;
                        mScript[-1].get(str);
-                       logInfo(str);
+                       logWarning(str);
                        mScript.clear();
                }
        }
index 2a2a9267026e5475ddd5c0a1d11433da19767251..d31b57dcf763c2fe0d38b1f3f96cc1fa24583223 100644 (file)
@@ -50,12 +50,10 @@ class Settings
 {
 public:
 
-       Settings() :
-               mGlobals(mScript.getGlobalTable()),
-               mTop(mScript[-1])
+       Settings()
        {
                mScript.importBaseLibrary();
-               importLogPrintFunction(mScript);
+               importLogFunctions(mScript);
        }
 
        ~Settings();
@@ -79,7 +77,6 @@ public:
 private:
 
        Script                  mScript;
-       Script::Slot    mGlobals, mTop;
 
        std::string             mUserFile;
 };
@@ -88,17 +85,20 @@ private:
 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
                {
@@ -107,7 +107,7 @@ bool Settings::get(const std::string& key, T& value)
                }
        }
 
-       bool got = mTop.get(value);
+       bool got = top.get(value);
        mScript.clear();
        return got;
 }
index 61cabd2c89296eb06e24884cd289448a7fb39ce1..22d3f15e92cab597259673d86c08cd2f4692d292 100644 (file)
 
 *******************************************************************************/
 
-#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"
@@ -50,8 +49,8 @@ namespace Mf {
  * 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>
@@ -103,29 +102,6 @@ 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:
 
        /**
@@ -134,7 +110,8 @@ public:
 
        explicit Impl(const std::string& name) :
                Library<Impl>(name),
-               mContext(0),
+               //mContext(0),
+               mImage(Texture::getPath(getName())),
                mWidth(0),
                mHeight(0),
                mMode(0),
@@ -158,11 +135,6 @@ public:
 
        ~Impl()
        {
-               if (mContext)
-               {
-                       SDL_FreeSurface(mContext);
-               }
-
                unloadFromGL();
        }
 
@@ -174,6 +146,7 @@ public:
         * method makes them ready.
         */
 
+       /*
        static SDL_Surface* prepareImageForGL(SDL_Surface* surface)
        {
                int w = powerOfTwo(surface->w);
@@ -234,6 +207,7 @@ public:
 
                return image;
        }
+       */
 
        /**
         * Use SDL_image to load images from file.  A surface with the image data is
@@ -243,42 +217,17 @@ public:
 
        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();
        }
 
 
@@ -295,7 +244,7 @@ public:
                        return;
                }
 
-               if (!mContext) loadFromFile();
+               //if (!mContext) loadFromFile();
 
                glGenTextures(1, &mObject);
                glBindTexture(GL_TEXTURE_2D, mObject);
@@ -307,18 +256,18 @@ public:
                        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;
        }
 
 
@@ -378,7 +327,7 @@ public:
        }
 
 
-       SDL_Surface*            mContext;
+       Image                           mImage;
        unsigned                        mWidth;                 ///< Horizontal dimension of the image.
        unsigned                        mHeight;                ///< Vertical dimension.
 
index 07addc313c8d9fc4093f46e205e352dc563d83c0..5f8a248f91a9cefb7818fd7347bc438eedba241d 100644 (file)
@@ -121,7 +121,7 @@ public:
        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);
 
index eeec47e7eb7d4dcc00b4a6b17fd732f8e61fc93a..e4579fbc700951215a32b0669a2602c5b7f62fbf 100644 (file)
 
 *******************************************************************************/
 
-#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"
@@ -173,12 +172,8 @@ void Video::setIcon()
 {
        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();
        }
 }
 
index a45b1fba55f939bf031038e0e1c4f3ecd13daaa4..43bdf02e3d46393aed9b66a39f1dff5ed5f5fa35 100644 (file)
@@ -415,7 +415,7 @@ struct Scene::Impl : public Mf::Library<Impl>
                        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;
index c45d1693a7d63982f33c1a0f9c32d0f2099d259a..dc3785aa0068d5ba9c3e17f8765d120c8704707e 100644 (file)
@@ -66,7 +66,7 @@ struct Tilemap::Impl : public Mf::Library<Impl>
                std::string filePath = Tilemap::getPath(getName());
 
                script.importStandardLibraries();
-               importLogPrintFunction(script);
+               importLogFunctions(script);
                bindScriptConstants(script);
 
                if (script.doFile(filePath) != Mf::Script::SUCCESS)
index 31fa7c61ec12ff0e4eece93e720b44c3a1371d5a..3c171e55dc219d028fd6b6a7c85d6b21702934bb 100755 (executable)
@@ -9,9 +9,9 @@ then
        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
index e6dffa2122d138d3fe18c34ad6ba7d991fa5af6f..d3b28eefaaeb535bdd9312e0fe2e3144c364f0c7 100644 (file)
 # 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
 
 
 #
@@ -470,5 +65,5 @@ then
        exit 1
 fi
 
-rm -rf "$DEST"
+rm -rf "$BUILD_DIR"
 
diff --git a/win32/yoink.nsi.in b/win32/yoink.nsi.in
new file mode 100644 (file)
index 0000000..b1a1aed
--- /dev/null
@@ -0,0 +1,151 @@
+;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
+
This page took 0.102186 seconds and 4 git commands to generate.