b) Porting
III. Packagers
a) The build system
- b) Help requested
+ b) Targeting Win32
I. Users
problems, especially any bugs which complicate packaging on certain
systems, please send back patches.
-b) Help requested
+b) Targeting Win32
-If you can create packages for your favorite platform, please send them
-back to me and/or place the package in a public repository appropriate for
-your distribution or platform. I would especially appreciate packages in
-common formats such as deb, rpm, or OS X app bundles.
+If you have a working mingw32 toolchain with all the dependencies, you can
+build a win32 binary using a command such as this:
+
+./configure --host=mingw32 --prefix=/usr/mingw32/usr
+
+where mingw32 is the correct name of your toolchain. You can get all the
+non-standard dependencies from the git repository at win32/win32-libs.zip.
+Just unzip the contents of that archive into your toolchain. If everything
+goes smoothly, you should have a yoink.exe appropriate for the win32
+platform. You can then build a complete installer using "make package" if
+you have nsis installed.
AC_PROG_RANLIB
AM_PROG_CC_C_O
+PKG_PROG_PKG_CONFIG
+
AC_PATH_PROGS([DOXYGEN], [doxygen])
AC_SUBST(DOXYGEN)
[threads=$enableval],
[threads=no])
+AC_ARG_ENABLE([gtk],
+ [ --enable-gtk enable GTK+ info/warning dialogs],
+ [gtk=$enableval],
+ [gtk=no])
+
+AC_ARG_ENABLE([qt4],
+ [ --enable-qt4 enable QT info/warning dialogs],
+ [qt4=$enableval],
+ [qt4=no])
+
AC_ARG_WITH([log-level],
[AS_HELP_STRING([--with-log-level=NUM],
[0, none... 1, errors... 4, everything (default: 3)])],
[Define to 1 if you want to use threads for parallel tasks.])
fi
+if test x$gtk = xyes
+then
+ AC_DEFINE([USE_GTK], 1,
+ [Define to 1 if you want to use GTK+ info/error dialogs.])
+else
+if test x$qt4 = xyes
+then
+ AC_DEFINE([USE_QT4], 1,
+ [Define to 1 if you want to use QT info/error dialogs.])
+fi
+fi
+
AC_DEFINE_UNQUOTED([YOINK_LOGLEVEL], [$log_level],
[Define to detail level of logging.])
[missing=yes
echo "***** Missing liblua ($website) *****"])
+if test x$gtk = xyes
+then
+ ##### GTK+ 2.0 #####
+ website="http://www.gtk.org/"
+ PKG_CHECK_MODULES([GTK], [gtk+-2.0],
+ [LIBS="$LIBS $GTK_LIBS"
+ CFLAGS="$CFLAGS $GTK_CFLAGS"
+ CXXFLAGS="$CXXFLAGS $GTK_CFLAGS"],
+ [missing=yes
+ echo "***** Missing GTK+-2.0 ($website) *****"])
+fi
+
+if test x$qt4 = xyes
+then
+ ##### QT4 #####
+ website="http://qt.nokia.com/"
+ PKG_CHECK_MODULES([QT], [QtGui],
+ [LIBS="$LIBS $QT_LIBS"
+ CFLAGS="$CFLAGS $QT_CFLAGS"
+ CXXFLAGS="$CXXFLAGS $QT_CFLAGS"],
+ [missing=yes
+ echo "***** Missing QT ($website) *****"])
+fi
+
##### librt (optional) #####
AC_SEARCH_LIBS([clock_gettime], [rt],
[AC_DEFINE([HAVE_CLOCK_GETTIME], 1,
-- Scene API:
--
-- Functions:
--- SetPlayfieldBounds(point1, point2)
--- SetMaximumBounds(point1, point2)
+-- SetBounds(point1, point2)
-- ResetTransform()
-- Translate(x, y, z)
-- Scale(x, y, z) or Scale(xyz)
-- Rotate(axis, degree) or Rotate(x, y, z)
-- SetTexture(name)
--- MakeTilemap({width = ..., surface_type = ..., tiles = {}})
--- MakeBillboard({tile = ..., u_scale = ...})
+-- DrawTilemap({width = $num, [surface = TOP | LEFT | RIGHT], tiles})
+-- DrawTile(tile, [u_scale])
--
-- Globals:
--- detail - level of detail of the scene
+-- detail - level of detail of the scene (HIGH, MEDIUM, or LOW)
-SetPlayfieldBounds({0, 0, -100}, {1280, 500, 100})
-SetMaximumBounds({-160, 0, -192}, {1440, 480, 224})
+SetBounds({-5, 0, -6}, {45, 15, 7})
-- Left end tower block
ResetTransform()
Translate(-5, 0, 5)
-Scale(32)
SetTexture("TowerBlock1")
-MakeTilemap({
+DrawTilemap({
width = 5,
- tiles = {
- 2, 2, 2, 2, 2,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 1, 0, 0, 1, 0,
- 4, 4, 4, 4, 4
- }
-})
+ 2, 2, 2, 2, 2,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0,
+ 4, 4, 4, 4, 4})
-- Right side
ResetTransform()
Rotate(Y, 90)
Translate(0, 0, 5)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 5,
- surface_type = RIGHT,
- tiles = {
- 2, 2, 2, 2, 2,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6,
- 4, 5, 5, 5, 4
- }
-})
+ surface = RIGHT,
+ 2, 2, 2, 2, 2,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6,
+ 4, 5, 5, 5, 4})
-- Top
ResetTransform()
Rotate(X, 90)
Translate(-5, 15, 0)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 5,
- surface_type = TOP,
- tiles = {
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3
- }
-})
+ surface = TOP,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3})
-- Leftmost background tower block
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Front
-if detail > 1 then
+if detail > LOW then
ResetTransform()
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 7,
- tiles = {
- 2, 2, 2, 2, 2, 2, 2,
- 0, 1, 0, 0, 0, 1, 0,
- 0, 1, 0, 0, 0, 1, 0,
- 0, 1, 0, 0, 6, 1, 0,
- 0, 1, 0, 0, 0, 1, 0,
- 0, 1, 0, 0, 0, 1, 0,
- 0, 1, 0, 0, 0, 1, 0,
- 4, 4, 5, 5, 5, 4, 4
- }
- })
+ 2, 2, 2, 2, 2, 2, 2,
+ 0, 1, 0, 0, 0, 1, 0,
+ 0, 1, 0, 0, 0, 1, 0,
+ 0, 1, 0, 0, 6, 1, 0,
+ 0, 1, 0, 0, 0, 1, 0,
+ 0, 1, 0, 0, 0, 1, 0,
+ 0, 1, 0, 0, 0, 1, 0,
+ 4, 4, 5, 5, 5, 4, 4})
-- Right side
ResetTransform()
Rotate(Y, 90)
Translate(7, 0, 0)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 6,
- tiles = {
- 2, 2, 2, 2, 2, 2,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 4, 4, 4, 4, 4, 4
- }
- })
+ 2, 2, 2, 2, 2, 2,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 4, 4, 4, 4, 4, 4})
-- Top
ResetTransform()
Rotate(X, 90)
Translate(-2, 8, -6)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 9,
- tiles = {
- 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3
- }
- })
+ 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3})
end
-- Foreground building with pitched roof
ResetTransform()
Rotate(Y, -90)
Translate(10, 0, 1)
-Scale(32)
SetTexture("Building")
-MakeTilemap({
+DrawTilemap({
width = 4,
- surface_type = LEFT,
- tiles = {
- -1, 9, 11, -1,
- 9, 10, 12, 11,
- 15, 7, 7, 16,
- 3, 5, 6, 4,
- 3, 6, 5, 4
- }
-})
+ surface = LEFT,
+ -1, 9, 11, -1,
+ 9, 10, 12, 11,
+ 15, 7, 7, 16,
+ 3, 5, 6, 4,
+ 3, 6, 5, 4})
-- Right wall
ResetTransform()
Rotate(Y, -90)
Translate(13, 0, 1)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 4,
- surface_type = RIGHT,
- tiles = {
- -1, 9, 11, -1,
- 9, 10, 12, 11,
- 15, 7, 7, 16,
- 3, 5, 6, 4,
- 3, 8, 5, 4
- }
-})
+ surface = RIGHT,
+ -1, 9, 11, -1,
+ 9, 10, 12, 11,
+ 15, 7, 7, 16,
+ 3, 5, 6, 4,
+ 3, 8, 5, 4})
-- Front wall
ResetTransform()
Translate(10, 0, 5)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 3,
- tiles = {
- 15, 7, 16,
- 3, 5, 4,
- 3, 6, 4
- }
-})
+ 15, 7, 16,
+ 3, 5, 4,
+ 3, 6, 4})
-- Pitched roof
Rotate(X, 135)
Scale(1, 1.5, 1.5)
Translate(10, 5, 3)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 3,
- tiles = {
- 13, 13, 13,
- 13, 13, 13
- }
-})
+ 13, 13, 13,
+ 13, 13, 13})
-- Finial
ResetTransform()
Translate(10, 5, 3)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 3,
- tiles = {
- 18, 18, 18
- }
-})
+ 18, 18, 18})
-- Cheaty invisible platform
ResetTransform()
Translate(10, 4, 3)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 3,
- surface_type = TOP,
- tiles = {
- -1, -1, -1
- }
-})
+ surface = TOP,
+ -1, -1, -1})
-- The ground
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ResetTransform()
Rotate(X, 90)
Translate(-3, 0, 0)
-Scale(32)
SetTexture("Scenery")
-MakeTilemap({
+DrawTilemap({
width = 13,
- surface_type = TOP,
- tiles = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- }
-})
+ surface = TOP,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})
-- Front grass
-if detail > 2 then
+if detail > MEDIUM then
ResetTransform()
Scale(8, 1, 1)
Translate(1, -0.5, 5)
- Scale(32)
- MakeBillboard({
- tile = 2,
- u_scale = 8
- })
+ DrawTile({
+ 2,
+ u_scale = 8})
-- Back grass
ResetTransform()
Scale(8, 1, 1)
Translate(1, -0.5, 1)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 8
})
Scale(4, 1, 1)
Rotate(Y, -90)
Translate(1, -0.5, 1)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 4
})
Scale(4, 1, 1)
Rotate(Y, -90)
Translate(9, -0.5, 1)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 4
})
ResetTransform()
Scale(11, 1, 1)
Translate(7, 0, 0)
- Scale(32)
- MakeBillboard({
- tile = 4,
+ DrawTile({
+ 4,
u_scale = 11
})
end
-- Front wall
-if detail > 1 then
+if detail > LOW then
ResetTransform()
Translate(19, 0, 0)
- Scale(32)
SetTexture("Building")
- MakeTilemap({
+ DrawTilemap({
width = 4,
- tiles = {
- -1, 9, 11, -1,
- 9, 10, 12, 11,
- 15, 7, 7, 16,
- 3, 6, 5, 4,
- 3, 5, 6, 4,
- 3, 8, 5, 4
- }
- })
+ -1, 9, 11, -1,
+ 9, 10, 12, 11,
+ 15, 7, 7, 16,
+ 3, 6, 5, 4,
+ 3, 5, 6, 4,
+ 3, 8, 5, 4})
-- Left wall
ResetTransform()
Rotate(Y, -90)
Translate(19, 0, -3)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 3,
- tiles = {
- 15, 1, 16,
- 3, 7, 4,
- 3, 5, 4,
- 3, 0, 4
- }
- })
+ 15, 1, 16,
+ 3, 7, 4,
+ 3, 5, 4,
+ 3, 0, 4})
-- Right wall
ResetTransform()
Rotate(Y, -90)
Translate(23, 0, -3)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 3,
- tiles = {
- 15, 0, 16,
- 3, 7, 4,
- 3, 6, 4,
- 3, 2, 4
- }
- })
+ 15, 0, 16,
+ 3, 7, 4,
+ 3, 6, 4,
+ 3, 2, 4})
-- Left pitched roof
Scale(1, 1.5, 1.5)
Rotate(Y, -90)
Translate(21, 6, -3)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 3,
- tiles = {
- 13, 13, 13,
- 13, 13, 13
- }
- })
+ 13, 13, 13,
+ 13, 13, 13})
-- Right pitched roof
Scale(1, 1.5, 1.5)
Rotate(Y, -90)
Translate(21, 6, -3)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 3,
- tiles = {
- 13, 13, 13,
- 13, 13, 13
- }
- })
+ 13, 13, 13,
+ 13, 13, 13})
-- Finial
ResetTransform()
Rotate(Y, -90)
Translate(21, 6, -3)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 3,
- tiles = {
- 18, 18, 18
- }
- })
+ 18, 18, 18})
end
-- More ground to the right
ResetTransform()
Rotate(X, 90)
Translate(10, 0, 0)
-Scale(32)
SetTexture("Scenery")
-MakeTilemap({
+DrawTilemap({
width = 3,
- surface_type = TOP,
- tiles = {
- 1, 1, 1,
- 1, 1, 1,
- -1, -1, -1,
- -1, -1, -1,
- -1, -1, -1,
- -1, -1, -1,
- 1, 1, 1
- }
-})
+ surface = TOP,
+ 1, 1, 1,
+ 1, 1, 1,
+ -1, -1, -1,
+ -1, -1, -1,
+ -1, -1, -1,
+ -1, -1, -1,
+ 1, 1, 1})
-- Left part of center courtyard
ResetTransform()
Rotate(X, 90)
Translate(13, 0, 0)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 8,
- surface_type = TOP,
- tiles = {
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 1, 1,
- 0, 0, 0, 0, 0, 0, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 0, 0, 0
- }
-})
+ surface = TOP,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 0, 0, 0})
-- Front grass
-if detail > 2 then
+if detail > MEDIUM then
ResetTransform()
Scale(12, 1, 1)
Translate(14, -0.5, 5)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 12
})
ResetTransform()
Scale(4, 1, 1)
Translate(14, -0.5, 1)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 4
})
ResetTransform()
Translate(13, -0.5, 3)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 1
})
ResetTransform()
Translate(13, -0.5, 2)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 1
})
ResetTransform()
Rotate(Y, -90)
Translate(14, -0.5, 1)
- Scale(32)
- MakeTilemap({
+ DrawTilemap({
width = 4,
- tiles = {
- 2, -1, 2, 2
- }
- })
+ 2, -1, 2, 2})
-- Grass left of house
ResetTransform()
Rotate(Y, -90)
Translate(18, -0.5, 0)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 1
})
ResetTransform()
Rotate(Y, -90)
Translate(24, -0.5, 0)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 1
})
ResetTransform()
Scale(4, 1, 1)
Translate(19, -0.5, 4)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 4
})
ResetTransform()
Scale(4, 1, 1)
Translate(19, -0.5, 2)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 4
})
Scale(2, 1, 1)
Rotate(Y, -90)
Translate(19, -0.5, 2)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 2
})
Scale(2, 1, 1)
Rotate(Y, -90)
Translate(23, -0.5, 2)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 2
})
end
ResetTransform()
Rotate(X, 90)
Translate(21, 0, 0)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 7,
- surface_type = TOP,
- tiles = {
- 1, 1, 1, 1, 1, 0, 0,
- 1, 1, 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1
- }
-})
+ surface = TOP,
+ 1, 1, 1, 1, 1, 0, 0,
+ 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1})
-- Fence to right of back house
-if detail > 2 then
+if detail > MEDIUM then
ResetTransform()
Scale(4, 1, 1)
Translate(24, 0, 0)
- Scale(32)
- MakeBillboard({
- tile = 4,
+ DrawTile({
+ 4,
u_scale = 4
})
ResetTransform()
Scale(4, 1, 1)
Translate(24, -0.5, 1)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 4
})
Scale(2, 1, 1)
Rotate(Y, -90)
Translate(26, -0.5, 5)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 2
})
Scale(2, 1, 1)
Rotate(Y, -90)
Translate(35, -0.5, 5)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 2
})
ResetTransform()
Scale(5, 1, 1)
Translate(35, -0.5, 5)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 5
})
ResetTransform()
Scale(6, 1, 1)
Translate(34, -0.5, 1)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 6
})
ResetTransform()
Rotate(Y, -90)
Translate(34, -0.5, 0)
- Scale(32)
- MakeBillboard({
- tile = 2,
+ DrawTile({
+ 2,
u_scale = 1
})
end
ResetTransform()
Rotate(X, 90)
Translate(28, 0, 4)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 5,
- surface_type = TOP,
- tiles = {
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0
- }
-})
+ surface = TOP,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0})
-- Rightmost ground
ResetTransform()
Rotate(X, 90)
Translate(33, 0, 0)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 10,
- surface_type = TOP,
- tiles = {
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
- 0, 1, 1, 1, 1, 1, 1, -1, -1, -1
- }
-})
+ surface = TOP,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, -1, -1, -1,
+ 0, 1, 1, 1, 1, 1, 1, -1, -1, -1})
-- Right foreground tower block
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ResetTransform()
Translate(28, 0, 4)
-Scale(32)
SetTexture("TowerBlock1")
-MakeTilemap({
+DrawTilemap({
width = 5,
- tiles = {
- 2, 2, 2, 2, 2,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 0,
- 4, 4, 4, 4, 4
- }
-})
+ 2, 2, 2, 2, 2,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0,
+ 4, 4, 4, 4, 4})
-- Right side
ResetTransform()
Rotate(Y, 90)
Translate(33, 0, 4)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 6,
- surface_type = RIGHT,
- tiles = {
- 2, 2, 2, 2, 2, 2,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 5, 4, 5, 5, 4, 5
- }
-})
+ surface = RIGHT,
+ 2, 2, 2, 2, 2, 2,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 5, 4, 5, 5, 4, 5})
-- Left side
ResetTransform()
Rotate(Y, 90)
Translate(28, 0, 4)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 6,
- surface_type = LEFT,
- tiles = {
- 2, 2, 2, 2, 2, 2,
- 0, 1, 6, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0,
- 5, 4, 5, 5, 4, 5
- }
-})
+ surface = LEFT,
+ 2, 2, 2, 2, 2, 2,
+ 0, 1, 6, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0,
+ 5, 4, 5, 5, 4, 5})
-- Top
ResetTransform()
Rotate(X, 90)
Translate(28, 7, -2)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 5,
- surface_type = TOP,
- tiles = {
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3
- }
-})
+ surface = TOP,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3})
-- Right end tower block
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ResetTransform()
Translate(40, 0, 5)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 5,
- tiles = {
- 2, 2, 2, 2, 2,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 6, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 6, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 0, 1, 0, 0, 1,
- 4, 4, 4, 4, 4
- }
-})
+ 2, 2, 2, 2, 2,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 6, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 6, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 0, 1, 0, 0, 1,
+ 4, 4, 4, 4, 4})
-- Left side
ResetTransform()
Rotate(Y, 90)
Translate(40, 0, 5)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 5,
- surface_type = LEFT,
- tiles = {
- 2, 2, 2, 2, 2,
- 6, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 6, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 4, 5, 5, 5, 4
- }
-})
+ surface = LEFT,
+ 2, 2, 2, 2, 2,
+ 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 4, 5, 5, 5, 4})
-- Top
ResetTransform()
Rotate(X, 90)
Translate(40, 15, 0)
-Scale(32)
-MakeTilemap({
+DrawTilemap({
width = 5,
- surface_type = TOP,
- tiles = {
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3
- }
-})
+ surface = TOP,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3})
-- Background
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ResetTransform()
-Translate(-0.3, -0.17, -900)
-Scale(3200, 1600, 1)
+Translate(-0.3, -0.17, -28)
+Scale(100, 50, 1)
SetTexture("BackgroundFar")
-MakeBillboard()
+DrawTile()
-Translate(0, 0, 300)
+Translate(0, 0, 5)
SetTexture("BackgroundNear")
-MakeBillboard({
- blend = detail > 1 and true or false
+DrawTile({
+ blend = detail > LOW and true or false
})
-- Trees
-- Left courtyard
-if detail > 1 then
+if detail > LOW then
ResetTransform()
- Scale(96)
- Translate(250, -2.5, 16)
- MakeBillboard({
- tile = 1
- })
+ Scale(3)
+ Translate(7.75, -0.1, 0.5)
+ DrawTile(1)
end
-- Center courtyard
ResetTransform()
-Scale(96)
-Translate(610, -2.5, 85)
-MakeBillboard({
- tile = 0
-})
+--Translate(610, -2.5, 85)
+Scale(3)
+Translate(19, -0.1, 2.5)
+DrawTile(0)
ResetTransform()
-Scale(96)
-Translate(650, -2.5, 115)
-MakeBillboard({
- tile = 1
-})
+Scale(3)
+Translate(20.25, -0.1, 3.5)
+DrawTile(1)
-- Right courtyard
-if detail > 1 then
+if detail > LOW then
ResetTransform()
- Scale(96)
- Translate(1080, -2.5, 10)
- MakeBillboard({
- tile = 1
- })
+ Scale(3)
+ Translate(34, -0.1, 0.25)
+ DrawTile(1)
ResetTransform()
- Scale(96)
- Translate(1120, -2.5, -15)
- MakeBillboard({
- tile = 0
- })
+ Scale(3)
+ Translate(36, -0.1, -0.5)
+ DrawTile(0)
ResetTransform()
- Scale(96)
- Translate(1220, -2.5, -30)
- MakeBillboard({
- tile = 1
- })
+ Scale(3)
+ Translate(37, -0.1, 0.75)
+ DrawTile(1)
+end
+
+
+
+function GetZCoord(x, y)
+ return 3
+end
+
+
+-- Functions:
+-- DisplayText(text, seconds)
+-- Yield(seconds)
+-- SpawnItem(what, coords, timeout)
+-- SpawnRandomItem(coords, timeout)
+-- SpawnCharacter(what, coords, ai level)
+-- SpawnHeroine(coords)
+-- PlaySound(name)
+-- PlayMusic(name)
+-- BeginNewWave()
+
+-- Events:
+-- BadGuyDied(enemy)
+-- PlayedDied(player)
+-- SceneLoaded()
+
+-- Globals:
+-- numberOfBadGuys
+
+
+-- Events
+---------
+
+Event = {}
+
+function Event:SceneLoaded()
+ SpawnHeroine({500, 500})
+ local waveNum = BeginNewWave()
+ PopulateScene(waveNum)
+end
+
+function Event:BadGuyDied(enemy)
+ if numberOfBadGuys == 0 then
+ local waveNum = BeginNewWave()
+ PopulateScene(waveNum)
+ end
+ if math.random() <= 0.2 then
+ SpawnRandomItem(enemy.position)
+ end
+end
+
+
+-- Helper functions
+-------------------
+
+function PopulateScene(waveNum)
+ -- spawn some robot troopers
+ local numBadGuys = math.random(3, 2 * waveNum)
+ for i = 0, numBadGuys do
+ SpawnCharacter("RobotTrooper", RandomSpawnPlace(), RandomSkillLevel())
+ end
+
+ -- spawn some alien warriors
+ if waveNum >= 10 then
+ numBadGuys = math.random(3, 2 * waveNum)
+ for i = 0, numBadGuys do
+ SpawnCharacter("AlienWarrior", RandomSpawnPlace(), RandomSkillLevel())
+ end
+ end
+
+ -- spawn some jetbots
+ if waveNum >= 20 then
+ numBadGuys = math.random(3, 2 * waveNum)
+ for i = 0, numBadGuys do
+ SpawnCharacter("Jetbot", RandomSpawnPlace(), RandomSkillLevel())
+ end
+ end
+end
+
+function RandomSpawnPlace()
+ return {500, 500}
+end
+
+function RandomSkillLevel()
+ return "dumb"
end
--- /dev/null
+
+-- Scene loader script
+
+scenes = {"Classic"}
+
-- Example Yoink Configuration File
--- vim: ft=lua
+-- vim: ft=lua ts=4
-print "loading yoinkrc..."
+print "loading default settings..."
-- Set the level of detail to use when drawing scenes. This can be 1, 2 or
-- 3, where 1 shows the least amount of detail and 3 draws the scene with
-- the most detail.
-detail = 3
+detail = 3
--- Set the amount of time in seconds between each update of the physics
--- state. A value of 100 or higher is ideal for accurate physics
--- approximations. Values that are much lower cause the CPU to do less
--- work, but accuracy will suffer. Errors could be introduced in the game
--- with extremely low values.
+-- Set the number of times each second the physics state will be updated. A
+-- value of 100 or higher is ideal for accurate physics approximations. Values
+-- that are much lower cause the CPU to do less work, but accuracy will suffer.
+-- Errors could be introduced in the game with extremely low values.
-timestep = 80
+timestep = 80
-- Set the maximum number of frames that can be drawn per second. A value
-- of 50 is pretty good. If your computer is really old, you can get away
-- not be able to update the physics on schedule which could actually
-- significantly lower the quality of the animation.
-maxfps = 40
+maxfps = timestep / 2
-- Set whether or not to print the current actual framerate to the console.
-printfps = false
+printfps = false
-- Set whether or not the game will run in full-screen mode. If false, the
-- game will run in a window.
-fullscreen = false
+fullscreen = false
-- If the game is running in a window, set whether or not the window will
-- be resizable.
-resizable = true
+resizable = true
-- Set the resolution or size of the window. The value is an array with
-- three number elements representing the width, height, and bits per pixel
-- 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 = {1024, 786}
-- Set whether or not the cursor will be visible when you mouse over the
-- display of the game.
-showcursor = true
+showcursor = false
-- Set whether or not the drawing should use two buffers. This results in
-- a higher quality animation. You should usually leave this as true.
-doublebuffer = true
+doublebuffer = true
-- Set whether or not to sync with the display in order to reduce
-- distortion.
-swapcontrol = true
+swapcontrol = true
LICENSE="BSD-2 BSD LGPL-2.1 ZLIB"
SLOT="0"
KEYWORDS="amd64 ~ppc x86"
-IUSE="debug double-precision profile threads"
+IUSE="debug double-precision gtk qt4 threads"
RDEPEND="dev-lang/lua
media-libs/freealut
--disable-dependency-tracking \
$(use_enable debug) \
$(use_enable double-precision) \
- $(use_enable profile) \
+ $(use_enable gtk) \
+ $(use_enable qt4) \
$(use_enable threads)
}
#include "Log.hh"
-struct SpringForce
+class SpringForce
{
+public:
+
explicit SpringForce(Mf::Vector2 x) :
location(x) {}
Mf::Vector2 location;
};
-struct ResistanceForce
+class ResistanceForce
{
+public:
+
explicit ResistanceForce(Mf::Scalar scale = 1.0) :
k(scale) {}
mState.force = Mf::Vector2(0.0, 0.0);
//mState.forces.push_back(SpringForce(Mf::Vector2(500.0, 200.0)));
mState.forces.push_back(ResistanceForce(2.0));
- //mState.forces.push_back(Mf::LinearState<2>::GravityForce(-100.0));
+ //mState.forces.push_back(Mf::LinearState<2>::GravityForce(-400.0));
// starting position
- mState.position = Mf::Vector2(64.0, 64.0);
+ mState.position = Mf::Vector2(5.0, 5.0);
mState.momentum = Mf::Vector2(0.0, 0.0);
mState.recalculate();
animation.update(t, dt);
- Mf::Vector3 center(mState.position[0], mState.position[1], z);
- Mf::Vector3 a(mState.position[0] - 16.0, mState.position[1] - 16.0, z);
- Mf::Vector3 b(mState.position[0] + 16.0, mState.position[1] + 16.0, z);
+ 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);
mAabb.init(a, b);
mSphere.init(center, a);
Mf::Scalar coords[8];
tilemap.getTileCoords(frame, coords, orientation);
- Mf::Scalar s = 16.0;
+ Mf::Scalar s = 0.5;
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(coords[0], coords[1]);
- glVertex3(position[0]-s, position[1]-s, z);
+ glVertex3(position[0]-s, position[1]-s, mZCoord);
glTexCoord2f(coords[2], coords[3]);
- glVertex3(position[0]+s, position[1]-s, z);
+ glVertex3(position[0]+s, position[1]-s, mZCoord);
glTexCoord2f(coords[4], coords[5]);
- glVertex3(position[0]+s, position[1]+s, z);
+ glVertex3(position[0]+s, position[1]+s, mZCoord);
glTexCoord2f(coords[6], coords[7]);
- glVertex3(position[0]-s, position[1]+s, z);
- glEnd();
-
- //glColor3f(0.0f, 0.0f, 0.0f);
- Mf::Texture::resetBind();
-
- glBegin(GL_TRIANGLES);
- glVertex3(480.0, 190.0, 64.0);
- glVertex3(520.0, 190.0, 64.0);
- glVertex3(500.0, 210.0, 64.0);
+ glVertex3(position[0]-s, position[1]+s, mZCoord);
glEnd();
+}
- //glColor3f(1.0f, 1.0f, 1.0f);
+void Character::setZCoord(Mf::Scalar z)
+{
+ mZCoord = z;
}
}
+void Character::addImpulse(Mf::Vector2 impulse)
+{
+ mState.momentum += impulse;
+}
+
+void Character::addForce(Mf::Vector2 force)
+{
+ mState.force += force;
+}
+
+void Character::setPosition(Mf::Vector2 position)
+{
+ mState.position = position;
+}
+
+
/** vim: set ts=4 sw=4 tw=80: *************************************************/
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& aabb) const;
Tilemap tilemap;
private:
- static const Mf::Scalar z = 96.0;
+ mutable Mf::Scalar mZCoord;
};
*******************************************************************************/
#include <Moof/Engine.hh>
+#include <Moof/Exception.hh>
#include <Moof/Log.hh>
#include <Moof/Math.hh>
#include <Moof/OpenGL.hh>
#endif
+
+Mf::Scalar GameLayer::getZCoord(const Mf::Vector2& position) const
+{
+ Mf::Scalar z;
+
+ mScript.getGlobalTable().pushField("GetZCoord");
+ mScript.push(position[0]);
+ mScript.push(position[1]);
+ mScript.call(2, 1);
+ mScript.getTop().get(z);
+ mScript.pop();
+
+ return z;
+}
+
+void GameLayer::loadSceneLoader()
+{
+ std::string loaderPath = Scene::getPath("loader");
+ if (loaderPath == "")
+ {
+ throw Mf::Exception(Mf::ErrorCode::RESOURCE_NOT_FOUND, "loader");
+ }
+
+ Mf::Script::Status status = mScript.doFile(loaderPath);
+ if (status != Mf::Script::SUCCESS)
+ {
+ std::string str;
+ mScript[-1].get(str);
+
+ Mf::logScript("%s", str.c_str());
+ throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str.c_str());
+ }
+
+ mScript.getGlobalTable().pushField("scenes");
+ mScript.getTop().get(mSceneList);
+ if (mSceneList.size() == 0)
+ {
+ Mf::logScript("no variable `scenes' within loader");
+ throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, "no scenes to load");
+ }
+}
+
+void GameLayer::advanceScene()
+{
+ if (mSceneList.size() != 0)
+ {
+ mScene = Scene::alloc(mSceneList[0]);
+ mSceneList.erase(mSceneList.begin());
+ mScene->load(mScript);
+ }
+}
+
+
GameLayer::GameLayer() :
- mMusic("BeatTheCube"),
+ mMusic("NightFusionIntro"),
mPunchSound("Thump")
{
mMusic.setLooping(true);
mMusic.enqueue("NightFusionLoop");
mMusic.stream();
+ loadSceneLoader();
+ advanceScene(); // load the first scene
+
mHeroine = Heroine::alloc();
mHeroine->animation.startSequence("FlyDiagonallyUp");
Mf::Scalar a[6] = {0.0, 1.5, -0.5, 3.0, -2.0, 1.0};
mInterp.init(a, 2.0, Mf::Interpolator::OSCILLATE);
- mScene = Scene::alloc("Classic");
-
setProjection();
mHud = Hud::alloc();
mScene->checkForCollision(*mHeroine);
mCamera.setPosition(Mf::Vector3(-mHeroine->getState().position[0],
- -mHeroine->getState().position[1], -256));
+ -mHeroine->getState().position[1], -10));
//mCamera.lookAt(Mf::promote(mHeroine->getState().position));
//Mf::Vector3 heroinePosition = Mf::promote(mHeroine->getState().position);
mScene->drawIfVisible(alpha, mCamera.getFrustum());
+ mHeroine->setZCoord(getZCoord(mHeroine->getState().position));
mHeroine->draw(alpha);
}
void GameLayer::setProjection(Mf::Scalar width, Mf::Scalar height)
{
- mCamera.setProjection(cml::rad(60.0), width / height, 32.0, 2500.0);
+ mCamera.setProjection(cml::rad(60.0), width / height, 1.0, 200.0);
}
#include <iostream>
#include <string>
+#include <vector>
#include <boost/shared_ptr.hpp>
#include <Moof/Interpolator.hh>
#include <Moof/Layer.hh>
#include <Moof/Math.hh>
+#include <Moof/Script.hh>
#include <Moof/Sound.hh>
#include "Character.hh"
}
void pushed(Mf::Engine& engine);
+
void update(Mf::Scalar t, Mf::Scalar dt);
void draw(Mf::Scalar alpha) const;
bool handleEvent(const Mf::Event& event);
private:
+ void loadSceneLoader();
+ void advanceScene();
+
+ Mf::Scalar getZCoord(const Mf::Vector2& position) const;
+
void setProjection();
void setProjection(Mf::Scalar width, Mf::Scalar height);
+ // the script object must be mutable because some script functions must be
+ // called during draw
+ mutable Mf::Script mScript;
+ std::vector<std::string> mSceneList;
+
Mf::Sound mMusic;
+ Mf::Sound mPunchSound;
HeroineP mHeroine;
SceneP mScene;
- Mf::Sound mPunchSound;
Mf::PolynomialInterpolator<5> mInterp;
bool Heroine::handleEvent(const Mf::Event& event)
{
- Mf::Scalar force = 4000.0;
+ Mf::Scalar force = 40.0;
switch (event.type)
{
#include <Moof/Dispatcher.hh>
#include <Moof/Exception.hh>
#include <Moof/Log.hh>
+#include <Moof/ModalDialog.hh>
#include <Moof/OpenGL.hh>
#include <Moof/Resource.hh>
#include <Moof/Transition.hh>
std::cout << " Executable: " << argv[0] << std::endl
<< " Version: "VERSION << std::endl
-#ifdef __DATE__
+#if defined(__DATE__) && defined(__TIME__)
<< " Built: "__DATE__" "__TIME__ << std::endl
#endif
<< " Compiler: "COMPILER_STRING << std::endl
<< "-"
#endif
<< "double-precision "
+#ifndef USE_GTK
+ << "-"
+#endif
+ << "gtk "
#ifndef PROFILING_ENABLED
<< "-"
#endif
<< "profile "
+#ifndef USE_QT4
+ << "-"
+#endif
+ << "qt4 "
#ifndef USE_THREADS
<< "-"
#endif
}
-typedef cml::matrix< Mf::Scalar, cml::fixed<5,5>,
- cml::col_basis, cml::col_major > Matrix5;
-
int main(int argc, char* argv[])
{
if (argc > 1)
Mf::Resource::addSearchPath(YOINK_DATADIR);
- std::string iconFile = Mf::Resource::getPath("yoink.png");
+ std::string iconFile = Mf::Resource::getPath(PACKAGE".png");
// Build the list of config files to search for, in this order:
configFiles += configFile;
}
-
try
{
Mf::Engine app(argc, argv, PACKAGE_STRING, iconFile, configFiles);
app.run();
}
- catch (Mf::Exception e)
+ catch (const Mf::Exception& e)
{
- Mf::logError("unhandled exception: <<%s>>", e.what());
- Mf::logInfo("it's time to crash now :-(");
- throw e;
+ Mf::logError("unhandled exception (code %d): \"%s\"",
+ e.code(), e.what());
+
+ Mf::ModalDialog dialog;
+ dialog.title = PACKAGE_STRING;
+ dialog.text1 = "Unhandled Exception";
+ dialog.text2 = e.what();
+ dialog.type = Mf::ModalDialog::CRITICAL;
+ dialog.run();
+
+ return 1;
}
return 0;
Moof/Log.cc \
Moof/Log.hh \
Moof/Math.hh \
+ Moof/ModalDialog.hh \
Moof/Octree.hh \
Moof/OpenGL.hh \
Moof/Plane.cc \
#include "Dispatcher.hh"
#include "Engine.hh"
#include "Event.hh"
+#include "Exception.hh"
#include "Log.hh"
#include "Random.hh"
#include "Settings.hh"
mTimestep(0.01),
mPrintFps(false)
{
-#if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
+#if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
#else
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) != 0)
#endif
{
- logError("sdl is complaining: %s", SDL_GetError());
- throw Exception(Exception::SDL_ERROR);
+ const char* error = SDL_GetError();
+ logError("sdl is complaining: %s", error);
+ throw Exception(ErrorCode::SDL_INIT, error);
}
if (FE_Init() != 0)
{
- logError("fast events error: %s", FE_GetError());
- throw Exception(Exception::SDL_ERROR);
+ const char* error = FE_GetError();
+ logError("fast events error: %s", error);
+ throw Exception(ErrorCode::FASTEVENTS_INIT, error);
}
alutInit(&argc, argv);
#include <boost/shared_ptr.hpp>
-#include <Moof/Exception.hh>
#include <Moof/Layer.hh>
#include <Moof/Math.hh>
class Engine
{
- class Impl;
- boost::shared_ptr<Impl> mImpl;
-
public:
Engine(int argc, char* argv[], const std::string& name,
LayerP pop(Layer* layer);
void clear();
- struct Exception : public Mf::Exception
- {
- explicit Exception(unsigned error) :
- Mf::Exception(error) {}
+private:
- void raise()
- {
- throw *this;
- }
- };
+ class Impl;
+ boost::shared_ptr<Impl> mImpl;
};
#ifndef _MOOF_EXCEPTION_HH_
#define _MOOF_EXCEPTION_HH_
+#include <cstring>
#include <exception>
-#include <boost/shared_ptr.hpp>
+
+#include <Moof/Math.hh>
namespace Mf {
-struct Exception : public std::exception
+class Exception : public std::exception
{
- enum
+public:
+
+ explicit Exception(unsigned code, const char* what = "")
{
- FILE_NOT_FOUND = 1,
- OPENGL_ERROR = 2,
- OPENAL_ERROR = 3,
- SDL_ERROR = 4
- };
-
- explicit Exception(unsigned error) :
- code(error) {}
+ mWhat[sizeof(mWhat)-1] = '\0';
+ strncpy(mWhat, what, sizeof(mWhat)-1);
+ mCode = code;
+ }
virtual ~Exception() throw() {}
virtual void raise()
throw *this;
}
- virtual const char* what() const throw()
+ unsigned code() const throw()
+ {
+ return mCode;
+ }
+
+ const char* what() const throw()
{
- switch (code)
- {
- case FILE_NOT_FOUND:
- return "file not found";
- case OPENGL_ERROR:
- return "opengl error";
- case OPENAL_ERROR:
- return "openal error";
- case SDL_ERROR:
- return "sdl error";
- }
- return "unknown error";
+ return mWhat;
}
- unsigned code;
+private:
+
+ unsigned mCode;
+ char mWhat[1024];
+};
+
+namespace ErrorCode {
+enum Code
+{
+ NONE = 0,
+ FASTEVENTS_INIT, // description
+ FILE_NOT_FOUND, // path of missing file
+ RESOURCE_NOT_FOUND, // name of missing resource
+ SCRIPT_ERROR, // description
+ SDL_INIT, // description
+ SDL_VIDEOMODE, // -
+ UNKNOWN_AUDIO_FORMAT, // -
+ UNKNOWN_IMAGE_FORMAT, // -
};
+} // namespace ErrorCode
} // namespace Mf
* interested code.
*/
-#include <memory>
#include <string>
#include <boost/shared_ptr.hpp>
--- /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_MODALDIALOG_HH_
+#define _MOOF_MODALDIALOG_HH_
+
+#include <string>
+
+#if defined(_WIN32) || defined(__WIN32__)
+#include <windows.h>
+#elif defined(__APPLE__) && defined(__MACH__)
+#include <Carbon/Carbon.h>
+#elif USE_GTK
+#include <gtk/gtk.h>
+#elif USE_QT4
+#include <QApplication>
+#include <QIcon>
+#include <QMessageBox>
+#endif
+
+#include <Moof/Resource.hh>
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+namespace Mf {
+
+
+/**
+ * Small wrapper over various user interface modal dialog windows.
+ */
+
+struct ModalDialog
+{
+ enum Type
+ {
+ INFO = 1,
+ WARNING = 2,
+ CRITICAL = 3
+ };
+
+ std::string title;
+ Type type;
+ std::string text1;
+ std::string text2;
+
+ void run() const
+ {
+#if USE_GTK
+
+ int argc = 0;
+ char** argv;
+ gtk_init(&argc, &argv);
+
+ GtkMessageType iconType;
+ switch (type)
+ {
+ case WARNING:
+ iconType = GTK_MESSAGE_WARNING;
+ break;
+ case CRITICAL:
+ iconType = GTK_MESSAGE_ERROR;
+ break;
+ default:
+ iconType = GTK_MESSAGE_INFO;
+ break;
+ }
+
+ GtkWidget* dialog = gtk_message_dialog_new(NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT, iconType,
+ GTK_BUTTONS_CLOSE, "%s", text1.c_str());
+ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+ "%s", text2.c_str());
+ gtk_window_set_title(GTK_WINDOW(dialog), title.c_str());
+
+ std::string iconPath = Resource::getPath(PACKAGE".png");
+ GdkPixbuf* iconPixbuf = gdk_pixbuf_new_from_file(iconPath.c_str(), NULL);
+ gtk_window_set_icon(GTK_WINDOW(dialog), iconPixbuf);
+
+ 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...
+
+#elif USE_QT4
+
+ int argc = 0;
+ char** argv;
+ QApplication qtApp(argc, argv);
+
+ QMessageBox::Icon iconType;
+ switch (type)
+ {
+ case WARNING:
+ iconType = QMessageBox::Warning;
+ break;
+ case CRITICAL:
+ iconType = QMessageBox::Critical;
+ break;
+ default:
+ iconType = QMessageBox::Information;
+ break;
+ }
+
+ QMessageBox dialog;
+ dialog.setWindowTitle(title.c_str());
+ dialog.setIcon(iconType);
+ dialog.setText(text1.c_str());
+ dialog.setInformativeText(text2.c_str());
+ dialog.setStandardButtons(QMessageBox::Close);
+
+ std::string iconPath = Resource::getPath(PACKAGE".png");
+ QIcon icon(iconPath.c_str());
+ dialog.setWindowIcon(icon);
+
+ dialog.exec();
+
+#endif
+ }
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_MODALDIALOG_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
std::vector<std::string> Resource::searchPaths_;
-Resource::~Resource() {}
-
-
void Resource::addSearchPath(const std::string& directory)
{
std::string path(directory);
path += '/';
}
-#if defined(__WIN32__) || defined(_WIN32) || defined(_WIN64)
+#if defined(_WIN32) || defined(__WIN32__)
boost::replace_all(path, "/", "\\");
#endif
std::string path(name);
-#if defined(__WIN32__) || defined(_WIN32) || defined(_WIN64)
+#if defined(_WIN32) || defined(__WIN32__)
boost::replace_all(path, "/", "\\");
#endif
std::string fullPath(*it);
fullPath += path;
- logDebug("looking for resource %s at %s", name.c_str(), path.c_str());
-
- if (access(fullPath.c_str(), R_OK) == 0)
- {
- logDebug("found resource %s at %s", name.c_str(), path.c_str());
- return fullPath;
- }
+ if (access(fullPath.c_str(), R_OK) == 0) return fullPath;
}
+ logWarning("cannot find resource %s", name.c_str());
+
// empty string
return std::string();
}
#include <string>
#include <vector>
-#include <Moof/Exception.hh>
-
namespace Mf {
{
public:
- virtual ~Resource();
+ virtual ~Resource() {}
/**
static std::string getPath(const std::string& name);
-
- struct Exception : public Mf::Exception
- {
- explicit Exception(unsigned error) :
- Mf::Exception(error) {}
-
- void raise()
- {
- throw *this;
- }
- };
-
private:
static std::vector<std::string> searchPaths_;
#include <lua.hpp>
-#include <Moof/Exception.hh>
#include <Moof/Log.hh>
{
typedef boost::function<int(Script&)> Function;
- enum TYPE
+ enum Type
{
NONE = LUA_TNONE,
NIL = LUA_TNIL,
THREAD = LUA_TTHREAD
};
- enum STATUS
+ enum Status
{
SUCCESS = 0,
YIELD = LUA_YIELD,
FILE_ERROR = LUA_ERRFILE
};
- enum PSEUDO_INDEX
+ enum PseudoIndex
{
REGISTRY = LUA_REGISTRYINDEX,
ENVIRONMENT = LUA_ENVIRONINDEX,
};
/**
- * This is the most noticeable abstraction on top of the standard Lua API.
+ * This is the most prominent abstraction on top of the standard Lua API.
* A Value object represents a value on the stack. More specifically, it
* represents a position on the stack. The distinction is only important
* when values are moved around on the stack or if the Value represents a
bool isLightData() const { return (bool)lua_islightuserdata(state, index); }
/**
- * Check the value and throw and error if its the wrong type. This
- * method never returns because it does a long jump. Consequently,
- * constructed C++ objects which exist on the stack between the current
- * frame and some lua function will not be destructed. That's not a
- * problem for objects that only exist on the stack, but any objects
- * that allocate memory on the heap (such as containers or strings) will
- * leak. Therefore, you should only call this method after cleaning up
- * such objects.
+ * Check the value and throw an error if its the wrong type. There's a
+ * little caveat: This method never returns because it does a long jump.
+ * Consequently, constructed C++ objects which exist on the stack
+ * between the current frame and some lua function will not be
+ * destructed. That's not a problem for objects that only exist on the
+ * stack, but any objects that allocate memory on the heap (such as
+ * containers or strings) will leak. Therefore, you should only call
+ * this method after cleaning up such objects. The best thing to do for
+ * defining functions is to simply check all the parameters at the
+ * get-go before any C++ objects are even constructed.
*/
- void requireType(TYPE type) const
+ void requireType(Type type) const
{
if (type != getType())
{
* Get the type of the value.
*/
- TYPE getType() const
+ Type getType() const
{
- return (TYPE)lua_type(state, index);
+ return (Type)lua_type(state, index);
}
/**
}
- STATUS doString(const std::string& commands)
+ Status doString(const std::string& commands)
{
- return (STATUS)luaL_dostring(mState, commands.c_str());
+ return (Status)luaL_dostring(mState, commands.c_str());
}
- STATUS doFile(const std::string& file)
+ Status doFile(const std::string& file)
{
- return (STATUS)luaL_dofile(mState, file.c_str());
+ return (Status)luaL_dofile(mState, file.c_str());
}
lua_pushthread(mState);
}
- STATUS resume(int nargs)
+ Status resume(int nargs)
{
- return (STATUS)lua_resume(mState, nargs);
+ return (Status)lua_resume(mState, nargs);
}
- STATUS getStatus() const
+ Status getStatus() const
{
- return (STATUS)lua_status(mState);
+ return (Status)lua_status(mState);
}
int yield(int results)
lua_xmove(thread.mState, mState, n);
}
- STATUS pushCode(const std::string& filename)
+ Status pushCode(const std::string& filename)
{
- return (STATUS)luaL_loadfile(mState, filename.c_str());
+ return (Status)luaL_loadfile(mState, filename.c_str());
}
- STATUS pushCode(const std::string& name, const char* buffer, size_t size)
+ Status pushCode(const std::string& name, const char* buffer, size_t size)
{
- return (STATUS)luaL_loadbuffer(mState, buffer, size, name.c_str());
+ return (Status)luaL_loadbuffer(mState, buffer, size, name.c_str());
}
void* pushNewData(size_t size)
* is any number of return values, depending on the callee).
*/
- STATUS call(int nargs, int nresults = LUA_MULTRET)
+ Status call(int nargs, int nresults = LUA_MULTRET)
{
- return (STATUS)lua_pcall(mState, nargs, nresults, 0);
+ return (Status)lua_pcall(mState, nargs, nresults, 0);
}
lua_gc(mState, LUA_GCSETSTEPMUL, step);
}
-
-
- struct Exception : public Mf::Exception
- {
- explicit Exception(unsigned error) :
- Mf::Exception(error) {}
-
- void raise()
- {
- throw *this;
- }
- };
-
-
private:
Script(lua_State* state) :
*******************************************************************************/
#include <cstdio>
+#include <deque>
#include <string>
-#include <queue>
#include <vector>
#include <AL/al.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
+#include "Exception.hh"
#include "Library.hh"
#include "Log.hh"
#include "Sound.hh"
class Buffer : public Library<Buffer>
{
- OggVorbis_File mOggStream;
- ALenum mFormat;
- ALsizei mFreq;
- std::vector<ALuint> mObjects;
-
public:
Buffer(const std::string& name) :
- Library<Buffer>(name)
+ Library<Buffer>(name),
+ mBuffer(-1)
{
mOggStream.datasource = 0;
openFile();
~Buffer()
{
- while (!mObjects.empty())
- {
- alDeleteBuffers(1, &mObjects.back());
- mObjects.pop_back();
- }
-
if (mOggStream.datasource)
{
ov_clear(&mOggStream);
}
+ if (int(mBuffer) != -1) alDeleteBuffers(1, &mBuffer);
}
{
logWarning("error while loading sound %s",
getName().c_str());
- throw Exception(Exception::BAD_AUDIO_FORMAT);
+ throw Exception(ErrorCode::UNKNOWN_AUDIO_FORMAT);
}
vorbis_info* vorbisInfo = ov_info(&mOggStream, -1);
if (size == 0)
{
logWarning("decoded no bytes from %s", getName().c_str());
- //throw Exception(Exception::FILE_NOT_FOUND);
+ //throw Exception("file_not_found");
return;
}
- ALuint obj;
- alGenBuffers(1, &obj);
-
- alBufferData(obj, mFormat, data, size, mFreq);
-
- mObjects.push_back(obj);
+ alGenBuffers(1, &mBuffer);
- alSourcei(source, AL_BUFFER, obj);
+ alBufferData(mBuffer, mFormat, data, size, mFreq);
+ alSourcei(source, AL_BUFFER, mBuffer);
- // don't need this anymore
+ // don't need to keep this loaded
ov_clear(&mOggStream);
mOggStream.datasource = 0;
}
-
- void beginStream(ALuint source, int nBuffers = 8)
- {
- if (!mOggStream.datasource) openFile();
- if (!mOggStream.datasource) return;
-
- ALuint objs[nBuffers];
- alGenBuffers(nBuffers, objs);
-
- for (int i = 0; i < nBuffers; ++i)
- {
- mObjects.push_back(objs[i]);
- stream(objs[i]);
- }
-
- alSourceQueueBuffers(source, nBuffers, objs);
- }
-
- enum StreamStatus
- {
- STREAM_OK = 0,
- STREAM_EOF = 1,
- STREAM_WRONG = 2
- };
-
- StreamStatus stream(ALuint buffer)
+ bool stream(ALuint buffer)
{
- std::vector<ALuint>::iterator it =
- std::find(mObjects.begin(), mObjects.end(), buffer);
-
- // that buffer doesn't belong to us
- if (it == mObjects.end()) return STREAM_WRONG;
-
char data[BUFFER_SIZE];
int size = 0;
}
}
- if (size == 0) return STREAM_EOF;
+ if (size == 0) return false;
alBufferData(buffer, mFormat, data, size, mFreq);
- return STREAM_OK;
+ return true;
}
- inline void rewind()
+ void rewind()
{
if (!mOggStream.datasource) openFile();
else ov_raw_seek(&mOggStream, 0);
}
- // delete unused buffers, return true if all buffers deleted
- inline bool clear()
- {
- // clear any openal errors
- alGetError();
+ private:
- while (!mObjects.empty())
- {
- ALuint buffer = mObjects.back();
- alDeleteBuffers(1, &buffer);
-
- // if an error occured, the buffer was not deleted because it's
- // still in use by some source
- if (alGetError() != AL_NO_ERROR) return false;
+ OggVorbis_File mOggStream;
+ ALenum mFormat;
+ ALsizei mFreq;
+ ALuint mBuffer;
+ };
- mObjects.pop_back();
- }
- return true;
- }
- };
+ Impl()
+ {
+ init();
+ }
+ Impl(const std::string& name)
+ {
+ init();
+ enqueue(name);
+ }
- Impl(const std::string& name) :
- mBuffer(Buffer::getInstance(name)),
- mIsPlaying(false),
- mIsLooping(false)
+ void init()
{
ALfloat zero[] = {0.0f, 0.0f, 0.0f};
alSourcef(mSource, AL_GAIN, 1.0f);
alSourcefv(mSource, AL_POSITION, zero);
alSourcefv(mSource, AL_VELOCITY, zero);
+
+ mIsPlaying = false;
+ mIsLooping = false;
}
~Impl()
{
+ stop();
+
alDeleteSources(1, &mSource);
+
+ while (!mBufferObjects.empty())
+ {
+ alDeleteBuffers(1, &mBufferObjects.back());
+ mBufferObjects.pop_back();
+ }
}
void play()
{
+ if (mQueue.empty()) return;
+
ALenum type;
alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
if (type != AL_STATIC)
{
- mBuffer->loadAll(mSource);
+ mQueue.front()->loadAll(mSource);
}
alSourcei(mSource, AL_LOOPING, mIsLooping);
void stream()
{
- ALenum type;
- alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
+ stop();
alSourcei(mSource, AL_BUFFER, AL_NONE);
- mBuffer->rewind();
- mBuffer->beginStream(mSource);
+ mQueue.front()->rewind();
+ beginStream();
alSourcei(mSource, AL_LOOPING, AL_FALSE);
alSourcePlay(mSource);
Timer::REPEAT);
}
- inline void update()
+ void beginStream()
+ {
+ ALuint buffer;
+ for (int i = mBufferObjects.size(); i < 4; ++i)
+ {
+ alGenBuffers(1, &buffer);
+ mBufferObjects.push_back(buffer);
+ }
+ for (int i = 0; i < 4; ++i)
+ {
+ buffer = mBufferObjects[i];
+ mQueue.front()->stream(buffer);
+ alSourceQueueBuffers(mSource, 1, &buffer);
+ }
+ }
+
+
+ void update()
{
ALint finished = 0;
while (finished-- > 0)
{
- ALuint buffer;
+ ALuint bufferObj;
+ alSourceUnqueueBuffers(mSource, 1, &bufferObj);
- alSourceUnqueueBuffers(mSource, 1, &buffer);
+ BufferP buffer = mQueue.front();
+ bool streamed = buffer->stream(bufferObj);
- Buffer::StreamStatus status = mBuffer->stream(buffer);
-
- if (status == Buffer::STREAM_OK)
+ if (streamed)
{
- alSourceQueueBuffers(mSource, 1, &buffer);
+ alSourceQueueBuffers(mSource, 1, &bufferObj);
}
- else if (status == Buffer::STREAM_EOF)
+ else
{
+ // the buffer couldn't be streamed, so get rid of it
+ mQueue.pop_front();
+
if (!mQueue.empty())
{
// begin the next buffer in the queue
- mExpired.push_back(mBuffer);
- mBuffer = mQueue.front();
- mQueue.pop();
- mBuffer->beginStream(mSource, 1);
+ mQueue.front()->rewind();
+ mQueue.front()->stream(bufferObj);
+ alSourceQueueBuffers(mSource, 1, &bufferObj);
+ logInfo("loading new buffer");
}
else if (mIsLooping)
{
- // restart from the beginning
- mBuffer->rewind();
- mBuffer->stream(buffer);
- alSourceQueueBuffers(mSource, 1, &buffer);
+ // reload the same buffer
+ mQueue.push_back(buffer);
+ buffer->rewind();
+ buffer->stream(bufferObj);
+ alSourceQueueBuffers(mSource, 1, &bufferObj);
+ logInfo("looping same buffer");
}
}
- else if (status == Buffer::STREAM_WRONG)
- {
- clear();
- mBuffer->beginStream(mSource, 1);
- }
}
ALenum state;
alGetSourcei(mSource, AL_SOURCE_STATE, &state);
// restart playing if we're stopped but supposed to be playing... this
- // means we didn't queue enough and the audio skipped
+ // means we didn't queue enough and the audio skipped :-(
if (mIsPlaying && state != AL_PLAYING)
{
alSourcePlay(mSource);
}
}
- inline void clear()
- {
- // try to remove expired buffers
- std::vector<BufferP>::iterator it;
- for (it = mExpired.end() - 1; it >= mExpired.begin(); --it)
- {
- if ((*it)->clear()) mExpired.erase(it);
- }
- }
-
void stop()
{
alSourceStop(mSource);
mIsPlaying = false;
+
+ mStreamTimer.invalidate();
}
- inline void pause()
+ void pause()
{
alSourcePause(mSource);
mIsPlaying = false;
+
+ mStreamTimer.invalidate();
}
- inline void resume()
+ void resume()
{
alSourcePlay(mSource);
mIsPlaying = true;
+
+ ALenum type;
+ alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
+
+ if (type == AL_STREAMING)
+ {
+ mStreamTimer.init(boost::bind(&Impl::streamUpdate, this, _1, _2),
+ 1.0, Timer::REPEAT);
+ }
}
- inline void setSample(const std::string& name)
+ void setSample(const std::string& name)
{
bool playing = isPlaying();
ALenum type;
alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
stop();
+ mQueue.clear();
//alSourcei(mSource, AL_BUFFER, AL_NONE);
- mBuffer = Buffer::getInstance(name);
+ enqueue(name);
- if (type == AL_STREAMING)
- {
- if (playing) stream();
- }
- else
+ if (playing)
{
- if (playing) play();
+ if (type == AL_STREAMING) stream();
+ else play();
}
}
- inline void enqueue(const std::string& name)
+ void enqueue(const std::string& name)
{
BufferP buffer = Buffer::getInstance(name);
- mQueue.push(buffer);
+ mQueue.push_back(buffer);
}
- inline bool isPlaying() const
+ bool isPlaying() const
{
if (mIsPlaying) return true;
}
- inline void setLooping(bool looping)
+ void setLooping(bool looping)
{
mIsLooping = looping;
}
- ALuint mSource;
- BufferP mBuffer;
-
- bool mIsPlaying;
- bool mIsLooping;
-
- std::queue<BufferP> mQueue;
- std::vector<BufferP> mExpired;
-
- Timer mStreamTimer;
-
void streamUpdate(Timer& timer, Scalar t)
{
// don't let the music die!
// TODO - might be nice to also allow using threads for streaming rather
// than a timer, probably as a compile-time option
}
+
+
+ ALuint mSource;
+ std::vector<ALuint> mBufferObjects;
+
+ bool mIsPlaying;
+ bool mIsLooping;
+
+ std::deque<BufferP> mQueue;
+
+ Timer mStreamTimer;
};
+
+Sound::Sound() :
+ // pass through
+ mImpl(new Sound::Impl) {}
+
Sound::Sound(const std::string& name) :
// pass through
mImpl(new Sound::Impl(name)) {}
class Sound : public Resource
{
- class Impl;
- boost::shared_ptr<Impl> mImpl;
-
public:
static SoundP alloc(const std::string& name)
return SoundP(new Sound(name));
}
+ Sound();
explicit Sound(const std::string& name);
void play();
void stream();
- // TODO - this API sucks
+ // TODO this API sucks... refactor me!!
void stop();
void pause();
static std::string getPath(const std::string& name);
+private:
- struct Exception : public Mf::Exception
- {
- enum
- {
- BAD_AUDIO_FORMAT = 1024
- };
-
- explicit Exception(unsigned error) :
- Mf::Exception(error) {}
-
- void raise()
- {
- throw *this;
- }
-
- const char* what() const throw()
- {
- switch (code)
- {
- case BAD_AUDIO_FORMAT:
- return "unknown audio format";
- }
- return Mf::Exception::what();
- }
- };
+ class Impl;
+ boost::shared_ptr<Impl> mImpl;
};
};
+inline bool checkCollision(const Sphere& a, const Sphere& b)
+{
+ Scalar d = (a.point - b.point).length();
+ return d < (a.radius + b.radius);
+}
+
+
} // namespace Mf
#endif // _MOOF_SPHERE_HH_
#include <SDL/SDL_image.h>
#include "Dispatcher.hh"
+#include "Exception.hh"
#include "Library.hh"
#include "Log.hh"
#include "OpenGL.hh"
if (!surface)
{
logWarning("texture not found: %s", getName().c_str());
- throw Exception(Exception::FILE_NOT_FOUND);
+ throw Exception(ErrorCode::FILE_NOT_FOUND, getName().c_str());
}
SDL_Surface* temp = prepareImageForGL(surface);
if (!temp)
{
- throw Exception(Exception::OPENGL_ERROR);
+ throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT);
}
if (temp->format->BytesPerPixel == 3)
else
{
SDL_FreeSurface(temp);
- throw Exception(Exception::BAD_IMAGE_FORMAT);
+ throw Exception(ErrorCode::UNKNOWN_IMAGE_FORMAT);
}
mWidth = temp->w;
* Image-loading and OpenGL texture loading.
*/
-#include <stdexcept>
-
#include <boost/shared_ptr.hpp>
-#include <Moof/Exception.hh>
#include <Moof/OpenGL.hh>
#include <Moof/Resource.hh>
class Texture : public Resource
{
- class Impl;
- boost::shared_ptr<Impl> mImpl;
-
public:
static TextureP alloc(const std::string& name)
return TextureP(new Texture(name));
}
- Texture(const std::string& name);
+ explicit Texture(const std::string& name);
void bind() const;
GLuint getObject() const;
static std::string getPath(const std::string& name);
+private:
- struct Exception : public Mf::Exception
- {
- enum
- {
- BAD_IMAGE_FORMAT = 1024
- };
-
- explicit Exception(unsigned error) :
- Mf::Exception(error) {}
-
- void raise()
- {
- throw *this;
- }
-
- const char* what() const throw()
- {
- switch (code)
- {
- case BAD_IMAGE_FORMAT:
- return "unknown image format";
- }
- return Mf::Exception::what();
- }
- };
+ class Impl;
+ boost::shared_ptr<Impl> mImpl;
};
#include <cerrno>
#include <ctime>
#include <limits>
-#include <stdexcept>
#include "Log.hh"
#include "Timer.hh"
namespace Mf {
-Scalar Timer::nextFire_ = std::numeric_limits<Scalar>::max();
-std::map<unsigned,Timer&> Timer::timers_;
+Scalar Timer::gNextFire = std::numeric_limits<Scalar>::max();
+std::map<unsigned,Timer&> Timer::gTimers;
unsigned Timer::getNewID()
}
mId = getNewID();
- timers_.insert(std::pair<unsigned,Timer&>(mId, *this));
+ gTimers.insert(std::pair<unsigned,Timer&>(mId, *this));
- if (mAbsolute < nextFire_) nextFire_ = mAbsolute;
+ if (mAbsolute < gNextFire) gNextFire = mAbsolute;
}
}
{
if (mMode != INVALID)
{
- timers_.erase(mId);
+ gTimers.erase(mId);
mMode = INVALID;
- if (isEqual(mAbsolute, nextFire_)) nextFire_ = findNextFire();
+ if (isEqual(mAbsolute, gNextFire)) gNextFire = findNextFire();
}
}
if (isEqual(mAbsolute, t, 1.0)) mAbsolute += mInterval;
else mAbsolute = mInterval + t;
- if (isEqual(absolute, nextFire_)) nextFire_ = findNextFire();
+ if (isEqual(absolute, gNextFire)) gNextFire = findNextFire();
}
else
{
std::map<unsigned,Timer&>::iterator it;
Scalar nextFire = std::numeric_limits<Scalar>::max();
- for (it = timers_.begin(); it != timers_.end(); ++it)
+ for (it = gTimers.begin(); it != gTimers.end(); ++it)
{
Scalar absolute = (*it).second.mAbsolute;
if (absolute < nextFire) nextFire = absolute;
{
std::map<unsigned,Timer&>::iterator it;
- if (nextFire_ > t) return;
+ if (gNextFire > t) return;
- for (it = timers_.begin(); it != timers_.end(); ++it)
+ for (it = gTimers.begin(); it != gTimers.end(); ++it)
{
Timer& timer = (*it).second;
if (timer.isExpired()) timer.fire();
#if HAVE_CLOCK_GETTIME
-// Since the monotonic clock will provide us with the timer since the computer
+// Since the monotonic clock will provide us with the time since the computer
// started, the number of seconds since that time could easily become so large
// that it cannot be accurately stored in a float (even with as little two days
// uptime), therefore we need to start from a more recent reference (when the
{
struct timespec ts;
- if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
- {
- throw std::runtime_error("cannot access monotonic clock");
- }
+ ASSERT(clock_gettime(CLOCK_MONOTONIC, &ts) == 0 && "cannot access clock");
return Scalar(ts.tv_sec - reference) + Scalar(ts.tv_nsec) / 1000000000.0;
}
namespace Mf {
-struct Timer
+class Timer
{
+public:
+
enum Mode
{
INVALID = -1,
static Scalar getNextFire()
{
- return nextFire_;
+ return gNextFire;
}
static void fireIfExpired(Scalar t);
Scalar mInterval;
unsigned mId;
- static Scalar nextFire_;
- static std::map<unsigned,Timer&> timers_;
+ static Scalar gNextFire;
+ static std::map<unsigned,Timer&> gTimers;
};
*******************************************************************************/
-#include <stdexcept>
-
#include <SDL/SDL_image.h>
#include "Dispatcher.hh"
+#include "Exception.hh"
#include "Log.hh"
#include "Settings.hh"
#include "Video.hh"
mAttribs.mode[1] = mode[1];
mAttribs.mode[2] = mode[2];
-#if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
+#if defined(_WIN32) || defined(__WIN32__)
// on win32, creating a new context via SDL_SetVideoMode will wipe
// out the GL state, so we gotta notify everyone to reload their
// state after the change
logInfo("video context recreated");
#endif
}
- else throw Exception(Exception::SDL_ERROR);
+ else throw Exception(ErrorCode::SDL_VIDEOMODE);
}
}
#include <SDL/SDL.h>
-#include <Moof/Exception.hh>
-
namespace Mf {
Video();
explicit Video(const Attributes& attribs);
- explicit Video(const std::string& caption, const std::string& icon);
+ Video(const std::string& caption, const std::string& icon);
~Video();
void setVideoMode(const long mode[3]);
int getWidth() const;
int getHeight() const;
-
- struct Exception : public Mf::Exception
- {
- explicit Exception(unsigned error) :
- Mf::Exception(error) {}
-
- void raise()
- {
- throw *this;
- }
- };
-
private:
void init(const Attributes& attribs);
#include <Moof/Aabb.hh>
#include <Moof/Camera.hh>
#include <Moof/Entity.hh>
+#include <Moof/Exception.hh>
+#include <Moof/Library.hh>
#include <Moof/Log.hh>
#include <Moof/Math.hh>
-#include <Moof/Mippleton.hh>
-#include <Moof/Octree.hh>
+//#include <Moof/Octree.hh>
#include <Moof/Script.hh>
#include <Moof/Settings.hh>
#include "Tilemap.hh"
-struct Scene::Impl : public Mf::Mippleton<Impl>
+struct Scene::Impl : public Mf::Library<Impl>
{
- struct Quad : public Mf::Entity, public Mf::OctreeInsertable
+ struct Quad : public Mf::Entity
{
- enum SURFACE_TYPE
+ enum SURFACE
{
NONE = 0,
LEFT = 1,
Quad(const Mf::Vector3 vertices[4], const std::string& texture,
Tilemap::Index tileIndex) :
- tilemap_(texture),
- blending_(false),
- fog_(false),
- surfaceType_(NONE)
+ mTilemap(texture),
+ mBlending(false),
+ mFog(false),
+ mSurface(NONE)
{
for (int i = 0, num = 0; i < 4; ++i)
{
for (int j = 0; j < 3; ++j, ++num)
{
- vertices_[num] = vertices[i][j];
+ mVertices[num] = vertices[i][j];
}
}
- if (!tilemap_.getTileCoords(tileIndex, texCoords_))
+ if (!mTilemap.getTileCoords(tileIndex, mTexCoords))
{
Mf::logWarning("no index %d in texture %s", tileIndex,
texture.c_str());
- texCoords_[0] = texCoords_[1] =
- texCoords_[3] = texCoords_[6] = 0.0;
- texCoords_[2] = texCoords_[4] =
- texCoords_[5] = texCoords_[7] = 1.0;
+ mTexCoords[0] = mTexCoords[1] =
+ mTexCoords[3] = mTexCoords[6] = 0.0;
+ mTexCoords[2] = mTexCoords[4] =
+ mTexCoords[5] = mTexCoords[7] = 1.0;
}
- aabb_.encloseVertices(vertices, 4);
- sphere_.point = aabb_.getCenter();
- sphere_.radius = (aabb_.min - sphere_.point).length();
+ mAabb.encloseVertices(vertices, 4);
+ mSphere.point = mAabb.getCenter();
+ mSphere.radius = (mAabb.min - mSphere.point).length();
}
void setBlending(bool blending)
{
- blending_ = blending;
+ mBlending = blending;
}
void setFog(bool fog)
{
- fog_ = fog;
+ mFog = fog;
}
- void setSurfaceType(SURFACE_TYPE type)
+ void setSurface(SURFACE type)
{
- surfaceType_ = type;
+ mSurface = type;
+ }
+
+ SURFACE getSurface() const
+ {
+ return mSurface;
}
void draw(Mf::Scalar alpha = 0.0) const
{
- if (blending_)
+ if (mBlending)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
- if (fog_)
+ if (mFog)
{
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_LINEAR);
}
//glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- tilemap_.bind();
+ mTilemap.bind();
- glVertexPointer(3, GL_SCALAR, 0, vertices_);
- glTexCoordPointer(2, GL_SCALAR, 0, texCoords_);
+ glVertexPointer(3, GL_SCALAR, 0, mVertices);
+ glTexCoordPointer(2, GL_SCALAR, 0, mTexCoords);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
bool isVisible(const Mf::Frustum& frustum) const
{
- return sphere_.isVisible(frustum);
- }
-
-
- bool isInsideAabb(const Mf::Aabb& aabb) const
- {
- // make sure the entity is fully inside the volume
- if (!(aabb_.max[0] < aabb.max[0] &&
- aabb_.min[0] > aabb.min[0] &&
- aabb_.max[1] < aabb.max[1] &&
- aabb_.min[1] > aabb.min[1] &&
- aabb_.max[2] < aabb.max[2] &&
- aabb_.min[2] > aabb.min[2]))
- {
- return false;
- }
-
- return true;
- }
-
- int getOctant(const Mf::Aabb& aabb) const
- {
- int octantNum = -1;
-
- Mf::Plane::Halfspace halfspace;
-
- Mf::Plane xy = aabb.getPlaneXY();
- halfspace = xy.intersects(sphere_);
- if (halfspace == Mf::Plane::INTERSECT)
- {
- halfspace = xy.intersects(aabb_);
- }
-
- if (halfspace == Mf::Plane::POSITIVE)
- {
- Mf::Plane xz = aabb.getPlaneXZ();
- halfspace = xz.intersects(sphere_);
- if (halfspace == Mf::Plane::INTERSECT)
- {
- halfspace = xz.intersects(aabb_);
- }
-
- if (halfspace == Mf::Plane::POSITIVE)
- {
- Mf::Plane yz = aabb.getPlaneYZ();
- halfspace = yz.intersects(sphere_);
- if (halfspace == Mf::Plane::INTERSECT)
- {
- halfspace = yz.intersects(aabb_);
- }
-
- if (halfspace == Mf::Plane::POSITIVE)
- {
- octantNum = 2;
- }
- else if (halfspace == Mf::Plane::NEGATIVE)
- {
- octantNum = 3;
- }
- }
- else if (halfspace == Mf::Plane::NEGATIVE)
- {
- Mf::Plane yz = aabb.getPlaneYZ();
- halfspace = yz.intersects(sphere_);
- if (halfspace == Mf::Plane::INTERSECT)
- {
- halfspace = yz.intersects(aabb_);
- }
-
- if (halfspace == Mf::Plane::POSITIVE)
- {
- octantNum = 1;
- }
- else if (halfspace == Mf::Plane::NEGATIVE)
- {
- octantNum = 0;
- }
- }
- }
- else if (halfspace == Mf::Plane::NEGATIVE)
- {
- Mf::Plane xz = aabb.getPlaneXZ();
- halfspace = xz.intersects(sphere_);
- if (halfspace == Mf::Plane::INTERSECT)
- {
- halfspace = xz.intersects(aabb_);
- }
-
- if (halfspace == Mf::Plane::POSITIVE)
- {
- Mf::Plane yz = aabb.getPlaneYZ();
- halfspace = yz.intersects(sphere_);
- if (halfspace == Mf::Plane::INTERSECT)
- {
- halfspace = yz.intersects(aabb_);
- }
-
- if (halfspace == Mf::Plane::POSITIVE)
- {
- octantNum = 6;
- }
- else if (halfspace == Mf::Plane::NEGATIVE)
- {
- octantNum = 7;
- }
- }
- else if (halfspace == Mf::Plane::NEGATIVE)
- {
- Mf::Plane yz = aabb.getPlaneYZ();
- halfspace = yz.intersects(sphere_);
- if (halfspace == Mf::Plane::INTERSECT)
- {
- halfspace = yz.intersects(aabb_);
- }
-
- if (halfspace == Mf::Plane::POSITIVE)
- {
- octantNum = 5;
- }
- else if (halfspace == Mf::Plane::NEGATIVE)
- {
- octantNum = 4;
- }
- }
- }
-
- return octantNum;
+ return mSphere.isVisible(frustum);
}
- Mf::Scalar vertices_[12];
- Mf::Scalar texCoords_[8];
+ Mf::Scalar mVertices[12];
+ Mf::Scalar mTexCoords[8];
- Tilemap tilemap_;
-
- bool blending_;
- bool fog_;
- SURFACE_TYPE surfaceType_;
+ Tilemap mTilemap;
- Mf::Aabb aabb_;
- Mf::Sphere sphere_;
+ bool mBlending;
+ bool mFog;
+ SURFACE mSurface;
};
- Mf::Matrix4 transform;
- std::string texture;
+ Mf::Matrix4 mTransform;
+ std::string mTexture;
- Mf::Octree<Quad>::Ptr octree;
+ //Mf::Octree<Quad>::Ptr mOctree;
+ std::list< boost::shared_ptr<Impl::Quad> > mObjects;
- Mf::Aabb playfieldBounds;
- Mf::Aabb maximumBounds;
+ Mf::Aabb mBounds;
enum AXIS
};
-
explicit Impl(const std::string& name) :
- Mf::Mippleton<Impl>(name)
- {
- loadFromFile();
- }
+ Mf::Library<Impl>(name) {}
void importSceneBindings(Mf::Script& script)
{
- script.importFunction("SetPlayfieldBounds",
- boost::bind(&Impl::setPlayfieldBounds, this, _1));
- script.importFunction("SetMaximumBounds",
- boost::bind(&Impl::setMaximumBounds, this, _1));
+ script.importFunction("SetBounds",
+ boost::bind(&Impl::setBounds, this, _1));
script.importFunction("ResetTransform",
boost::bind(&Impl::resetTransform, this, _1));
script.importFunction("Translate",
boost::bind(&Impl::rotate, this, _1));
script.importFunction("SetTexture",
boost::bind(&Impl::setTexture, this, _1));
- script.importFunction("MakeTilemap",
- boost::bind(&Impl::makeTilemap, this, _1));
- script.importFunction("MakeBillboard",
- boost::bind(&Impl::makeBillboard, this, _1));
+ script.importFunction("DrawTilemap",
+ boost::bind(&Impl::drawTilemap, this, _1));
+ script.importFunction("DrawTile",
+ boost::bind(&Impl::drawTile, this, _1));
int detail = 3;
Mf::Settings::getInstance().get("detail", detail);
script.push(detail); script.set("detail");
+ script.push(1); script.set("LOW");
+ script.push(2); script.set("MEDIUM");
+ script.push(3); script.set("HIGH");
+
script.push(X); script.set("X");
script.push(Y); script.set("Y");
script.push(Z); script.set("Z");
}
- void loadFromFile()
+ Mf::Script::Status load(Mf::Script& script)
{
- Mf::Script script;
std::string filePath = Scene::getPath(getName());
+ if (filePath == "") return Mf::Script::FILE_ERROR;
- script.importStandardLibraries();
- importLogScript(script);
importSceneBindings(script);
-
- if (script.doFile(filePath) != Mf::Script::SUCCESS)
- {
- std::string str;
- script[-1].get(str);
- Mf::logScript("%s", str.c_str());
- }
+ return script.doFile(filePath);
}
return 0;
}
- int setPlayfieldBounds(Mf::Script& script)
+ int setBounds(Mf::Script& script)
{
- return loadBox(script, playfieldBounds);
- }
-
- int setMaximumBounds(Mf::Script& script)
- {
- int ret = loadBox(script, maximumBounds);
- octree = Mf::Octree<Quad>::alloc(maximumBounds);
+ int ret = loadBox(script, mBounds);
+ //mOctree = Mf::Octree<Quad>::alloc(mBounds);
return ret;
}
int resetTransform(Mf::Script& script)
{
- transform.identity();
+ mTransform.identity();
return 0;
}
Mf::Matrix4 translation;
cml::matrix_translation(translation, vec);
- transform = translation * transform;
+ mTransform = translation * mTransform;
return 0;
}
Mf::Matrix4 scaling;
cml::matrix_scale(scaling, vec);
- transform = scaling * transform;
+ mTransform = scaling * mTransform;
}
else if (script.getSize() == 1)
{
Mf::Matrix4 scaling;
cml::matrix_uniform_scale(scaling, value);
- transform = scaling * transform;
+ mTransform = scaling * mTransform;
}
else
{
Mf::Scalar value;
angle.get(value);
- cml::matrix_rotate_about_world_axis(transform, index, cml::rad(value));
+ cml::matrix_rotate_about_world_axis(mTransform, index, cml::rad(value));
return 0;
}
int setTexture(Mf::Script& script)
{
- script[1].requireString().get(texture);
+ script[1].requireString().get(mTexture);
return 0;
}
- int makeTilemap(Mf::Script& script)
+ int drawTilemap(Mf::Script& script)
{
Mf::Script::Value table = script[1].requireTable();
Mf::Script::Value top = script[-1];
- Quad::SURFACE_TYPE surfaceType;
- table.pushField("surface_type");
- top.get(surfaceType);
+ Quad::SURFACE surface;
+ table.pushField("surface");
+ top.get(surface);
+ script.pop();
int width = 1;
int height = 1;
table.pushField("width");
top.get(width);
+ script.pop();
int nTiles = 0;
- table.pushField("tiles");
+ //table.pushField("tiles");
Mf::Script::Value tiles = script.getTop();
nTiles = tiles.getLength();
Mf::Vector4 vertices[height+1][width+1];
- Mf::Matrix4 transposedTransform = transform;
+ Mf::Matrix4 transposedTransform = mTransform;
transposedTransform.transpose();
for (int h = 0; h <= height; ++h)
demotedVertices[2] = Mf::demote(vertices[h+1][w+1]);
demotedVertices[3] = Mf::demote(vertices[h+1][w]);
- Quad* quad = new Quad(demotedVertices, texture, indices[h][w]);
- quad->setSurfaceType(surfaceType);
+ Quad* quad = new Quad(demotedVertices, mTexture, indices[h][w]);
+ quad->setSurface(surface);
boost::shared_ptr<Quad> quadPtr(quad);
- octree->insert(quadPtr);
+ //mOctree->insert(quadPtr);
+ mObjects.push_back(quadPtr);
}
}
return 0;
}
- int makeBillboard(Mf::Script& script)
+ int drawTile(Mf::Script& script)
{
- Mf::Script::Value table = script[1];
+ Mf::Script::Value param = script[1];
Mf::Script::Value top = script[-1];
Tilemap::Index index = 0;
bool blending = false;
bool fog = false;
- if (table.isTable())
+ if (param.isTable())
{
- table.pushField("tile");
+ script.push(1);
+ param.pushField();
top.get(index);
- table.pushField("u_scale");
+ param.pushField("u_scale");
top.get(width);
- table.pushField("blend");
+ param.pushField("blend");
top.get(blending);
- table.pushField("fog");
+ param.pushField("fog");
top.get(fog);
}
+ else if (param.isNumber())
+ {
+ param.get(index);
+ }
Mf::Vector4 vertices[2][width+1];
- Mf::Matrix4 transposedTransform = transform;
+ Mf::Matrix4 transposedTransform = mTransform;
transposedTransform.transpose();
Mf::Scalar xf;
demotedVertices[2] = Mf::demote(vertices[1][w+1]);
demotedVertices[3] = Mf::demote(vertices[1][w]);
- Quad* quad = new Quad(demotedVertices, texture, index);
+ Quad* quad = new Quad(demotedVertices, mTexture, index);
quad->setBlending(blending);
quad->setFog(fog);
boost::shared_ptr<Quad> quadPtr(quad);
- octree->insert(quadPtr);
+ //mOctree->insert(quadPtr);
+ mObjects.push_back(quadPtr);
}
return 0;
mImpl(Scene::Impl::getInstance(name)) {}
+Mf::Script::Status Scene::load(Mf::Script& script)
+{
+ // pass through
+ return mImpl->load(script);
+}
+
+
void Scene::draw(Mf::Scalar alpha) const
{
- mImpl->octree->draw(alpha);
+ //mImpl->mOctree->draw(alpha);
+ std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
+ std::list< boost::shared_ptr<Impl::Quad> >::const_iterator it;
+
+ for (it = objects.begin(); it != objects.end(); ++it)
+ {
+ (*it)->draw(alpha);
+ }
+
+ mImpl->mBounds.draw();
}
void Scene::drawIfVisible(Mf::Scalar alpha, const Mf::Frustum& frustum) const
{
- mImpl->octree->drawIfVisible(alpha, frustum);
+ //mImpl->mOctree->drawIfVisible(alpha, frustum);
+ std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
+ std::list< boost::shared_ptr<Impl::Quad> >::const_iterator it;
+
+ for (it = objects.begin(); it != objects.end(); ++it)
+ {
+ (*it)->drawIfVisible(alpha, frustum);
+ }
+
+ mImpl->mBounds.draw();
}
bool Scene::checkForCollision(Character& character)
{
- std::list< boost::shared_ptr<Impl::Quad> > objects;
+ return false;
+ //std::list< boost::shared_ptr<Impl::Quad> > objects;
//std::list<Mf::Octree<Impl::Quad>::InsertableP> objects;
- mImpl->octree->getNearbyObjects(objects, character);
- mImpl->maximumBounds.draw();
+ //mImpl->mOctree->getNearbyObjects(objects, character);
+
+ std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
+ std::list< boost::shared_ptr<Impl::Quad> >::const_iterator it;
+
+ int collisions = 0;
+ Mf::Sphere sphere = character.getSphere();
+
+ for (it = objects.begin(); it != objects.end(); ++it)
+ {
+ Impl::Quad::SURFACE type = (*it)->getSurface();
+ if (type == Impl::Quad::NONE) continue;
+
+ if (Mf::checkCollision(sphere, (*it)->getSphere()))
+ {
+ ++collisions;
+
+ Mf::Vector2 impulse(0.0, 0.0);
+ Mf::Vector2 p = character.getState().momentum;
+
+ Mf::State2 state = character.getState(1.0);
+ sphere = character.getSphere();
+ Mf::Scalar alpha = 1.0;
+ while (Mf::checkCollision(sphere, (*it)->getSphere()))
+ {
+ alpha -= 0.05;
+ state = character.getState(alpha);
+ }
+
+ character.setPosition(state.position);
+
+ //switch (type)
+ //{
+ //case Impl::Quad::TOP:
+ //if (p[1] < 0.0) impulse[1] = -p[1];
+ //break;
+ //case Impl::Quad::LEFT:
+ //if (p[0] > 0.0) impulse[0] = 1.5*-p[0];
+ //break;
+ //case Impl::Quad::RIGHT:
+ //if (p[0] < 0.0) impulse[0] = 1.5*-p[0];
+ //break;
+ //}
+
+ //character.addImpulse(impulse);
+ }
+ }
+
+ if (collisions > 0)
+ {
+ Mf::logInfo("collisions: %d", collisions);
+ }
- Mf::logDebug("nearby objects: %d", objects.size());
return false;
}
#include <Moof/Cullable.hh>
#include <Moof/Drawable.hh>
#include <Moof/Resource.hh>
+#include <Moof/Script.hh>
class Character;
public:
- Scene(const std::string& name);
+ explicit Scene(const std::string& name);
static SceneP alloc(const std::string& name)
{
return SceneP(new Scene(name));
}
+ Mf::Script::Status load(Mf::Script& script);
+
void draw(Mf::Scalar alpha) const;
void drawIfVisible(Mf::Scalar alpha, const Mf::Frustum& frustum) const;
+ Mf::Scalar getZCoord(const Mf::Vector2& position) const;
+
bool checkForCollision(Character& character);
static std::string getPath(const std::string& name);
} Orientation;
- Tilemap(const std::string& name);
+ explicit Tilemap(const std::string& name);
/**
* Calculate texture coordinates for a tile at a certain index. Tiles are
#define COMPILER_NAME "COMO"
#define COMPILER_VERSION __COMO_VERSION__
#elif defined(_CRAYC) && defined(_REVISION)
-#define COMPILER_NAME "GRAYC"
+#define COMPILER_NAME "CRAYC"
#define COMPILER_VERSION _REVISION
#elif defined(__DECCXX) && defined(__DECCXX)
#define COMPILER_NAME "DECCXX"
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.png"
+ File "$ROOT_DIR/README" "$ROOT_DIR/TODO" "$ROOT_DIR/doc/screenshot.jpg"
File /r "$ROOT_DIR/doc/licenses"
; uninstall
WriteUninstaller "uninstall.exe"